edinburgh 0.4.6 → 0.6.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/README.md +403 -461
- package/build/src/datapack.d.ts +9 -9
- package/build/src/datapack.js +10 -10
- package/build/src/datapack.js.map +1 -1
- package/build/src/edinburgh.d.ts +21 -10
- package/build/src/edinburgh.js +33 -55
- package/build/src/edinburgh.js.map +1 -1
- package/build/src/indexes.d.ts +99 -288
- package/build/src/indexes.js +253 -636
- package/build/src/indexes.js.map +1 -1
- package/build/src/migrate.js +17 -39
- package/build/src/migrate.js.map +1 -1
- package/build/src/models.d.ts +177 -113
- package/build/src/models.js +487 -259
- package/build/src/models.js.map +1 -1
- package/build/src/types.d.ts +41 -51
- package/build/src/types.js +39 -52
- package/build/src/types.js.map +1 -1
- package/build/src/utils.d.ts +4 -4
- package/build/src/utils.js +4 -4
- package/package.json +1 -3
- package/skill/AnyModelClass.md +7 -0
- package/skill/FindOptions.md +37 -0
- package/skill/Lifecycle Hooks.md +24 -0
- package/skill/{Model_delete.md → Lifecycle Hooks_delete.md } +2 -2
- package/skill/{Model_getPrimaryKeyHash.md → Lifecycle Hooks_getPrimaryKeyHash.md } +1 -1
- package/skill/{Model_isValid.md → Lifecycle Hooks_isValid.md } +1 -1
- package/skill/Lifecycle Hooks_migrate.md +26 -0
- package/skill/{Model_preCommit.md → Lifecycle Hooks_preCommit.md } +3 -5
- package/skill/{Model_preventPersist.md → Lifecycle Hooks_preventPersist.md } +2 -2
- package/skill/{Model_validate.md → Lifecycle Hooks_validate.md } +2 -2
- package/skill/ModelBase.md +7 -0
- package/skill/ModelClass.md +8 -0
- package/skill/SKILL.md +253 -215
- package/skill/Schema Evolution.md +19 -0
- package/skill/TypeWrapper_containsNull.md +11 -0
- package/skill/TypeWrapper_deserialize.md +9 -0
- package/skill/TypeWrapper_getError.md +11 -0
- package/skill/TypeWrapper_serialize.md +10 -0
- package/skill/TypeWrapper_serializeType.md +9 -0
- package/skill/array.md +2 -2
- package/skill/defineModel.md +23 -0
- package/skill/deleteEverything.md +8 -0
- package/skill/field.md +4 -4
- package/skill/link.md +12 -10
- package/skill/literal.md +1 -1
- package/skill/opt.md +1 -1
- package/skill/or.md +1 -1
- package/skill/record.md +1 -1
- package/skill/set.md +2 -2
- package/skill/setOnSaveCallback.md +2 -2
- package/skill/transact.md +3 -3
- package/src/datapack.ts +10 -10
- package/src/edinburgh.ts +46 -58
- package/src/indexes.ts +338 -802
- package/src/migrate.ts +15 -37
- package/src/models.ts +617 -314
- package/src/types.ts +61 -54
- package/src/utils.ts +4 -4
- package/skill/BaseIndex.md +0 -16
- package/skill/BaseIndex_batchProcess.md +0 -10
- package/skill/BaseIndex_find.md +0 -7
- package/skill/Model.md +0 -22
- package/skill/Model_findAll.md +0 -12
- package/skill/Model_migrate.md +0 -34
- package/skill/Model_replaceInto.md +0 -16
- package/skill/PrimaryIndex.md +0 -8
- package/skill/PrimaryIndex_get.md +0 -17
- package/skill/PrimaryIndex_getLazy.md +0 -13
- package/skill/SecondaryIndex.md +0 -9
- package/skill/UniqueIndex.md +0 -9
- package/skill/UniqueIndex_get.md +0 -17
- package/skill/dump.md +0 -8
- package/skill/index.md +0 -32
- package/skill/primary.md +0 -26
- package/skill/registerModel.md +0 -26
- package/skill/unique.md +0 -32
package/src/migrate.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import * as lowlevel from "olmdb/lowlevel";
|
|
2
2
|
import DataPack from "./datapack.js";
|
|
3
|
-
import {
|
|
3
|
+
import { currentTxn, type Transaction, transact } from "./edinburgh.js";
|
|
4
|
+
import { modelRegistry } from "./models.js";
|
|
4
5
|
import { dbDel, toBuffer, bytesEqual } from "./utils.js";
|
|
5
|
-
import { PrimaryIndex } from "./indexes.js";
|
|
6
6
|
import { deserializeType, TypeWrapper } from "./types.js";
|
|
7
|
-
import { transact } from "./edinburgh.js";
|
|
8
7
|
|
|
9
8
|
const INDEX_ID_PREFIX = -2;
|
|
10
9
|
|
|
@@ -118,14 +117,13 @@ export async function runMigration(options: MigrationOptions = {}): Promise<Migr
|
|
|
118
117
|
|
|
119
118
|
// Build maps of known index IDs
|
|
120
119
|
const knownIndexIds = new Set<number>();
|
|
121
|
-
const
|
|
120
|
+
const modelByPkIndexId = new Map<number, typeof modelRegistry[string]>();
|
|
122
121
|
|
|
123
122
|
for (const model of Object.values(modelRegistry)) {
|
|
124
123
|
if (options.tables && !options.tables.includes(model.tableName)) continue;
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
for (const sec of model._secondaries || []) {
|
|
124
|
+
knownIndexIds.add(model._indexId!);
|
|
125
|
+
modelByPkIndexId.set(model._indexId!, model);
|
|
126
|
+
for (const sec of Object.values(model._secondaries || {})) {
|
|
129
127
|
knownIndexIds.add(sec._indexId!);
|
|
130
128
|
}
|
|
131
129
|
}
|
|
@@ -155,24 +153,24 @@ export async function runMigration(options: MigrationOptions = {}): Promise<Migr
|
|
|
155
153
|
|
|
156
154
|
// Phase 1: Populate secondary indexes and/or rewrite row data
|
|
157
155
|
if (populateSecondaries || rewriteData) {
|
|
158
|
-
for (const [indexId,
|
|
156
|
+
for (const [indexId, model] of modelByPkIndexId) {
|
|
159
157
|
let secondaryCount = 0;
|
|
160
158
|
let rewrittenCount = 0;
|
|
161
159
|
const migrateFn = (model as any).migrate as ((record: Record<string, any>) => void) | undefined;
|
|
162
|
-
const secondaries = model._secondaries ||
|
|
160
|
+
const secondaries = Object.values(model._secondaries || {});
|
|
163
161
|
|
|
164
162
|
await forEachRow(indexId, (txn, keyBuf, valueBuf) => {
|
|
165
163
|
const valuePack = new DataPack(valueBuf);
|
|
166
164
|
const version = valuePack.readNumber();
|
|
167
|
-
if (version ===
|
|
165
|
+
if (version === model._currentVersion) return; // Already current
|
|
168
166
|
|
|
169
|
-
const versionInfo =
|
|
167
|
+
const versionInfo = model._loadVersionInfo(txn.id, version);
|
|
170
168
|
|
|
171
169
|
// Deserialize pre-migrate values from key + old-format value
|
|
172
170
|
const record: Record<string, any> = {};
|
|
173
171
|
const keyPack = new DataPack(keyBuf);
|
|
174
172
|
keyPack.readNumber(); // skip indexId
|
|
175
|
-
for (const [name, type] of
|
|
173
|
+
for (const [name, type] of model._indexFields.entries()) {
|
|
176
174
|
record[name] = type.deserialize(keyPack);
|
|
177
175
|
}
|
|
178
176
|
for (const [name, type] of versionInfo.nonKeyFields.entries()) {
|
|
@@ -191,33 +189,14 @@ export async function runMigration(options: MigrationOptions = {}): Promise<Migr
|
|
|
191
189
|
sec._write(txn, keyBuf, record as any);
|
|
192
190
|
secondaryCount++;
|
|
193
191
|
} else if (preMigrate) {
|
|
194
|
-
if (sec.
|
|
195
|
-
// Computed indexes: compare serialized keys to avoid unnecessary re-indexing
|
|
196
|
-
const oldKeyBytes = sec._serializeKeyFields(preMigrate).toUint8Array();
|
|
197
|
-
const newKeyBytes = sec._serializeKeyFields(record).toUint8Array();
|
|
198
|
-
if (!bytesEqual(oldKeyBytes, newKeyBytes)) {
|
|
199
|
-
sec._delete(txn, keyBuf, preMigrate as any);
|
|
200
|
-
sec._write(txn, keyBuf, record as any);
|
|
201
|
-
secondaryCount++;
|
|
202
|
-
}
|
|
203
|
-
} else {
|
|
204
|
-
// Existing secondary, update if migrate changed any of its fields
|
|
205
|
-
for (const [field, type] of sec._fieldTypes.entries()) {
|
|
206
|
-
if (!type.equals(preMigrate[field], record[field])) {
|
|
207
|
-
sec._delete(txn, keyBuf, preMigrate as any);
|
|
208
|
-
sec._write(txn, keyBuf, record as any);
|
|
209
|
-
secondaryCount++;
|
|
210
|
-
break;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
}
|
|
192
|
+
if (sec._update(txn, keyBuf, record as any, preMigrate)) secondaryCount++;
|
|
214
193
|
}
|
|
215
194
|
}
|
|
216
195
|
}
|
|
217
196
|
|
|
218
197
|
// Rewrite primary row data to current version
|
|
219
198
|
if (rewriteData) {
|
|
220
|
-
|
|
199
|
+
model._writePK(txn, keyBuf, record);
|
|
221
200
|
rewrittenCount++;
|
|
222
201
|
}
|
|
223
202
|
});
|
|
@@ -245,7 +224,6 @@ export async function runMigration(options: MigrationOptions = {}): Promise<Migr
|
|
|
245
224
|
const failures: Record<string, number> = {};
|
|
246
225
|
|
|
247
226
|
await forEachRow(oldDef.id, (txn, keyBuf) => {
|
|
248
|
-
let instance;
|
|
249
227
|
try {
|
|
250
228
|
// Deserialize old key
|
|
251
229
|
const keyPack = new DataPack(keyBuf);
|
|
@@ -260,7 +238,7 @@ export async function runMigration(options: MigrationOptions = {}): Promise<Migr
|
|
|
260
238
|
if (migrateFn) migrateFn(record);
|
|
261
239
|
|
|
262
240
|
// _write validates, checks duplicates, writes primary + secondaries
|
|
263
|
-
instance = new (model as any)(record, txn);
|
|
241
|
+
let instance = new (model as any)(record, txn);
|
|
264
242
|
instance._write(txn);
|
|
265
243
|
dbDel(txn.id, keyBuf);
|
|
266
244
|
converted++;
|
|
@@ -271,7 +249,7 @@ export async function runMigration(options: MigrationOptions = {}): Promise<Migr
|
|
|
271
249
|
failures['error'] = (failures['error'] || 0) + 1;
|
|
272
250
|
}
|
|
273
251
|
} finally {
|
|
274
|
-
|
|
252
|
+
txn.instances.clear(); // We've already handled the _write() ourselves
|
|
275
253
|
}
|
|
276
254
|
});
|
|
277
255
|
|