@minatojs/driver-memory
Version:
In-memory Driver for Minato
209 lines (207 loc) • 7.61 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var src_exports = {};
__export(src_exports, {
MemoryDriver: () => MemoryDriver,
default: () => src_default
});
module.exports = __toCommonJS(src_exports);
var import_cosmokit = require("cosmokit");
var import_minato = require("minato");
var MemoryDriver = class extends import_minato.Driver {
static name = "memory";
#store = {
_fields: []
};
async prepare(name) {
}
async start() {
}
async $save(name) {
}
async stop() {
}
table(sel, env = {}) {
if (typeof sel === "string") {
return this.#store[sel] ||= [];
}
if (!(sel instanceof import_minato.Selection)) {
throw new Error("Should not reach here");
}
const { ref, query, table, args, model } = sel;
const { fields, group, having } = sel.args[0];
let data;
if (typeof table === "object" && !(table instanceof import_minato.Selection)) {
const entries = Object.entries(table).map(([name, sel2]) => [name, this.table(sel2, env)]);
const catesian = /* @__PURE__ */ __name((entries2) => {
if (!entries2.length)
return [];
const [[name, rows], ...tail] = entries2;
if (!tail.length)
return rows.map((row) => ({ [name]: row }));
return rows.flatMap((row) => catesian(tail).map((tail2) => ({ ...tail2, [name]: row })));
}, "catesian");
data = catesian(entries).map((x) => ({ ...env, [ref]: x })).filter((data2) => (0, import_minato.executeEval)(data2, having)).map((x) => x[ref]);
} else {
data = this.table(table, env).filter((row) => (0, import_minato.executeQuery)(row, query, ref, env));
}
env[ref] = data;
const branches = [];
const groupFields = group ? (0, import_cosmokit.pick)(fields, group) : fields;
for (let row of (0, import_minato.executeSort)(data, args[0], ref)) {
row = model.format(row, false);
for (const key in model.fields) {
if (model.fields[key].deprecated)
continue;
row[key] ??= null;
}
let index = row;
if (fields) {
index = (0, import_cosmokit.valueMap)(groupFields, (expr) => (0, import_minato.executeEval)({ ...env, [ref]: row }, expr));
}
let branch = branches.find((branch2) => {
if (!group || !groupFields)
return false;
for (const key in groupFields) {
if (branch2.index[key] !== index[key])
return false;
}
return true;
});
if (!branch) {
branch = { index, table: [] };
branches.push(branch);
}
branch.table.push(row);
}
return branches.map(({ index, table: table2 }) => {
if (group) {
if (having) {
const value = (0, import_minato.executeEval)(table2.map((row) => ({ ...env, [ref]: row, _: row })), having);
if (!value)
return;
}
for (const key in (0, import_cosmokit.omit)(fields, group)) {
index[key] = (0, import_minato.executeEval)(table2.map((row) => ({ ...env, [ref]: row, _: row })), fields[key]);
}
}
return model.parse(index, false);
}).filter(Boolean);
}
async drop(table) {
delete this.#store[table];
}
async dropAll() {
this.#store = { _fields: [] };
}
async stats() {
return {};
}
async get(sel) {
return this.table(sel);
}
async eval(sel, expr) {
const { query, table } = sel;
const ref = typeof table === "string" ? sel.ref : table.ref;
const data = this.table(table).filter((row) => (0, import_minato.executeQuery)(row, query, ref));
return (0, import_minato.executeEval)(data.map((row) => ({ [ref]: row, _: row })), expr);
}
async set(sel, data) {
const { table, ref, query } = sel;
const matched = this.table(table).filter((row) => (0, import_minato.executeQuery)(row, query, ref)).map((row) => (0, import_minato.executeUpdate)(row, data, ref)).length;
this.$save(table);
return { matched };
}
async remove(sel) {
const { ref, query, table } = sel;
const data = this.table(table);
this.#store[table] = data.filter((row) => !(0, import_minato.executeQuery)(row, query, ref));
this.$save(table);
const count = data.length - this.#store[table].length;
return { removed: count, matched: count };
}
async create(sel, data) {
const { table, model } = sel;
const { primary, autoInc } = model;
const store = this.table(table);
if (!Array.isArray(primary) && autoInc && !(primary in data)) {
let meta = this.#store._fields.find((row) => row.table === table && row.field === primary);
if (!meta) {
meta = { table, field: primary, autoInc: 0 };
this.#store._fields.push(meta);
}
meta.autoInc += 1;
data[primary] = meta.autoInc;
} else {
const duplicated = await this.database.get(table, (0, import_cosmokit.pick)(data, (0, import_cosmokit.makeArray)(primary)));
if (duplicated.length) {
throw new import_minato.RuntimeError("duplicate-entry");
}
}
const copy = model.create(data);
store.push(copy);
this.$save(table);
return (0, import_cosmokit.clone)(copy);
}
async upsert(sel, data, keys) {
const { table, model, ref } = sel;
const result = { inserted: 0, matched: 0 };
for (const update of data) {
const row = this.table(table).find((row2) => {
return keys.every((key) => row2[key] === update[key]);
});
if (row) {
(0, import_minato.executeUpdate)(row, update, ref);
result.matched++;
} else {
const data2 = (0, import_minato.executeUpdate)(model.create(), update, ref);
await this.database.create(table, data2).catch(import_cosmokit.noop);
result.inserted++;
}
}
this.$save(table);
return result;
}
executeSelection(sel, env = {}) {
const expr = sel.args[0], table = sel.table;
if (Array.isArray(env))
env = { [sel.ref]: env };
const data = this.table(sel.table, env);
const res = expr.$ ? data.map((row) => (0, import_minato.executeEval)({ ...env, [table.ref]: row, _: row }, expr)) : (0, import_minato.executeEval)(Object.assign(data.map((row) => ({ [table.ref]: row, _: row })), env), expr);
return res;
}
async withTransaction(callback) {
const data = (0, import_cosmokit.clone)(this.#store);
await callback(this).then(void 0, (e) => {
this.#store = data;
throw e;
});
}
};
((MemoryDriver2) => {
MemoryDriver2.Config = import_minato.z.object({});
})(MemoryDriver || (MemoryDriver = {}));
var src_default = MemoryDriver;
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
MemoryDriver
});
//# sourceMappingURL=index.js.map