iagate-querykit
Version:
QueryKit: lightweight TypeScript query toolkit with models, views, triggers, events, scheduler and adapters (better-sqlite3).
57 lines (56 loc) • 1.96 kB
JavaScript
import { getExecutorForTable } from './config';
import { QueryBuilder } from './query-builder';
export class Seed {
async run(_ctx) { return []; }
}
export async function runSeed(table, dataOrSeed, opts = {}) {
const exec = getExecutorForTable(table);
if (!exec)
throw new Error('No executor configured for QueryKit');
if (opts.truncate) {
if (exec.runSync)
exec.runSync(`DELETE FROM ${table}`, []);
else
await exec.executeQuery(`DELETE FROM ${table}`, []);
}
let rows;
if (Array.isArray(dataOrSeed))
rows = dataOrSeed;
else {
const ctx = { exec, qb: (t) => new QueryBuilder(t) };
const out = await dataOrSeed.run(ctx);
rows = out || [];
}
if (!rows.length)
return 0;
// batch insert with optional conflict handling
const uniqueKeys = (opts.uniqueBy || []);
const shouldUpsert = !!opts.upsert;
const shouldIgnore = !!opts.ignoreDuplicates;
for (const row of rows) {
if (uniqueKeys.length && shouldIgnore) {
const attributes = {};
for (const key of uniqueKeys)
attributes[String(key)] = row[String(key)];
const exists = await new QueryBuilder(table).whereAll(attributes).exists();
if (exists)
continue;
await new QueryBuilder(table).insert(row).make();
continue;
}
if (uniqueKeys.length && shouldUpsert) {
const attributes = {};
const values = {};
for (const [k, v] of Object.entries(row)) {
if (uniqueKeys.includes(k))
attributes[k] = v;
else
values[k] = v;
}
await new QueryBuilder(table).updateOrInsert(attributes, values).make();
continue;
}
await new QueryBuilder(table).insert(row).make();
}
return rows.length;
}