@assemora/database 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +163 -0
- package/dist/adapter.d.ts +133 -0
- package/dist/adapter.d.ts.map +1 -0
- package/dist/adapter.js +26 -0
- package/dist/adapter.js.map +1 -0
- package/dist/errors.d.ts +48 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +54 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/join-table.d.ts +66 -0
- package/dist/join-table.d.ts.map +1 -0
- package/dist/join-table.js +265 -0
- package/dist/join-table.js.map +1 -0
- package/dist/memory.d.ts +22 -0
- package/dist/memory.d.ts.map +1 -0
- package/dist/memory.js +398 -0
- package/dist/memory.js.map +1 -0
- package/dist/query-ast.d.ts +79 -0
- package/dist/query-ast.d.ts.map +1 -0
- package/dist/query-ast.js +29 -0
- package/dist/query-ast.js.map +1 -0
- package/dist/schema-diff.d.ts +187 -0
- package/dist/schema-diff.d.ts.map +1 -0
- package/dist/schema-diff.js +473 -0
- package/dist/schema-diff.js.map +1 -0
- package/package.json +36 -0
package/dist/memory.js
ADDED
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory adapter.
|
|
3
|
+
*
|
|
4
|
+
* SPEC.md §109 asks for a memory adapter so the data layer can be built and tested
|
|
5
|
+
* before PostgreSQL exists. It implements the same contract as any other adapter, so
|
|
6
|
+
* a query proven here runs unchanged against `@assemora/database-postgres`.
|
|
7
|
+
*
|
|
8
|
+
* Development and tests only — nothing here is durable.
|
|
9
|
+
*/
|
|
10
|
+
import { AssemoraError } from '@assemora/core';
|
|
11
|
+
import { pivotAddress } from './join-table.js';
|
|
12
|
+
const compare = (left, right) => {
|
|
13
|
+
if (left === right)
|
|
14
|
+
return 0;
|
|
15
|
+
if (left === null || left === undefined)
|
|
16
|
+
return -1;
|
|
17
|
+
if (right === null || right === undefined)
|
|
18
|
+
return 1;
|
|
19
|
+
if (left instanceof Date && right instanceof Date)
|
|
20
|
+
return left.getTime() - right.getTime();
|
|
21
|
+
if (typeof left === 'number' && typeof right === 'number')
|
|
22
|
+
return left - right;
|
|
23
|
+
return String(left).localeCompare(String(right));
|
|
24
|
+
};
|
|
25
|
+
const likeToRegExp = (pattern) => new RegExp(`^${pattern
|
|
26
|
+
.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
|
27
|
+
.replace(/%/g, '.*')
|
|
28
|
+
.replace(/_/g, '.')}$`, 'i');
|
|
29
|
+
const evaluateComparison = (row, condition) => {
|
|
30
|
+
const actual = row[condition.field];
|
|
31
|
+
const expected = condition.value;
|
|
32
|
+
switch (condition.operator) {
|
|
33
|
+
case '=':
|
|
34
|
+
return compare(actual, expected) === 0;
|
|
35
|
+
case '!=':
|
|
36
|
+
return compare(actual, expected) !== 0;
|
|
37
|
+
case '>':
|
|
38
|
+
return compare(actual, expected) > 0;
|
|
39
|
+
case '>=':
|
|
40
|
+
return compare(actual, expected) >= 0;
|
|
41
|
+
case '<':
|
|
42
|
+
return compare(actual, expected) < 0;
|
|
43
|
+
case '<=':
|
|
44
|
+
return compare(actual, expected) <= 0;
|
|
45
|
+
case 'in':
|
|
46
|
+
return Array.isArray(expected) && expected.some((item) => compare(actual, item) === 0);
|
|
47
|
+
case 'not in':
|
|
48
|
+
return Array.isArray(expected) && !expected.some((item) => compare(actual, item) === 0);
|
|
49
|
+
case 'like':
|
|
50
|
+
return typeof actual === 'string' && likeToRegExp(String(expected)).test(actual);
|
|
51
|
+
case 'between':
|
|
52
|
+
return (Array.isArray(expected) &&
|
|
53
|
+
compare(actual, expected[0]) >= 0 &&
|
|
54
|
+
compare(actual, expected[1]) <= 0);
|
|
55
|
+
case 'is null':
|
|
56
|
+
return actual === null || actual === undefined;
|
|
57
|
+
case 'is not null':
|
|
58
|
+
return actual !== null && actual !== undefined;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
const readPath = (value, path) => path.reduce((current, key) => typeof current === 'object' && current !== null
|
|
62
|
+
? current[key]
|
|
63
|
+
: undefined, value);
|
|
64
|
+
/** A fragment is contained when every leaf it names matches the document. */
|
|
65
|
+
const contains = (document, fragment) => {
|
|
66
|
+
if (fragment === null || typeof fragment !== 'object')
|
|
67
|
+
return compare(document, fragment) === 0;
|
|
68
|
+
if (Array.isArray(fragment)) {
|
|
69
|
+
return (Array.isArray(document) &&
|
|
70
|
+
fragment.every((item) => document.some((candidate) => contains(candidate, item))));
|
|
71
|
+
}
|
|
72
|
+
if (typeof document !== 'object' || document === null)
|
|
73
|
+
return false;
|
|
74
|
+
return Object.entries(fragment).every(([key, value]) => contains(document[key], value));
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Structural equality, so a document compares the same way it would in SQL.
|
|
78
|
+
*
|
|
79
|
+
* Comparing through `String()` made `['a','b']` equal to the text `a,b` here and to
|
|
80
|
+
* nothing at all in PostgreSQL — the same Query AST meaning two different things,
|
|
81
|
+
* which is exactly what SPEC.md §30 exists to prevent.
|
|
82
|
+
*/
|
|
83
|
+
const deepEquals = (left, right) => {
|
|
84
|
+
if (left === right)
|
|
85
|
+
return true;
|
|
86
|
+
if (left === null || right === null || left === undefined || right === undefined)
|
|
87
|
+
return false;
|
|
88
|
+
if (typeof left !== 'object' || typeof right !== 'object')
|
|
89
|
+
return false;
|
|
90
|
+
if (Array.isArray(left) || Array.isArray(right)) {
|
|
91
|
+
return (Array.isArray(left) &&
|
|
92
|
+
Array.isArray(right) &&
|
|
93
|
+
left.length === right.length &&
|
|
94
|
+
left.every((item, index) => deepEquals(item, right[index])));
|
|
95
|
+
}
|
|
96
|
+
const a = left;
|
|
97
|
+
const b = right;
|
|
98
|
+
const keys = Object.keys(a);
|
|
99
|
+
return keys.length === Object.keys(b).length && keys.every((key) => deepEquals(a[key], b[key]));
|
|
100
|
+
};
|
|
101
|
+
const evaluateJson = (row, condition) => {
|
|
102
|
+
const document = row[condition.field];
|
|
103
|
+
if (condition.operator === 'contains')
|
|
104
|
+
return contains(document, condition.value);
|
|
105
|
+
const value = readPath(document, condition.path);
|
|
106
|
+
if (condition.operator === 'like') {
|
|
107
|
+
return typeof value === 'string' && likeToRegExp(String(condition.value)).test(value);
|
|
108
|
+
}
|
|
109
|
+
return deepEquals(value, condition.value);
|
|
110
|
+
};
|
|
111
|
+
const evaluate = (row, condition) => {
|
|
112
|
+
if (condition.kind === 'group')
|
|
113
|
+
return matches(row, condition.conditions);
|
|
114
|
+
if (condition.kind === 'json')
|
|
115
|
+
return evaluateJson(row, condition);
|
|
116
|
+
return evaluateComparison(row, condition);
|
|
117
|
+
};
|
|
118
|
+
const matches = (row, conditions) => {
|
|
119
|
+
let result = true;
|
|
120
|
+
for (const [index, condition] of conditions.entries()) {
|
|
121
|
+
const value = evaluate(row, condition);
|
|
122
|
+
if (index === 0) {
|
|
123
|
+
result = value;
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
result = condition.combinator === 'or' ? result || value : result && value;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return result;
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* Whether a value can identify a row at all.
|
|
133
|
+
*
|
|
134
|
+
* A null key joins to nothing in SQL — `null = null` is unknown — so a row holding one
|
|
135
|
+
* has no related rows, rather than every row that also holds none.
|
|
136
|
+
*/
|
|
137
|
+
const isKey = (value) => value !== null && value !== undefined;
|
|
138
|
+
/**
|
|
139
|
+
* The bucket a key falls in.
|
|
140
|
+
*
|
|
141
|
+
* Two keys share a bucket exactly when `compare` calls them equal, so relations
|
|
142
|
+
* matched in one pass through an index match the same rows a comparison per row did.
|
|
143
|
+
*/
|
|
144
|
+
const bucketOf = (value) => value instanceof Date ? String(value.getTime()) : String(value);
|
|
145
|
+
/**
|
|
146
|
+
* Whether a key value falls in one of the buckets already indexed.
|
|
147
|
+
*
|
|
148
|
+
* A `Map` and a `Set` are both asked this, and a value that is no key at all answers
|
|
149
|
+
* no — otherwise a stored `null` would land in the bucket the text `"null"` occupies.
|
|
150
|
+
*/
|
|
151
|
+
const isOneOf = (buckets, value) => isKey(value) && buckets.has(bucketOf(value));
|
|
152
|
+
const groupByKey = (rows, key) => {
|
|
153
|
+
const grouped = new Map();
|
|
154
|
+
for (const row of rows) {
|
|
155
|
+
const value = row[key];
|
|
156
|
+
if (!isKey(value))
|
|
157
|
+
continue;
|
|
158
|
+
const bucket = bucketOf(value);
|
|
159
|
+
const existing = grouped.get(bucket);
|
|
160
|
+
if (existing === undefined)
|
|
161
|
+
grouped.set(bucket, [row]);
|
|
162
|
+
else
|
|
163
|
+
existing.push(row);
|
|
164
|
+
}
|
|
165
|
+
return grouped;
|
|
166
|
+
};
|
|
167
|
+
/**
|
|
168
|
+
* The column on the far table that a join column copies, as the join table declares it.
|
|
169
|
+
*
|
|
170
|
+
* Read back off the derived descriptor rather than worked out again here: which column
|
|
171
|
+
* a pivot points at is decided in one place (`joinTableDescriptor`), and a second
|
|
172
|
+
* opinion is how a load comes to look where no write ever put a row.
|
|
173
|
+
*/
|
|
174
|
+
const linkedKey = (join, column) => {
|
|
175
|
+
const link = join.relations.find((relation) => relation.foreignKey === column);
|
|
176
|
+
if (link === undefined) {
|
|
177
|
+
throw new AssemoraError('INVALID_JOIN_TABLE', `The join table "${join.name}" declares no foreign key on "${column}"`, { status: 500 });
|
|
178
|
+
}
|
|
179
|
+
return link.ownerKey;
|
|
180
|
+
};
|
|
181
|
+
const sort = (rows, order) => order.length === 0
|
|
182
|
+
? rows
|
|
183
|
+
: [...rows].sort((left, right) => {
|
|
184
|
+
for (const step of order) {
|
|
185
|
+
const difference = compare(left[step.field], right[step.field]);
|
|
186
|
+
if (difference !== 0)
|
|
187
|
+
return step.direction === 'desc' ? -difference : difference;
|
|
188
|
+
}
|
|
189
|
+
return 0;
|
|
190
|
+
});
|
|
191
|
+
export const createMemoryAdapter = (seed = {}) => {
|
|
192
|
+
const tables = new Map();
|
|
193
|
+
let scans = 0;
|
|
194
|
+
for (const [table, rows] of Object.entries(seed)) {
|
|
195
|
+
tables.set(table, rows.map((row) => ({ ...row })));
|
|
196
|
+
}
|
|
197
|
+
const store = (table) => {
|
|
198
|
+
const existing = tables.get(table);
|
|
199
|
+
if (existing !== undefined)
|
|
200
|
+
return existing;
|
|
201
|
+
const created = [];
|
|
202
|
+
tables.set(table, created);
|
|
203
|
+
return created;
|
|
204
|
+
};
|
|
205
|
+
/**
|
|
206
|
+
* One pass over one table, and the only way rows are ever selected.
|
|
207
|
+
*
|
|
208
|
+
* Everything that reads goes through here, so `scanCount()` measures what a query
|
|
209
|
+
* costs: a batched relation load adds a fixed number of passes, and one loaded row
|
|
210
|
+
* by row adds a pass per row (SPEC.md §89).
|
|
211
|
+
*/
|
|
212
|
+
const scan = (table, keep) => {
|
|
213
|
+
scans += 1;
|
|
214
|
+
return store(table).filter(keep);
|
|
215
|
+
};
|
|
216
|
+
const relationOf = (table, name) => {
|
|
217
|
+
const relation = table.relations.find((candidate) => candidate.name === name);
|
|
218
|
+
if (relation === undefined) {
|
|
219
|
+
throw new AssemoraError('UNKNOWN_RELATION', `Table "${table.name}" has no relation "${name}"`, { status: 500 });
|
|
220
|
+
}
|
|
221
|
+
return relation;
|
|
222
|
+
};
|
|
223
|
+
/**
|
|
224
|
+
* The rows a `belongsToMany` links, in two passes: one over the join table, one over
|
|
225
|
+
* the target (SPEC.md §23).
|
|
226
|
+
*
|
|
227
|
+
* The join table is derived rather than looked up in `related`: no model declares it,
|
|
228
|
+
* so nothing registers a descriptor for it, and deriving it from the same function
|
|
229
|
+
* the DDL and the schema diff use is what makes a load look where a write put the
|
|
230
|
+
* rows (SPEC.md §24).
|
|
231
|
+
*/
|
|
232
|
+
const loadThroughJoinTable = (rows, table, relation, load, related) => {
|
|
233
|
+
const target = related[relation.target];
|
|
234
|
+
// Which column of the target the join table copies is the target's own business, so
|
|
235
|
+
// its descriptor has to be to hand. PostgreSQL refuses the same load for the same
|
|
236
|
+
// reason, and assuming `id` here would make the two adapters disagree quietly.
|
|
237
|
+
if (target === undefined) {
|
|
238
|
+
throw new AssemoraError('UNKNOWN_RELATION', `The descriptor for "${relation.target}" was not provided`, { status: 500 });
|
|
239
|
+
}
|
|
240
|
+
for (const row of rows)
|
|
241
|
+
row[relation.name] = [];
|
|
242
|
+
const owners = groupByKey(rows, relation.ownerKey);
|
|
243
|
+
const anchor = rows.find((row) => isKey(row[relation.ownerKey]));
|
|
244
|
+
if (anchor === undefined)
|
|
245
|
+
return;
|
|
246
|
+
// One row is enough to learn where the links live: the address is the same for
|
|
247
|
+
// every row of the table, and only `ownerValue` differs.
|
|
248
|
+
const pivot = pivotAddress(table, relation, anchor, target);
|
|
249
|
+
const links = scan(pivot.table.name, (link) => isOneOf(owners, link[pivot.ownerColumn]) && isKey(link[pivot.relatedColumn]));
|
|
250
|
+
/** Which owners hold each target, which is all a join table has to say. */
|
|
251
|
+
const heldBy = new Map();
|
|
252
|
+
for (const link of links) {
|
|
253
|
+
const ownerBucket = bucketOf(link[pivot.ownerColumn]);
|
|
254
|
+
const targetBucket = bucketOf(link[pivot.relatedColumn]);
|
|
255
|
+
const existing = heldBy.get(targetBucket);
|
|
256
|
+
if (existing === undefined)
|
|
257
|
+
heldBy.set(targetBucket, [ownerBucket]);
|
|
258
|
+
// The pair is unique in the table `joinTableDescriptor` describes, and nothing
|
|
259
|
+
// enforces that here. Counting a duplicate link twice would load the same role
|
|
260
|
+
// twice where PostgreSQL, holding the constraint, could not have stored it.
|
|
261
|
+
else if (!existing.includes(ownerBucket))
|
|
262
|
+
existing.push(ownerBucket);
|
|
263
|
+
}
|
|
264
|
+
if (heldBy.size === 0)
|
|
265
|
+
return;
|
|
266
|
+
const targetKey = linkedKey(pivot.table, pivot.relatedColumn);
|
|
267
|
+
const children = scan(relation.target, (candidate) => isOneOf(heldBy, candidate[targetKey]));
|
|
268
|
+
// A join table has no order of its own, so one has to be chosen or the two
|
|
269
|
+
// adapters answer with the same rows in different orders and every unit test that
|
|
270
|
+
// reads `user.roles[0]` proves nothing about production (ADR-0013). The far key is
|
|
271
|
+
// the column both ends of the link already agree on, and it is what PostgreSQL
|
|
272
|
+
// orders the join by. Sorted through the same comparator every other order in this
|
|
273
|
+
// adapter uses, so a pivot load is ordered the way `order` in the AST is.
|
|
274
|
+
const loaded = sort(loadRelations(children, target, load.nested, related), [
|
|
275
|
+
{ field: targetKey, direction: 'asc' },
|
|
276
|
+
]);
|
|
277
|
+
const collected = new Map();
|
|
278
|
+
for (const child of loaded) {
|
|
279
|
+
for (const ownerBucket of heldBy.get(bucketOf(child[targetKey])) ?? []) {
|
|
280
|
+
const existing = collected.get(ownerBucket);
|
|
281
|
+
if (existing === undefined)
|
|
282
|
+
collected.set(ownerBucket, [child]);
|
|
283
|
+
else
|
|
284
|
+
existing.push(child);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
for (const [ownerBucket, matched] of owners) {
|
|
288
|
+
const linked = collected.get(ownerBucket) ?? [];
|
|
289
|
+
for (const row of matched)
|
|
290
|
+
row[relation.name] = linked;
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
/**
|
|
294
|
+
* Loads relations in batches: one pass per relation, never one per row.
|
|
295
|
+
*
|
|
296
|
+
* SPEC.md §89 asks for N+1 to be caught by tests rather than by review, and
|
|
297
|
+
* `diagnostics.scanCount()` is what those tests read.
|
|
298
|
+
*/
|
|
299
|
+
const loadRelations = (rows, table, loads, related) => {
|
|
300
|
+
const enriched = rows.map((row) => ({ ...row }));
|
|
301
|
+
for (const load of loads) {
|
|
302
|
+
const relation = relationOf(table, load.relation);
|
|
303
|
+
if (relation.kind === 'belongsToMany') {
|
|
304
|
+
loadThroughJoinTable(enriched, table, relation, load, related);
|
|
305
|
+
continue;
|
|
306
|
+
}
|
|
307
|
+
const owned = relation.kind === 'belongsTo';
|
|
308
|
+
const localKey = owned ? relation.foreignKey : relation.ownerKey;
|
|
309
|
+
const remoteKey = owned ? relation.ownerKey : relation.foreignKey;
|
|
310
|
+
const keys = new Set(enriched.filter((row) => isKey(row[localKey])).map((row) => bucketOf(row[localKey])));
|
|
311
|
+
const target = related[relation.target];
|
|
312
|
+
const candidates = keys.size === 0
|
|
313
|
+
? []
|
|
314
|
+
: scan(relation.target, (candidate) => isOneOf(keys, candidate[remoteKey]));
|
|
315
|
+
const loaded = target === undefined
|
|
316
|
+
? candidates.map((candidate) => ({ ...candidate }))
|
|
317
|
+
: loadRelations(candidates, target, load.nested, related);
|
|
318
|
+
const grouped = groupByKey(loaded, remoteKey);
|
|
319
|
+
for (const row of enriched) {
|
|
320
|
+
const value = row[localKey];
|
|
321
|
+
const matched = (isKey(value) ? grouped.get(bucketOf(value)) : undefined) ?? [];
|
|
322
|
+
row[relation.name] = relation.kind === 'hasMany' ? matched : (matched[0] ?? null);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
return enriched;
|
|
326
|
+
};
|
|
327
|
+
const adapter = {
|
|
328
|
+
async execute(query, context) {
|
|
329
|
+
const rows = store(query.model);
|
|
330
|
+
const related = context.related ?? {};
|
|
331
|
+
if (query.operation === 'insert') {
|
|
332
|
+
const inserted = { ...(query.data ?? {}) };
|
|
333
|
+
rows.push(inserted);
|
|
334
|
+
return { ...inserted };
|
|
335
|
+
}
|
|
336
|
+
const selected = scan(query.model, (row) => matches(row, query.where));
|
|
337
|
+
if (query.operation === 'count')
|
|
338
|
+
return selected.length;
|
|
339
|
+
if (query.operation === 'delete') {
|
|
340
|
+
for (const row of selected) {
|
|
341
|
+
const index = rows.indexOf(row);
|
|
342
|
+
if (index >= 0)
|
|
343
|
+
rows.splice(index, 1);
|
|
344
|
+
}
|
|
345
|
+
return selected.length;
|
|
346
|
+
}
|
|
347
|
+
if (query.operation === 'update') {
|
|
348
|
+
for (const row of selected)
|
|
349
|
+
Object.assign(row, query.data ?? {});
|
|
350
|
+
return selected.length;
|
|
351
|
+
}
|
|
352
|
+
const ordered = sort(selected, query.order);
|
|
353
|
+
const offset = query.offset ?? 0;
|
|
354
|
+
const limited = query.limit === undefined
|
|
355
|
+
? ordered.slice(offset)
|
|
356
|
+
: ordered.slice(offset, offset + query.limit);
|
|
357
|
+
const materialised = limited.map((row) => ({ ...row }));
|
|
358
|
+
return (query.with.length > 0
|
|
359
|
+
? loadRelations(materialised, context.table, query.with, related)
|
|
360
|
+
: materialised);
|
|
361
|
+
},
|
|
362
|
+
async transaction(callback) {
|
|
363
|
+
const snapshot = new Map();
|
|
364
|
+
for (const [table, rows] of tables)
|
|
365
|
+
snapshot.set(table, rows.map((row) => ({ ...row })));
|
|
366
|
+
try {
|
|
367
|
+
return await callback();
|
|
368
|
+
}
|
|
369
|
+
catch (error) {
|
|
370
|
+
// A failed transaction leaves nothing behind, exactly as a real one would.
|
|
371
|
+
tables.clear();
|
|
372
|
+
for (const [table, rows] of snapshot)
|
|
373
|
+
tables.set(table, rows);
|
|
374
|
+
throw error;
|
|
375
|
+
}
|
|
376
|
+
},
|
|
377
|
+
introspect() {
|
|
378
|
+
return Promise.resolve({ tables: [] });
|
|
379
|
+
},
|
|
380
|
+
rows(table) {
|
|
381
|
+
return store(table).map((row) => ({ ...row }));
|
|
382
|
+
},
|
|
383
|
+
seed(table, rows) {
|
|
384
|
+
tables.set(table, rows.map((row) => ({ ...row })));
|
|
385
|
+
},
|
|
386
|
+
reset() {
|
|
387
|
+
tables.clear();
|
|
388
|
+
},
|
|
389
|
+
diagnostics: {
|
|
390
|
+
scanCount: () => scans,
|
|
391
|
+
reset: () => {
|
|
392
|
+
scans = 0;
|
|
393
|
+
},
|
|
394
|
+
},
|
|
395
|
+
};
|
|
396
|
+
return adapter;
|
|
397
|
+
};
|
|
398
|
+
//# sourceMappingURL=memory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Query AST (SPEC.md §30).
|
|
3
|
+
*
|
|
4
|
+
* The query builder never constructs adapter queries directly; it produces this
|
|
5
|
+
* neutral description instead. That keeps one stable contract between Assemora Data,
|
|
6
|
+
* database adapters, the policy layer and the AI query layer — and it is why an
|
|
7
|
+
* agent expresses a selection as structure rather than as SQL (SPEC.md §85).
|
|
8
|
+
*/
|
|
9
|
+
export type ComparisonOperator = '=' | '!=' | '>' | '>=' | '<' | '<=' | 'in' | 'not in'
|
|
10
|
+
/** Case-insensitive, in every adapter: it exists to serve search. */
|
|
11
|
+
| 'like' | 'between' | 'is null' | 'is not null';
|
|
12
|
+
export type Combinator = 'and' | 'or';
|
|
13
|
+
export type Comparison = {
|
|
14
|
+
readonly kind: 'comparison';
|
|
15
|
+
readonly combinator: Combinator;
|
|
16
|
+
readonly field: string;
|
|
17
|
+
readonly operator: ComparisonOperator;
|
|
18
|
+
readonly value?: unknown;
|
|
19
|
+
};
|
|
20
|
+
/** A parenthesised set of conditions, produced by `where(q => ...)`. */
|
|
21
|
+
export type ConditionGroup = {
|
|
22
|
+
readonly kind: 'group';
|
|
23
|
+
readonly combinator: Combinator;
|
|
24
|
+
readonly conditions: readonly Condition[];
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* A condition on a JSON document (SPEC.md §38).
|
|
28
|
+
*
|
|
29
|
+
* `path` addresses a key inside the document; an empty path means the document
|
|
30
|
+
* itself. `contains` asks whether the document includes the given fragment.
|
|
31
|
+
*/
|
|
32
|
+
export type JsonComparison = {
|
|
33
|
+
readonly kind: 'json';
|
|
34
|
+
readonly combinator: Combinator;
|
|
35
|
+
readonly field: string;
|
|
36
|
+
readonly path: readonly string[];
|
|
37
|
+
readonly operator: 'equals' | 'contains' | 'like';
|
|
38
|
+
readonly value: unknown;
|
|
39
|
+
};
|
|
40
|
+
export type Condition = Comparison | ConditionGroup | JsonComparison;
|
|
41
|
+
export type SortDirection = 'asc' | 'desc';
|
|
42
|
+
export type Order = {
|
|
43
|
+
readonly field: string;
|
|
44
|
+
readonly direction: SortDirection;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* A relation to load alongside the row, addressed by its declared name.
|
|
48
|
+
*
|
|
49
|
+
* A load carries no order of its own — `order` above sorts the rows the query
|
|
50
|
+
* selects, not the rows hanging off them. One exception is stated rather than left to
|
|
51
|
+
* the adapter: a `belongsToMany` arrives ordered by the *target's* key, ascending.
|
|
52
|
+
* A join table has no natural order, so without a rule the two adapters answer with
|
|
53
|
+
* the same rows in different orders and a unit test that reads `user.roles[0]` passes
|
|
54
|
+
* against the memory adapter and is wrong against PostgreSQL (ADR-0013).
|
|
55
|
+
*/
|
|
56
|
+
export type RelationLoad = {
|
|
57
|
+
readonly relation: string;
|
|
58
|
+
readonly nested: readonly RelationLoad[];
|
|
59
|
+
};
|
|
60
|
+
export type QueryOperation = 'select' | 'insert' | 'update' | 'delete' | 'count';
|
|
61
|
+
export type QueryAst = {
|
|
62
|
+
readonly model: string;
|
|
63
|
+
readonly operation: QueryOperation;
|
|
64
|
+
readonly where: readonly Condition[];
|
|
65
|
+
readonly order: readonly Order[];
|
|
66
|
+
readonly with: readonly RelationLoad[];
|
|
67
|
+
readonly limit?: number;
|
|
68
|
+
readonly offset?: number;
|
|
69
|
+
/** Values for an insert or an update. */
|
|
70
|
+
readonly data?: Readonly<Record<string, unknown>>;
|
|
71
|
+
};
|
|
72
|
+
export declare const emptyQuery: (model: string, operation?: QueryOperation) => QueryAst;
|
|
73
|
+
export declare const comparison: (field: string, operator: ComparisonOperator, value?: unknown) => Comparison;
|
|
74
|
+
export declare const orComparison: (field: string, operator: ComparisonOperator, value?: unknown) => Comparison;
|
|
75
|
+
export declare const jsonEquals: (field: string, path: readonly string[], value: unknown, combinator?: Combinator) => JsonComparison;
|
|
76
|
+
export declare const jsonLike: (field: string, path: readonly string[], pattern: string, combinator?: Combinator) => JsonComparison;
|
|
77
|
+
export declare const jsonContains: (field: string, value: unknown, combinator?: Combinator) => JsonComparison;
|
|
78
|
+
export declare const group: (conditions: readonly Condition[], combinator?: Combinator) => ConditionGroup;
|
|
79
|
+
//# sourceMappingURL=query-ast.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-ast.d.ts","sourceRoot":"","sources":["../src/query-ast.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Query AST (SPEC.md §30).
|
|
3
|
+
*
|
|
4
|
+
* The query builder never constructs adapter queries directly; it produces this
|
|
5
|
+
* neutral description instead. That keeps one stable contract between Assemora Data,
|
|
6
|
+
* database adapters, the policy layer and the AI query layer — and it is why an
|
|
7
|
+
* agent expresses a selection as structure rather than as SQL (SPEC.md §85).
|
|
8
|
+
*/
|
|
9
|
+
export const emptyQuery = (model, operation = 'select') => ({
|
|
10
|
+
model,
|
|
11
|
+
operation,
|
|
12
|
+
where: [],
|
|
13
|
+
order: [],
|
|
14
|
+
with: [],
|
|
15
|
+
});
|
|
16
|
+
const compare = (combinator, field, operator, value) => ({
|
|
17
|
+
kind: 'comparison',
|
|
18
|
+
combinator,
|
|
19
|
+
field,
|
|
20
|
+
operator,
|
|
21
|
+
...(value === undefined ? {} : { value }),
|
|
22
|
+
});
|
|
23
|
+
export const comparison = (field, operator, value) => compare('and', field, operator, value);
|
|
24
|
+
export const orComparison = (field, operator, value) => compare('or', field, operator, value);
|
|
25
|
+
export const jsonEquals = (field, path, value, combinator = 'and') => ({ kind: 'json', combinator, field, path, operator: 'equals', value });
|
|
26
|
+
export const jsonLike = (field, path, pattern, combinator = 'and') => ({ kind: 'json', combinator, field, path, operator: 'like', value: pattern });
|
|
27
|
+
export const jsonContains = (field, value, combinator = 'and') => ({ kind: 'json', combinator, field, path: [], operator: 'contains', value });
|
|
28
|
+
export const group = (conditions, combinator = 'and') => ({ kind: 'group', combinator, conditions });
|
|
29
|
+
//# sourceMappingURL=query-ast.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-ast.js","sourceRoot":"","sources":["../src/query-ast.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAuFH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,KAAa,EAAE,SAAS,GAAmB,QAAQ,EAAY,EAAE,CAAC,CAAC;IAC5F,KAAK;IACL,SAAS;IACT,KAAK,EAAE,EAAE;IACT,KAAK,EAAE,EAAE;IACT,IAAI,EAAE,EAAE;CACT,CAAC,CAAA;AAEF,MAAM,OAAO,GAAG,CACd,UAAsB,EACtB,KAAa,EACb,QAA4B,EAC5B,KAAe,EACH,EAAE,CAAC,CAAC;IAChB,IAAI,EAAE,YAAY;IAClB,UAAU;IACV,KAAK;IACL,QAAQ;IACR,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;CAC1C,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,CACxB,KAAa,EACb,QAA4B,EAC5B,KAAe,EACH,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAA;AAEvD,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,KAAa,EACb,QAA4B,EAC5B,KAAe,EACH,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAA;AAEtD,MAAM,CAAC,MAAM,UAAU,GAAG,CACxB,KAAa,EACb,IAAuB,EACvB,KAAc,EACd,UAAU,GAAe,KAAK,EACd,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAA;AAE3F,MAAM,CAAC,MAAM,QAAQ,GAAG,CACtB,KAAa,EACb,IAAuB,EACvB,OAAe,EACf,UAAU,GAAe,KAAK,EACd,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAA;AAElG,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,KAAa,EACb,KAAc,EACd,UAAU,GAAe,KAAK,EACd,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAA;AAEjG,MAAM,CAAC,MAAM,KAAK,GAAG,CACnB,UAAgC,EAChC,UAAU,GAAe,KAAK,EACd,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,CAAA"}
|