edinburgh 0.1.2

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.
@@ -0,0 +1,632 @@
1
+ import * as olmdb from "olmdb";
2
+ import { DatabaseError } from "olmdb";
3
+ import { Bytes } from "./bytes.js";
4
+ import { getMockModel, modelRegistry } from "./models.js";
5
+ import { assert, logLevel } from "./utils.js";
6
+ import { deserializeType, serializeType } from "./types.js";
7
+ /** @internal Symbol used to access the underlying model from a proxy */
8
+ export const TARGET_SYMBOL = Symbol('target');
9
+ const MAX_INDEX_ID_PREFIX = -1;
10
+ const INDEX_ID_PREFIX = -2;
11
+ /**
12
+ * Iterator for range queries on indexes.
13
+ * Handles common iteration logic for both primary and unique indexes.
14
+ * Implements both Iterator and Iterable interfaces for efficiency.
15
+ */
16
+ class IndexRangeIterator {
17
+ iterator;
18
+ indexId;
19
+ parentIndex;
20
+ constructor(iterator, indexId, parentIndex) {
21
+ this.iterator = iterator;
22
+ this.indexId = indexId;
23
+ this.parentIndex = parentIndex;
24
+ }
25
+ [Symbol.iterator]() {
26
+ return this;
27
+ }
28
+ next() {
29
+ if (!this.iterator)
30
+ return { done: true, value: undefined };
31
+ const entry = this.iterator.next();
32
+ if (entry.done) {
33
+ this.iterator.close();
34
+ return { done: true, value: undefined };
35
+ }
36
+ // Extract the key without the index ID
37
+ const keyBytes = new Bytes(entry.value.key);
38
+ const entryIndexId = keyBytes.readNumber();
39
+ assert(entryIndexId === this.indexId);
40
+ // Use polymorphism to get the model from the entry
41
+ const model = this.parentIndex._getModelFromEntry(keyBytes, new Bytes(entry.value.value));
42
+ if (!model) {
43
+ // This shouldn't happen, but skip if it does
44
+ return this.next();
45
+ }
46
+ return { done: false, value: model };
47
+ }
48
+ count() {
49
+ let result = 0;
50
+ for (const _ of this)
51
+ result++;
52
+ return result;
53
+ }
54
+ fetch() {
55
+ for (const model of this) {
56
+ return model; // Return the first model found
57
+ }
58
+ }
59
+ }
60
+ /**
61
+ * Base class for database indexes for efficient lookups on model fields.
62
+ *
63
+ * Indexes enable fast queries on specific field combinations and enforce uniqueness constraints.
64
+ *
65
+ * @template M - The model class this index belongs to.
66
+ * @template F - The field names that make up this index.
67
+ */
68
+ export class BaseIndex {
69
+ _fieldNames;
70
+ _MyModel;
71
+ /**
72
+ * Create a new index.
73
+ * @param MyModel - The model class this index belongs to.
74
+ * @param _fieldNames - Array of field names that make up this index.
75
+ */
76
+ constructor(MyModel, _fieldNames, isPrimary = false) {
77
+ this._fieldNames = _fieldNames;
78
+ this._MyModel = MyModel = getMockModel(MyModel);
79
+ // The primary key should be [0] in _indexes
80
+ (MyModel._indexes ||= [])[isPrimary ? 'unshift' : 'push'](this);
81
+ }
82
+ _cachedIndexId;
83
+ /**
84
+ * Deserialize index key bytes back to field values.
85
+ * @param bytes - Bytes to read from.
86
+ * @returns Array of field values.
87
+ */
88
+ _deserializeKey(bytes) {
89
+ const result = [];
90
+ for (let i = 0; i < this._fieldNames.length; i++) {
91
+ const fieldName = this._fieldNames[i];
92
+ const fieldConfig = this._MyModel.fields[fieldName];
93
+ fieldConfig.type.deserialize(result, i, bytes);
94
+ }
95
+ return result;
96
+ }
97
+ /**
98
+ * Serialize field values to bytes for index key.
99
+ * @param args - Field values to serialize (can be partial for range queries).
100
+ * @param bytes - Bytes to write to.
101
+ * @internal
102
+ */
103
+ _serializeArgs(args, bytes) {
104
+ const argsArray = Array.isArray(args) ? args : Object.values(args);
105
+ assert(argsArray.length <= this._fieldNames.length);
106
+ for (let i = 0; i < argsArray.length; i++) {
107
+ const fieldName = this._fieldNames[i];
108
+ const fieldConfig = this._MyModel.fields[fieldName];
109
+ fieldConfig.type.validateAndSerialize(argsArray, i, bytes);
110
+ }
111
+ }
112
+ /**
113
+ * Create database key from field values.
114
+ * @param args - Field values.
115
+ * @returns Database key bytes.
116
+ */
117
+ _getKeyFromArgs(args) {
118
+ assert(args.length === this._fieldNames.length);
119
+ let indexId = this._getIndexId();
120
+ let keyBytes = new Bytes().writeNumber(indexId);
121
+ this._serializeArgs(args, keyBytes);
122
+ return keyBytes.getBuffer();
123
+ }
124
+ /**
125
+ * Serialize model fields to bytes for index key.
126
+ * @param model - Model instance.
127
+ * @param bytes - Bytes to write to.
128
+ */
129
+ _serializeModel(model, bytes) {
130
+ for (let i = 0; i < this._fieldNames.length; i++) {
131
+ const fieldName = this._fieldNames[i];
132
+ const fieldConfig = this._MyModel.fields[fieldName];
133
+ fieldConfig.type.validateAndSerialize(model, fieldName, bytes, model);
134
+ }
135
+ }
136
+ /**
137
+ * Create database key from model instance.
138
+ * @param model - Model instance.
139
+ * @param includeIndexId - Whether to include index ID in key.
140
+ * @returns Database key bytes or undefined if skipped.
141
+ * @internal
142
+ */
143
+ _getKeyFromModel(model, includeIndexId) {
144
+ const bytes = new Bytes();
145
+ if (includeIndexId)
146
+ bytes.writeNumber(this._getIndexId());
147
+ this._serializeModel(model, bytes);
148
+ return bytes.getBuffer();
149
+ }
150
+ /**
151
+ * Extract field values from model for this index.
152
+ * @param model - Model instance.
153
+ * @returns Field values or undefined if should be skipped.
154
+ * @internal
155
+ */
156
+ _modelToArgs(model) {
157
+ return this._checkSkip(model) ? undefined : this._fieldNames.map((fieldName) => model[fieldName]);
158
+ }
159
+ /**
160
+ * Get or create unique index ID for this index.
161
+ * @returns Numeric index ID.
162
+ */
163
+ _getIndexId() {
164
+ // Resolve an index to a number
165
+ let indexId = this._cachedIndexId;
166
+ if (indexId == null) {
167
+ const indexNameBytes = new Bytes().writeNumber(INDEX_ID_PREFIX).writeString(this._MyModel.tableName).writeString(this._getTypeName());
168
+ for (let name of this._fieldNames) {
169
+ indexNameBytes.writeString(name);
170
+ serializeType(this._MyModel.fields[name].type, indexNameBytes);
171
+ }
172
+ const indexNameBuf = indexNameBytes.getBuffer();
173
+ let result = olmdb.get(indexNameBuf);
174
+ if (result) {
175
+ indexId = this._cachedIndexId = new Bytes(result).readNumber();
176
+ }
177
+ else {
178
+ const maxIndexIdBuf = new Bytes().writeNumber(MAX_INDEX_ID_PREFIX).getBuffer();
179
+ result = olmdb.get(maxIndexIdBuf);
180
+ indexId = result ? new Bytes(result).readNumber() + 1 : 1;
181
+ olmdb.onCommit(() => {
182
+ // Only if the transaction succeeds can we cache this id
183
+ this._cachedIndexId = indexId;
184
+ });
185
+ const idBuf = new Bytes().writeNumber(indexId).getBuffer();
186
+ olmdb.put(indexNameBuf, idBuf);
187
+ olmdb.put(maxIndexIdBuf, idBuf); // This will also cause the transaction to rerun if we were raced
188
+ if (logLevel >= 1) {
189
+ console.log(`Created index ${this._MyModel.tableName}[${this._fieldNames.join(', ')}] with id ${indexId}`);
190
+ }
191
+ }
192
+ }
193
+ return indexId;
194
+ }
195
+ /**
196
+ * Check if indexing should be skipped for a model instance.
197
+ * @param model - Model instance.
198
+ * @returns true if indexing should be skipped.
199
+ */
200
+ _checkSkip(model) {
201
+ for (const fieldName of this._fieldNames) {
202
+ const fieldConfig = this._MyModel.fields[fieldName];
203
+ if (fieldConfig.type.checkSkipIndex(model, fieldName))
204
+ return true;
205
+ }
206
+ return false;
207
+ }
208
+ /**
209
+ * Find model instances using flexible range query options.
210
+ *
211
+ * Supports exact matches, inclusive/exclusive range queries, and reverse iteration.
212
+ * For single-field indexes, you can pass values directly or in arrays.
213
+ * For multi-field indexes, pass arrays or partial arrays for prefix matching.
214
+ *
215
+ * @param opts - Query options object
216
+ * @param opts.is - Exact match (sets both `from` and `to` to same value)
217
+ * @param opts.from - Range start (inclusive)
218
+ * @param opts.after - Range start (exclusive)
219
+ * @param opts.to - Range end (inclusive)
220
+ * @param opts.before - Range end (exclusive)
221
+ * @param opts.reverse - Whether to iterate in reverse order
222
+ * @returns An iterable of model instances matching the query
223
+ *
224
+ * @example
225
+ * ```typescript
226
+ * // Exact match
227
+ * for (const user of User.byEmail.find({is: "john@example.com"})) {
228
+ * console.log(user.name);
229
+ * }
230
+ *
231
+ * // Range query (inclusive)
232
+ * for (const user of User.byEmail.find({from: "a@", to: "m@"})) {
233
+ * console.log(user.email);
234
+ * }
235
+ *
236
+ * // Range query (exclusive)
237
+ * for (const user of User.byEmail.find({after: "a@", before: "m@"})) {
238
+ * console.log(user.email);
239
+ * }
240
+ *
241
+ * // Open-ended ranges
242
+ * for (const user of User.byEmail.find({from: "m@"})) { // m@ and later
243
+ * console.log(user.email);
244
+ * }
245
+ *
246
+ * for (const user of User.byEmail.find({to: "m@"})) { // up to and including m@
247
+ * console.log(user.email);
248
+ * }
249
+ *
250
+ * // Reverse iteration
251
+ * for (const user of User.byEmail.find({reverse: true})) {
252
+ * console.log(user.email); // Z to A order
253
+ * }
254
+ *
255
+ * // Multi-field index prefix matching
256
+ * for (const item of CompositeModel.pk.find({from: ["electronics", "phones"]})) {
257
+ * console.log(item.name); // All electronics/phones items
258
+ * }
259
+ *
260
+ * // For single-field indexes, you can use the value directly
261
+ * for (const user of User.byEmail.find({is: "john@example.com"})) {
262
+ * console.log(user.name);
263
+ * }
264
+ * ```
265
+ */
266
+ find(opts = {}) {
267
+ const indexId = this._getIndexId();
268
+ let startKey = new Bytes().writeNumber(indexId);
269
+ let endKey = startKey.copy();
270
+ if ('is' in opts) {
271
+ // Exact match - set both start and end to the same value
272
+ this._serializeArgs(toArray(opts.is), startKey);
273
+ endKey = startKey.copy().increment();
274
+ }
275
+ else {
276
+ // Range query
277
+ if ('from' in opts) {
278
+ this._serializeArgs(toArray(opts.from), startKey);
279
+ }
280
+ else if ('after' in opts) {
281
+ this._serializeArgs(toArray(opts.after), startKey);
282
+ if (!startKey.increment()) {
283
+ // There can be nothing 'after' - return an empty iterator
284
+ return new IndexRangeIterator(undefined, indexId, this);
285
+ }
286
+ }
287
+ if ('to' in opts) {
288
+ this._serializeArgs(toArray(opts.to), endKey);
289
+ endKey.increment();
290
+ }
291
+ else if ('before' in opts) {
292
+ this._serializeArgs(toArray(opts.before), endKey);
293
+ }
294
+ else {
295
+ endKey = endKey.increment(); // Next indexId
296
+ }
297
+ }
298
+ // For reverse scans, swap start/end keys since OLMDB expects it
299
+ const scanStart = opts.reverse ? endKey : startKey;
300
+ const scanEnd = opts.reverse ? startKey : endKey;
301
+ const iterator = olmdb.scan({
302
+ start: scanStart?.getBuffer(),
303
+ end: scanEnd?.getBuffer(),
304
+ reverse: opts.reverse || false,
305
+ });
306
+ return new IndexRangeIterator(iterator, indexId, this);
307
+ }
308
+ }
309
+ function toArray(args) {
310
+ // Use type assertion to satisfy TypeScript while maintaining runtime correctness
311
+ return (Array.isArray(args) ? args : [args]);
312
+ }
313
+ /**
314
+ * Primary index that stores the actual model data.
315
+ *
316
+ * @template M - The model class this index belongs to.
317
+ * @template F - The field names that make up this index.
318
+ */
319
+ export class PrimaryIndex extends BaseIndex {
320
+ constructor(MyModel, fieldNames) {
321
+ super(MyModel, fieldNames, true);
322
+ if (MyModel._pk && MyModel._pk !== this) {
323
+ throw new DatabaseError(`Model ${MyModel.tableName} already has a primary key defined`, 'INIT_ERROR');
324
+ }
325
+ MyModel._pk = this;
326
+ }
327
+ /**
328
+ * Get a model instance by primary key values.
329
+ * @param args - The primary key values.
330
+ * @returns The model instance if found, undefined otherwise.
331
+ *
332
+ * @example
333
+ * ```typescript
334
+ * const user = User.pk.get("john_doe");
335
+ * ```
336
+ */
337
+ get(...args) {
338
+ let keyBuffer = this._getKeyFromArgs(args);
339
+ if (logLevel >= 3) {
340
+ console.log(`Getting primary ${this._MyModel.tableName}[${this._fieldNames.join(', ')}] (id=${this._getIndexId()}) with key`, args, keyBuffer);
341
+ }
342
+ let valueBuffer = olmdb.get(keyBuffer);
343
+ if (!valueBuffer)
344
+ return;
345
+ // This is a primary index. So we can now deserialize all primary and non-primary fields into instance values.
346
+ const model = new this._MyModel();
347
+ // We'll want to set all loaded values on the unproxied target object.
348
+ const unproxied = model[TARGET_SYMBOL];
349
+ unproxied._state = 2; // Loaded from disk, unmodified
350
+ const valueBytes = new Bytes(valueBuffer);
351
+ let primaryKeyIndex = 0;
352
+ for (const [fieldName, fieldConfig] of Object.entries(this._MyModel.fields)) {
353
+ if (this._fieldNames.includes(fieldName)) { // Value is part of primary key
354
+ unproxied[fieldName] = args[primaryKeyIndex];
355
+ primaryKeyIndex++;
356
+ }
357
+ else {
358
+ // We're passing in the proxied model
359
+ fieldConfig.type.deserialize(unproxied, fieldName, valueBytes, model);
360
+ }
361
+ }
362
+ return model;
363
+ }
364
+ /**
365
+ * Extract model from iterator entry for primary index.
366
+ * @param keyBytes - Key bytes with index ID already read.
367
+ * @param valueBytes - Value bytes from the entry.
368
+ * @returns Model instance or undefined.
369
+ * @internal
370
+ */
371
+ _getModelFromEntry(keyBytes, valueBytes) {
372
+ const model = new this._MyModel();
373
+ // We'll want to set all loaded values on the unproxied target object.
374
+ const unproxied = model[TARGET_SYMBOL];
375
+ unproxied._state = 2; // Loaded from disk, unmodified
376
+ for (let i = 0; i < this._fieldNames.length; i++) {
377
+ const fieldName = this._fieldNames[i];
378
+ const fieldConfig = this._MyModel.fields[fieldName];
379
+ fieldConfig.type.deserialize(unproxied, fieldName, keyBytes);
380
+ }
381
+ for (const [fieldName, fieldConfig] of Object.entries(this._MyModel.fields)) {
382
+ if (this._fieldNames.includes(fieldName))
383
+ continue; // Value is part of primary key
384
+ // We're passing in the proxied model
385
+ fieldConfig.type.deserialize(unproxied, fieldName, valueBytes, model);
386
+ }
387
+ return model;
388
+ }
389
+ /**
390
+ * Save primary index entry.
391
+ * @param model - Model instance.
392
+ * @param originalKey - Original key if updating.
393
+ */
394
+ _save(model, originalKey) {
395
+ // Note: this can (and usually will) be called on the non-proxied model instance.
396
+ assert(this._MyModel.prototype === model.constructor.prototype);
397
+ let newKey = this._getKeyFromModel(model, true);
398
+ if (originalKey && Buffer.compare(newKey, originalKey))
399
+ throw new DatabaseError(`Cannot change primary key for ${this._MyModel.tableName}[${this._fieldNames.join(', ')}]: ${originalKey} -> ${newKey}`, 'PRIMARY_CHANGE');
400
+ // Serialize all non-primary key fields
401
+ let valBytes = new Bytes();
402
+ for (const [fieldName, fieldConfig] of Object.entries(model._fields)) {
403
+ if (!this._fieldNames.includes(fieldName)) {
404
+ fieldConfig.type.validateAndSerialize(model, fieldName, valBytes, model);
405
+ }
406
+ }
407
+ olmdb.put(newKey, valBytes.getBuffer());
408
+ if (logLevel >= 2) {
409
+ const keyBytes = new Bytes(newKey);
410
+ let indexId = keyBytes.readNumber();
411
+ console.log(`Saved primary ${this._MyModel.tableName}[${this._fieldNames.join(', ')}] (id=${indexId}) with key`, this._deserializeKey(keyBytes), keyBytes.getBuffer());
412
+ }
413
+ return newKey;
414
+ }
415
+ _getTypeName() {
416
+ return 'primary';
417
+ }
418
+ }
419
+ /**
420
+ * Unique index that stores references to the primary key.
421
+ *
422
+ * @template M - The model class this index belongs to.
423
+ * @template F - The field names that make up this index.
424
+ */
425
+ export class UniqueIndex extends BaseIndex {
426
+ /**
427
+ * Get a model instance by unique index key values.
428
+ * @param args - The unique index key values.
429
+ * @returns The model instance if found, undefined otherwise.
430
+ *
431
+ * @example
432
+ * ```typescript
433
+ * const userByEmail = User.byEmail.get("john@example.com");
434
+ * ```
435
+ */
436
+ get(...args) {
437
+ let keyBuffer = this._getKeyFromArgs(args);
438
+ if (logLevel >= 3) {
439
+ console.log(`Getting unique ${this._MyModel.tableName}[${this._fieldNames.join(', ')}] (id=${this._getIndexId()}) with key`, args, keyBuffer);
440
+ }
441
+ let valueBuffer = olmdb.get(keyBuffer);
442
+ if (!valueBuffer)
443
+ return;
444
+ const pk = this._MyModel._pk;
445
+ const valueArgs = pk._deserializeKey(new Bytes(valueBuffer));
446
+ const result = pk.get(...valueArgs);
447
+ if (!result)
448
+ throw new DatabaseError(`Unique index ${this._MyModel.tableName}[${this._fieldNames.join(', ')}] points at non-existing primary for key: ${args.join(', ')}`, 'CONSISTENCY_ERROR');
449
+ return result;
450
+ }
451
+ /**
452
+ * Extract model from iterator entry for unique index.
453
+ * @param keyBytes - Key bytes with index ID already read.
454
+ * @param valueBytes - Value bytes from the entry.
455
+ * @returns Model instance or undefined.
456
+ * @internal
457
+ */
458
+ _getModelFromEntry(keyBytes, valueBytes) {
459
+ // For unique indexes, the value contains the primary key
460
+ const pk = this._MyModel._pk;
461
+ const primaryKeyArgs = pk._deserializeKey(valueBytes);
462
+ return pk.get(...primaryKeyArgs);
463
+ }
464
+ /**
465
+ * Save unique index entry.
466
+ * @param model - Model instance.
467
+ * @param originalKey - Original key if updating.
468
+ */
469
+ _save(model, originalKey) {
470
+ // Note: this can (and usually will) be called on the non-proxied model instance.
471
+ assert(this._MyModel.prototype === model.constructor.prototype);
472
+ let newKey = this._checkSkip(model) ? undefined : this._getKeyFromModel(model, true);
473
+ if (originalKey) {
474
+ if (newKey && Buffer.compare(newKey, originalKey) === 0) {
475
+ // No change in index key, nothing to do
476
+ return newKey;
477
+ }
478
+ olmdb.del(originalKey);
479
+ }
480
+ if (!newKey) {
481
+ // No new key, nothing to do
482
+ return;
483
+ }
484
+ // Check that this is not a duplicate key
485
+ if (olmdb.get(newKey)) {
486
+ throw new DatabaseError(`Unique constraint violation for ${model.constructor.tableName}[${this._fieldNames.join('+')}]`, 'UNIQUE_CONSTRAINT');
487
+ }
488
+ let linkKey = model.constructor._pk._getKeyFromModel(model, false);
489
+ olmdb.put(newKey, linkKey);
490
+ if (logLevel >= 2) {
491
+ console.log(`Saved unique index ${this._MyModel.tableName}[${this._fieldNames.join(', ')}] with key ${newKey}`);
492
+ }
493
+ return newKey;
494
+ }
495
+ _getTypeName() {
496
+ return 'unique';
497
+ }
498
+ }
499
+ // OLMDB does not support storing empty values, so we use a single byte value for secondary indexes.
500
+ const SECONDARY_VALUE = new Uint8Array([1]); // Single byte value for secondary indexes
501
+ /**
502
+ * Secondary index for non-unique lookups.
503
+ *
504
+ * @template M - The model class this index belongs to.
505
+ * @template F - The field names that make up this index.
506
+ */
507
+ export class SecondaryIndex extends BaseIndex {
508
+ /**
509
+ * Save secondary index entry.
510
+ * @param model - Model instance.
511
+ * @param originalKey - Original key if updating.
512
+ */
513
+ _save(model, originalKey) {
514
+ // Note: this can (and usually will) be called on the non-proxied model instance.
515
+ assert(this._MyModel.prototype === model.constructor.prototype);
516
+ let newKey = this._getKeyFromModel(model, true);
517
+ if (originalKey) {
518
+ if (newKey && Buffer.compare(newKey, originalKey) === 0) {
519
+ // No change in index key, nothing to do
520
+ return;
521
+ }
522
+ olmdb.del(originalKey);
523
+ }
524
+ if (!newKey) {
525
+ // No new key, nothing to do (index should be skipped)
526
+ return;
527
+ }
528
+ // For secondary indexes, we store a single byte value
529
+ olmdb.put(newKey, SECONDARY_VALUE);
530
+ if (logLevel >= 2) {
531
+ console.log(`Saved secondary index ${this._MyModel.tableName}[${this._fieldNames.join(', ')}] with key ${newKey}`);
532
+ }
533
+ return newKey;
534
+ }
535
+ /**
536
+ * Extract model from iterator entry for secondary index.
537
+ * @param keyBytes - Key bytes with index ID already read.
538
+ * @param valueBytes - Value bytes from the entry.
539
+ * @returns Model instance or undefined.
540
+ * @internal
541
+ */
542
+ _getModelFromEntry(keyBytes, valueBytes) {
543
+ // For secondary indexes, the primary key is stored after the index fields in the key
544
+ // First skip past the index fields
545
+ const temp = [];
546
+ for (let i = 0; i < this._fieldNames.length; i++) {
547
+ const fieldName = this._fieldNames[i];
548
+ const fieldConfig = this._MyModel.fields[fieldName];
549
+ fieldConfig.type.deserialize(temp, 0, keyBytes);
550
+ }
551
+ // Now deserialize the primary key from the remaining bytes
552
+ const pk = this._MyModel._pk;
553
+ const primaryKeyArgs = pk._deserializeKey(keyBytes);
554
+ return pk.get(...primaryKeyArgs);
555
+ }
556
+ /**
557
+ * Create secondary index key that includes both index fields and primary key.
558
+ * @param model - Model instance.
559
+ * @returns Database key bytes or undefined if skipped.
560
+ */
561
+ _getKeyFromModel(model, includeIndexId) {
562
+ const bytes = new Bytes();
563
+ if (includeIndexId)
564
+ bytes.writeNumber(this._getIndexId());
565
+ // Write the index fields
566
+ this._serializeModel(model, bytes);
567
+ // Write the primary key fields
568
+ const pk = this._MyModel._pk;
569
+ pk._serializeModel(model, bytes);
570
+ return bytes.getBuffer();
571
+ }
572
+ _getTypeName() {
573
+ return 'secondary';
574
+ }
575
+ }
576
+ export function primary(MyModel, fields) {
577
+ return new PrimaryIndex(MyModel, Array.isArray(fields) ? fields : [fields]);
578
+ }
579
+ export function unique(MyModel, fields) {
580
+ return new UniqueIndex(MyModel, Array.isArray(fields) ? fields : [fields]);
581
+ }
582
+ export function index(MyModel, fields) {
583
+ return new SecondaryIndex(MyModel, Array.isArray(fields) ? fields : [fields]);
584
+ }
585
+ /**
586
+ * Dump database contents for debugging.
587
+ *
588
+ * Prints all indexes and their data to the console for inspection.
589
+ * This is primarily useful for development and debugging purposes.
590
+ */
591
+ export function dump() {
592
+ let indexesById = new Map();
593
+ console.log("--- Database dump ---");
594
+ for (const { key, value } of olmdb.scan()) {
595
+ const kb = new Bytes(key);
596
+ const vb = new Bytes(value);
597
+ const indexId = kb.readNumber();
598
+ if (indexId === MAX_INDEX_ID_PREFIX) {
599
+ console.log("* Max index id", vb.readNumber());
600
+ }
601
+ else if (indexId === INDEX_ID_PREFIX) {
602
+ const name = kb.readString();
603
+ const type = kb.readString();
604
+ const fields = {};
605
+ while (kb.readAvailable()) {
606
+ const name = kb.readString();
607
+ fields[name] = deserializeType(kb, 0);
608
+ }
609
+ const fieldDescription = Object.entries(fields).map(([name, type]) => `${name}:${type}`);
610
+ const indexId = vb.readNumber();
611
+ console.log(`* Definition for ${type} ${indexId} for ${name}[${fieldDescription.join(',')}]`);
612
+ indexesById.set(indexId, { name, type, fields });
613
+ }
614
+ else if (indexId > 0 && indexesById.has(indexId)) {
615
+ const index = indexesById.get(indexId);
616
+ const { name, type, fields } = index;
617
+ const rowKey = {};
618
+ for (const [fieldName, fieldType] of Object.entries(fields)) {
619
+ fieldType.deserialize(rowKey, fieldName, kb);
620
+ }
621
+ const Model = modelRegistry[name];
622
+ // TODO: once we're storing schemas (serializeType) in the db, we can deserialize here
623
+ let displayValue = (type === 'secondary') ? Model._pk._deserializeKey(kb) : vb;
624
+ console.log(`* Row for ${type} ${indexId} with key ${JSON.stringify(rowKey)}`, displayValue);
625
+ }
626
+ else {
627
+ console.log(`* Unhandled ${indexId} index key=${kb} value=${vb}`);
628
+ }
629
+ }
630
+ console.log("--- End of database dump ---");
631
+ }
632
+ //# sourceMappingURL=indexes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexes.js","sourceRoot":"","sources":["../../src/indexes.ts"],"names":[],"mappings":"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"}