import { formatPg, sql } from "../../z2s/src/sql.js";
import { CRUDMutatorFactory } from "./custom.js";
class ZQLDatabase {
  connection;
  #crudFactory;
  constructor(connection, schema) {
    this.connection = connection;
    this.#crudFactory = new CRUDMutatorFactory(schema);
  }
  transaction(callback, transactionInput) {
    const {
      upstreamSchema = "",
      clientGroupID = "",
      clientID = "",
      mutationID = 0
    } = transactionInput ?? {};
    return this.connection.transaction(async (dbTx) => {
      const zeroTx = await this.#makeServerTransaction(
        dbTx,
        clientID,
        mutationID
      );
      return callback(zeroTx, {
        async updateClientMutationID() {
          const formatted = formatPg(
            sql`INSERT INTO ${sql.ident(upstreamSchema)}.clients 
                    as current ("clientGroupID", "clientID", "lastMutationID")
                        VALUES (${clientGroupID}, ${clientID}, ${1})
                    ON CONFLICT ("clientGroupID", "clientID")
                    DO UPDATE SET "lastMutationID" = current."lastMutationID" + 1
                    RETURNING "lastMutationID"`
          );
          const [{ lastMutationID }] = await dbTx.query(
            formatted.text,
            formatted.values
          );
          return { lastMutationID };
        },
        async writeMutationResult(result) {
          const formatted = formatPg(
            sql`INSERT INTO ${sql.ident(upstreamSchema)}.mutations
                    ("clientGroupID", "clientID", "mutationID", "result")
                VALUES (${clientGroupID}, ${result.id.clientID}, ${result.id.id}, ${JSON.stringify(
              result.result
            )}::text::json)`
          );
          await dbTx.query(formatted.text, formatted.values);
        },
        async deleteMutationResults(args) {
          if ("type" in args && args.type === "bulk") {
            const formatted = formatPg(
              sql`DELETE FROM ${sql.ident(upstreamSchema)}."mutations"
                  WHERE "clientGroupID" = ${args.clientGroupID}
                    AND "clientID" = ANY(${args.clientIDs})`
            );
            await dbTx.query(formatted.text, formatted.values);
          } else {
            const formatted = formatPg(
              sql`DELETE FROM ${sql.ident(upstreamSchema)}."mutations"
                  WHERE "clientGroupID" = ${args.clientGroupID}
                    AND "clientID" = ${args.clientID}
                    AND "mutationID" <= ${args.upToMutationID}`
            );
            await dbTx.query(formatted.text, formatted.values);
          }
        }
      });
    });
  }
  #makeServerTransaction(dbTx, clientID, mutationID) {
    return this.#crudFactory.createTransaction(dbTx, clientID, mutationID);
  }
  run(query, options) {
    return this.transaction((tx) => tx.run(query, options));
  }
}
export {
  ZQLDatabase
};
//# sourceMappingURL=zql-database.js.map
