import { must } from "../../../shared/src/must.js";
import "../../../zero-protocol/src/push.js";
import { consume } from "../../../zql/src/ivm/stream.js";
import { toPrimaryKeyString } from "./keys.js";
function defaultOptionalFieldsToNull(schema, value) {
  let rv = value;
  for (const name in schema.columns) {
    if (rv[name] === void 0) {
      rv = { ...rv, [name]: null };
    }
  }
  return rv;
}
async function insert(tx, arg, schema, ivmBranch) {
  const key = toPrimaryKeyString(
    arg.tableName,
    schema.tables[arg.tableName].primaryKey,
    arg.value
  );
  if (!await tx.has(key)) {
    const val = defaultOptionalFieldsToNull(
      schema.tables[arg.tableName],
      arg.value
    );
    await tx.set(key, val);
    if (ivmBranch) {
      consume(
        must(ivmBranch.getSource(arg.tableName)).push({
          type: "add",
          row: arg.value
        })
      );
    }
  }
}
async function upsert(tx, arg, schema, ivmBranch) {
  const key = toPrimaryKeyString(
    arg.tableName,
    schema.tables[arg.tableName].primaryKey,
    arg.value
  );
  if (await tx.has(key)) {
    await update(tx, { ...arg }, schema, ivmBranch);
  } else {
    await insert(tx, { ...arg }, schema, ivmBranch);
  }
}
async function update(tx, arg, schema, ivmBranch) {
  const key = toPrimaryKeyString(
    arg.tableName,
    schema.tables[arg.tableName].primaryKey,
    arg.value
  );
  const prev = await tx.get(key);
  if (prev === void 0) {
    return;
  }
  const update2 = arg.value;
  const next = { ...prev };
  for (const k in update2) {
    if (update2[k] !== void 0) {
      next[k] = update2[k];
    }
  }
  await tx.set(key, next);
  if (ivmBranch) {
    consume(
      must(ivmBranch.getSource(arg.tableName)).push({
        type: "edit",
        oldRow: prev,
        row: next
      })
    );
  }
}
async function deleteImpl(tx, arg, schema, ivmBranch) {
  const key = toPrimaryKeyString(
    arg.tableName,
    schema.tables[arg.tableName].primaryKey,
    arg.value
  );
  const prev = await tx.get(key);
  if (prev === void 0) {
    return;
  }
  await tx.del(key);
  if (ivmBranch) {
    consume(
      must(ivmBranch.getSource(arg.tableName)).push({
        type: "remove",
        row: prev
      })
    );
  }
}
export {
  deleteImpl as delete,
  insert,
  update,
  upsert
};
//# sourceMappingURL=crud-impl.js.map
