edinburgh 0.4.6 → 0.5.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 +263 -381
- package/build/src/datapack.js +1 -1
- package/build/src/datapack.js.map +1 -1
- package/build/src/edinburgh.d.ts +5 -5
- package/build/src/edinburgh.js +6 -7
- package/build/src/edinburgh.js.map +1 -1
- package/build/src/indexes.d.ts +44 -113
- package/build/src/indexes.js +145 -175
- package/build/src/indexes.js.map +1 -1
- package/build/src/migrate.js +11 -31
- package/build/src/migrate.js.map +1 -1
- package/build/src/models.d.ts +73 -54
- package/build/src/models.js +110 -171
- package/build/src/models.js.map +1 -1
- package/build/src/types.d.ts +29 -21
- package/build/src/types.js +16 -30
- package/build/src/types.js.map +1 -1
- package/package.json +1 -3
- package/skill/BaseIndex_batchProcess.md +1 -1
- package/skill/BaseIndex_find.md +2 -2
- package/skill/BaseIndex_find_2.md +7 -0
- package/skill/BaseIndex_find_3.md +7 -0
- package/skill/BaseIndex_find_4.md +7 -0
- package/skill/Model.md +5 -7
- package/skill/Model_batchProcess.md +8 -0
- package/skill/Model_delete.md +1 -1
- package/skill/Model_migrate.md +2 -4
- package/skill/Model_preCommit.md +2 -4
- package/skill/Model_preventPersist.md +1 -1
- package/skill/Model_replaceInto.md +2 -2
- package/skill/NonPrimaryIndex.md +10 -0
- package/skill/SKILL.md +140 -150
- package/skill/SecondaryIndex.md +2 -2
- package/skill/UniqueIndex.md +2 -2
- package/skill/defineModel.md +22 -0
- package/skill/field.md +2 -2
- package/skill/link.md +11 -9
- package/skill/transact.md +2 -2
- package/src/datapack.ts +1 -1
- package/src/edinburgh.ts +6 -9
- package/src/indexes.ts +155 -271
- package/src/migrate.ts +9 -30
- package/src/models.ts +186 -180
- package/src/types.ts +31 -26
- package/skill/Model_findAll.md +0 -12
- package/skill/PrimaryIndex.md +0 -8
- package/skill/PrimaryIndex_get.md +0 -17
- package/skill/PrimaryIndex_getLazy.md +0 -13
- package/skill/UniqueIndex_get.md +0 -17
- 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/README.md
CHANGED
|
@@ -22,39 +22,41 @@ import * as E from "edinburgh";
|
|
|
22
22
|
// Initialize the database (optional, defaults to ".edinburgh")
|
|
23
23
|
E.init("./my-database");
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
@E.registerModel
|
|
27
|
-
class User extends E.Model<User> {
|
|
28
|
-
// Define a primary key (optional, defaults to using the "id" field)
|
|
29
|
-
static pk = E.primary(User, "id");
|
|
30
|
-
// Define a unique index on the email field
|
|
31
|
-
static byEmail = E.unique(User, "email");
|
|
32
|
-
|
|
33
|
-
// Define fields with simple types -- they will be type-checked at compile time and validated at runtime.
|
|
25
|
+
const User = E.defineModel(class {
|
|
34
26
|
id = E.field(E.identifier);
|
|
35
27
|
name = E.field(E.string);
|
|
36
28
|
age = E.field(E.number);
|
|
37
|
-
email = E.field(E.opt(E.string));
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
29
|
+
email = E.field(E.opt(E.string));
|
|
30
|
+
// Optional link to another instance of this model (needs a function as `User` is not defined yet at this point)
|
|
31
|
+
supervisor = E.field(E.opt(E.link(() => User)));
|
|
32
|
+
// A field with a more elaborate type. In TypeScript: `User | User[] | "unknown" | "whatever"`, defaulting to "unknown".
|
|
33
|
+
something = E.field(
|
|
34
|
+
E.or(
|
|
35
|
+
E.link(() => User),
|
|
36
|
+
E.array(E.link(() => User)),
|
|
37
|
+
E.literal("unknown"),
|
|
38
|
+
E.literal("whatever")
|
|
39
|
+
),
|
|
40
|
+
{ default: "unknown" }
|
|
41
|
+
);
|
|
42
|
+
}, {
|
|
43
|
+
pk: "id",
|
|
44
|
+
unique: {
|
|
45
|
+
byEmail: "email",
|
|
46
|
+
},
|
|
47
|
+
tableName: "User",
|
|
48
|
+
});
|
|
45
49
|
|
|
46
|
-
// Use in transactions
|
|
47
50
|
await E.transact(() => {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const john = new User({ // Unique 'id' is automatically generated if not provided
|
|
53
|
-
name: "John Doe",
|
|
51
|
+
// Unique 'id' values are auto-generated if not provided
|
|
52
|
+
const boss = new User({ name: "Big Boss", age: 50 });
|
|
53
|
+
new User({
|
|
54
|
+
name: "John Doe",
|
|
54
55
|
age: 41,
|
|
55
56
|
email: "john@example.com",
|
|
56
57
|
supervisor: boss, // Link to another model instance
|
|
57
58
|
});
|
|
59
|
+
// Newly instantiated models are automatically saved to the database on transaction commit
|
|
58
60
|
});
|
|
59
61
|
|
|
60
62
|
await E.transact(() => {
|
|
@@ -66,41 +68,31 @@ await E.transact(() => {
|
|
|
66
68
|
john.age++;
|
|
67
69
|
|
|
68
70
|
// The supervisor object is lazy loaded on first access
|
|
69
|
-
console.log(`${john.supervisor!.name} is ${john.name}'s supervisor`);
|
|
71
|
+
console.log(`${john.supervisor!.name} is ${john.name}'s supervisor`);
|
|
70
72
|
});
|
|
71
73
|
```
|
|
72
74
|
|
|
73
75
|
## Tutorial
|
|
74
76
|
|
|
75
|
-
### TypeScript Configuration
|
|
76
|
-
|
|
77
|
-
When using TypeScript to transpile to JavaScript, make sure to enable the following options in your `tsconfig.json`:
|
|
78
|
-
|
|
79
|
-
```json
|
|
80
|
-
{
|
|
81
|
-
"compilerOptions": {
|
|
82
|
-
"target": "es2022",
|
|
83
|
-
"experimentalDecorators": true
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
```
|
|
87
77
|
|
|
88
78
|
### Defining Models
|
|
89
79
|
|
|
90
|
-
Models are
|
|
80
|
+
Models are plain, usually anonymous, classes passed to `E.defineModel()`:
|
|
91
81
|
|
|
92
82
|
```typescript
|
|
93
83
|
import * as E from "edinburgh";
|
|
94
84
|
|
|
95
|
-
|
|
96
|
-
class User extends E.Model<User> {
|
|
97
|
-
static pk = E.primary(User, "id");
|
|
98
|
-
|
|
85
|
+
const User = E.defineModel(class {
|
|
99
86
|
id = E.field(E.identifier);
|
|
100
87
|
name = E.field(E.string);
|
|
101
88
|
email = E.field(E.string);
|
|
102
89
|
age = E.field(E.number);
|
|
103
|
-
}
|
|
90
|
+
}, {
|
|
91
|
+
pk: "id",
|
|
92
|
+
unique: {
|
|
93
|
+
byEmail: "email",
|
|
94
|
+
},
|
|
95
|
+
});
|
|
104
96
|
```
|
|
105
97
|
|
|
106
98
|
Instance fields are declared with `E.field(type, options?)`. Available types:
|
|
@@ -124,16 +116,13 @@ Instance fields are declared with `E.field(type, options?)`. Available types:
|
|
|
124
116
|
#### Defaults
|
|
125
117
|
|
|
126
118
|
```typescript
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
static pk = E.primary(Post, "id");
|
|
130
|
-
|
|
131
|
-
id = E.field(E.identifier); // auto-generated
|
|
119
|
+
const Post = E.defineModel(class {
|
|
120
|
+
id = E.field(E.identifier); // auto-generated
|
|
132
121
|
title = E.field(E.string);
|
|
133
122
|
status = E.field(E.or("draft", "published"), {default: "draft"});
|
|
134
|
-
tags = E.field(E.array(E.string), {default: () => []});
|
|
135
|
-
createdAt = E.field(E.dateTime);
|
|
136
|
-
}
|
|
123
|
+
tags = E.field(E.array(E.string), {default: () => []}); // use function for mutable defaults
|
|
124
|
+
createdAt = E.field(E.dateTime); // dateTime defaults to new Date()
|
|
125
|
+
}, { pk: "id" });
|
|
137
126
|
```
|
|
138
127
|
|
|
139
128
|
### Transactions
|
|
@@ -146,8 +135,8 @@ E.init("./my-database");
|
|
|
146
135
|
|
|
147
136
|
// Create
|
|
148
137
|
await E.transact(() => {
|
|
149
|
-
|
|
150
|
-
|
|
138
|
+
// User.id is auto-generated
|
|
139
|
+
new User({name: "Alice", email: "alice@example.com", age: 30});
|
|
151
140
|
});
|
|
152
141
|
|
|
153
142
|
// Read + Update
|
|
@@ -170,27 +159,26 @@ Transactions auto-retry on conflict (up to 6 times by default). Keep transaction
|
|
|
170
159
|
Edinburgh supports three index types:
|
|
171
160
|
|
|
172
161
|
```typescript
|
|
173
|
-
|
|
174
|
-
class Product extends E.Model<Product> {
|
|
175
|
-
static pk = E.primary(Product, "sku"); // primary: one per model, stores data
|
|
176
|
-
static byName = E.unique(Product, "name"); // unique: enforces uniqueness + fast lookup
|
|
177
|
-
static byCategory = E.index(Product, "category");// secondary: non-unique, for queries
|
|
178
|
-
|
|
162
|
+
const Product = E.defineModel(class {
|
|
179
163
|
sku = E.field(E.string);
|
|
180
164
|
name = E.field(E.string);
|
|
181
165
|
category = E.field(E.string);
|
|
182
166
|
price = E.field(E.number);
|
|
183
|
-
}
|
|
167
|
+
}, {
|
|
168
|
+
pk: "sku",
|
|
169
|
+
unique: { byName: "name" },
|
|
170
|
+
index: { byCategory: "category" },
|
|
171
|
+
});
|
|
184
172
|
```
|
|
185
173
|
|
|
186
|
-
If no `
|
|
174
|
+
If no `pk` is provided, Edinburgh auto-creates one on an `id` field, adding it as an `E.identifier` field if needed.
|
|
187
175
|
|
|
188
176
|
#### Lookups
|
|
189
177
|
|
|
190
178
|
```typescript
|
|
191
179
|
await E.transact(() => {
|
|
192
180
|
// Primary key lookup
|
|
193
|
-
const
|
|
181
|
+
const p1 = Product.get("SKU-001");
|
|
194
182
|
|
|
195
183
|
// Unique index lookup
|
|
196
184
|
const p2 = Product.byName.get("Widget");
|
|
@@ -211,18 +199,18 @@ await E.transact(() => {
|
|
|
211
199
|
}
|
|
212
200
|
|
|
213
201
|
// Range (inclusive)
|
|
214
|
-
for (const p of Product.
|
|
202
|
+
for (const p of Product.find({from: "A", to: "M"})) {
|
|
215
203
|
console.log(p.sku);
|
|
216
204
|
}
|
|
217
205
|
|
|
218
206
|
// Exclusive bounds
|
|
219
|
-
for (const p of Product.
|
|
207
|
+
for (const p of Product.find({after: "A", before: "M"})) { ... }
|
|
220
208
|
|
|
221
209
|
// Open-ended
|
|
222
|
-
for (const p of Product.
|
|
210
|
+
for (const p of Product.find({from: "M"})) { ... }
|
|
223
211
|
|
|
224
212
|
// Reverse
|
|
225
|
-
for (const p of Product.
|
|
213
|
+
for (const p of Product.find({reverse: true})) { ... }
|
|
226
214
|
|
|
227
215
|
// Count and fetch helpers
|
|
228
216
|
const count = Product.byCategory.find({is: "electronics"}).count();
|
|
@@ -230,25 +218,24 @@ await E.transact(() => {
|
|
|
230
218
|
});
|
|
231
219
|
```
|
|
232
220
|
|
|
233
|
-
#### Composite
|
|
221
|
+
#### Composite Primary Keys
|
|
234
222
|
|
|
235
223
|
```typescript
|
|
236
|
-
|
|
237
|
-
class Event extends E.Model<Event> {
|
|
238
|
-
static pk = E.primary(Event, ["year", "month", "id"]);
|
|
239
|
-
|
|
224
|
+
const Event = E.defineModel(class {
|
|
240
225
|
year = E.field(E.number);
|
|
241
226
|
month = E.field(E.number);
|
|
242
227
|
id = E.field(E.identifier);
|
|
243
228
|
title = E.field(E.string);
|
|
244
|
-
}
|
|
229
|
+
}, {
|
|
230
|
+
pk: ["year", "month", "id"] as const,
|
|
231
|
+
});
|
|
245
232
|
|
|
246
233
|
await E.transact(() => {
|
|
247
234
|
// Prefix matching — find all events in 2025
|
|
248
|
-
for (const e of Event.
|
|
235
|
+
for (const e of Event.find({is: [2025]})) { ... }
|
|
249
236
|
|
|
250
237
|
// Find events in March 2025
|
|
251
|
-
for (const e of Event.
|
|
238
|
+
for (const e of Event.find({is: [2025, 3]})) { ... }
|
|
252
239
|
});
|
|
253
240
|
```
|
|
254
241
|
|
|
@@ -257,10 +244,7 @@ await E.transact(() => {
|
|
|
257
244
|
You can freely add regular methods, getters, and other non-persistent properties to model classes. These work normally in JavaScript but are **not stored in the database** and **not synchronized** across transactions or processes.
|
|
258
245
|
|
|
259
246
|
```typescript
|
|
260
|
-
|
|
261
|
-
class User extends E.Model<User> {
|
|
262
|
-
static pk = E.primary(User, "id");
|
|
263
|
-
id = E.field(E.identifier);
|
|
247
|
+
const User = E.defineModel(class {
|
|
264
248
|
firstName = E.field(E.string);
|
|
265
249
|
lastName = E.field(E.string);
|
|
266
250
|
|
|
@@ -275,27 +259,30 @@ class User extends E.Model<User> {
|
|
|
275
259
|
greet(): string {
|
|
276
260
|
return `Hello, ${this.fullName}!`;
|
|
277
261
|
}
|
|
278
|
-
}
|
|
262
|
+
});
|
|
279
263
|
```
|
|
280
264
|
|
|
281
265
|
#### Computed Indexes
|
|
282
266
|
|
|
283
|
-
Instead of naming fields, you can pass a
|
|
267
|
+
Instead of naming fields, you can pass a function as an index specification. The function receives a model instance and returns an **array** of index key values. Each element creates a separate index entry, enabling multi-value indexes. Return `[]` to skip indexing for that instance (partial index).
|
|
284
268
|
|
|
285
269
|
```typescript
|
|
286
|
-
|
|
287
|
-
class Article extends E.Model<Article> {
|
|
288
|
-
static pk = E.primary(Article, "id");
|
|
289
|
-
static byFullName = E.unique(Article, (a: Article) => [`${a.firstName} ${a.lastName}`]);
|
|
290
|
-
static byWord = E.index(Article, (a: Article) => a.title.toLowerCase().split(" "));
|
|
291
|
-
static byDomain = E.index(Article, (a: Article) => a.email ? [a.email.split("@")[1]] : []);
|
|
292
|
-
|
|
270
|
+
const Article = E.defineModel(class {
|
|
293
271
|
id = E.field(E.identifier);
|
|
294
272
|
firstName = E.field(E.string);
|
|
295
273
|
lastName = E.field(E.string);
|
|
296
274
|
title = E.field(E.string);
|
|
297
275
|
email = E.field(E.opt(E.string));
|
|
298
|
-
}
|
|
276
|
+
}, {
|
|
277
|
+
pk: "id",
|
|
278
|
+
unique: {
|
|
279
|
+
byFullName: (a: any) => [`${a.firstName} ${a.lastName}`], // computed covering unique index
|
|
280
|
+
},
|
|
281
|
+
index: {
|
|
282
|
+
byDomain: (a: any) => a.email ? [a.email.split("@")[1]] : [], // computed partial index
|
|
283
|
+
byWord: (a: any) => a.title.toLowerCase().split(" "), // computed multi-index
|
|
284
|
+
},
|
|
285
|
+
});
|
|
299
286
|
|
|
300
287
|
await E.transact(() => {
|
|
301
288
|
new Article({ firstName: "Jane", lastName: "Doe", title: "Hello World", email: "jane@acme.com" });
|
|
@@ -311,34 +298,29 @@ await E.transact(() => {
|
|
|
311
298
|
});
|
|
312
299
|
```
|
|
313
300
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
### Relationships (Links)
|
|
301
|
+
### Relationships
|
|
317
302
|
|
|
318
|
-
Use `E.link(Model)` for foreign keys:
|
|
303
|
+
Use `E.link(Model)` for foreign keys. Use a thunk (a function that just returns a value) for forward references when needed:
|
|
319
304
|
|
|
320
305
|
```typescript
|
|
321
|
-
|
|
322
|
-
class Author extends E.Model<Author> {
|
|
323
|
-
static pk = E.primary(Author, "id");
|
|
306
|
+
const Author = E.defineModel(class {
|
|
324
307
|
id = E.field(E.identifier);
|
|
325
308
|
name = E.field(E.string);
|
|
326
|
-
}
|
|
309
|
+
}, { pk: "id" });
|
|
327
310
|
|
|
328
|
-
|
|
329
|
-
class Book extends E.Model<Book> {
|
|
330
|
-
static pk = E.primary(Book, "id");
|
|
311
|
+
const Book = E.defineModel(class {
|
|
331
312
|
id = E.field(E.identifier);
|
|
332
313
|
title = E.field(E.string);
|
|
333
314
|
author = E.field(E.link(Author));
|
|
334
|
-
}
|
|
315
|
+
}, { pk: "id" });
|
|
335
316
|
|
|
336
317
|
await E.transact(() => {
|
|
337
318
|
const author = new Author({name: "Tolkien"});
|
|
338
319
|
const book = new Book({title: "The Hobbit", author});
|
|
339
320
|
|
|
340
321
|
// Later: linked models are lazy-loaded on property access
|
|
341
|
-
const b = Book.
|
|
322
|
+
const b = Book.get(book.id)!;
|
|
323
|
+
console.log(b.author.id); // no need to load yet..
|
|
342
324
|
console.log(b.author.name); // loads Author automatically (~1µs)
|
|
343
325
|
});
|
|
344
326
|
```
|
|
@@ -347,7 +329,7 @@ await E.transact(() => {
|
|
|
347
329
|
|
|
348
330
|
```typescript
|
|
349
331
|
await E.transact(() => {
|
|
350
|
-
const user = User.
|
|
332
|
+
const user = User.get(someId);
|
|
351
333
|
if (user) user.delete();
|
|
352
334
|
});
|
|
353
335
|
```
|
|
@@ -365,10 +347,16 @@ await E.transact(() => {
|
|
|
365
347
|
user.preventPersist(); // exclude from commit
|
|
366
348
|
});
|
|
367
349
|
|
|
368
|
-
//
|
|
350
|
+
// find() iterates all instances (or use range options)
|
|
369
351
|
await E.transact(() => {
|
|
370
|
-
for (const user of User.
|
|
371
|
-
for (const user of User.
|
|
352
|
+
for (const user of User.find()) { ... }
|
|
353
|
+
for (const user of User.find({reverse: true})) { ... }
|
|
354
|
+
|
|
355
|
+
// {fetch: 'first'} returns a single instance or undefined
|
|
356
|
+
const first = User.find({fetch: 'first'});
|
|
357
|
+
|
|
358
|
+
// {fetch: 'single'} returns a single instance, or throws if there are none or more than one
|
|
359
|
+
const only = User.find({fetch: 'single'});
|
|
372
360
|
});
|
|
373
361
|
|
|
374
362
|
// replaceInto: upsert by primary key
|
|
@@ -382,7 +370,7 @@ await E.transact(() => {
|
|
|
382
370
|
For large datasets, `batchProcess` auto-commits in batches:
|
|
383
371
|
|
|
384
372
|
```typescript
|
|
385
|
-
await Product.
|
|
373
|
+
await Product.batchProcess({ limitRows: 1000 }, (product) => {
|
|
386
374
|
product.category = "archived";
|
|
387
375
|
});
|
|
388
376
|
// Commits every ~1 second or 4096 rows (configurable via limitSeconds, limitRows)
|
|
@@ -390,12 +378,10 @@ await Product.byCategory.batchProcess({is: "old"}, (product) => {
|
|
|
390
378
|
|
|
391
379
|
### Lazy Schema Migrations
|
|
392
380
|
|
|
393
|
-
When you change a model's schema, Edinburgh
|
|
381
|
+
When you change a model's schema, Edinburgh lazily migrates old records on access. You can provide a `static migrate(record)` function to transform old rows:
|
|
394
382
|
|
|
395
383
|
```typescript
|
|
396
|
-
|
|
397
|
-
class User extends E.Model<User> {
|
|
398
|
-
static pk = E.primary(User, "id");
|
|
384
|
+
const UserV2 = E.defineModel(class {
|
|
399
385
|
id = E.field(E.identifier);
|
|
400
386
|
name = E.field(E.string);
|
|
401
387
|
role = E.field(E.string); // newly added field
|
|
@@ -438,9 +424,7 @@ console.log(result.secondaries); // { User: 1500 }
|
|
|
438
424
|
Compute derived fields before data is written:
|
|
439
425
|
|
|
440
426
|
```typescript
|
|
441
|
-
|
|
442
|
-
class Article extends E.Model<Article> {
|
|
443
|
-
static pk = E.primary(Article, "id");
|
|
427
|
+
const Article = E.defineModel(class {
|
|
444
428
|
id = E.field(E.identifier);
|
|
445
429
|
title = E.field(E.string);
|
|
446
430
|
slug = E.field(E.string);
|
|
@@ -448,7 +432,7 @@ class Article extends E.Model<Article> {
|
|
|
448
432
|
preCommit() {
|
|
449
433
|
this.slug = this.title.toLowerCase().replace(/\s+/g, "-");
|
|
450
434
|
}
|
|
451
|
-
}
|
|
435
|
+
}, { pk: "id" });
|
|
452
436
|
```
|
|
453
437
|
|
|
454
438
|
### Change Tracking
|
|
@@ -493,7 +477,7 @@ The following is auto-generated from `src/edinburgh.ts`:
|
|
|
493
477
|
|
|
494
478
|
**Signature:** `() => void`
|
|
495
479
|
|
|
496
|
-
### init · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
480
|
+
### init · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L65)
|
|
497
481
|
|
|
498
482
|
Initialize the database with the specified directory path.
|
|
499
483
|
This function may be called multiple times with the same parameters. If it is not called before the first transact(),
|
|
@@ -511,7 +495,7 @@ the database will be automatically initialized with the default directory.
|
|
|
511
495
|
init("./my-database");
|
|
512
496
|
```
|
|
513
497
|
|
|
514
|
-
### transact · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
498
|
+
### transact · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L116)
|
|
515
499
|
|
|
516
500
|
Executes a function within a database transaction context.
|
|
517
501
|
|
|
@@ -545,7 +529,7 @@ times.
|
|
|
545
529
|
|
|
546
530
|
```typescript
|
|
547
531
|
const paid = await E.transact(() => {
|
|
548
|
-
const user = User.
|
|
532
|
+
const user = User.get("john_doe");
|
|
549
533
|
if (user.credits > 0) {
|
|
550
534
|
user.credits--;
|
|
551
535
|
return true;
|
|
@@ -556,12 +540,12 @@ const paid = await E.transact(() => {
|
|
|
556
540
|
```typescript
|
|
557
541
|
// Transaction with automatic retry on conflicts
|
|
558
542
|
await E.transact(() => {
|
|
559
|
-
const counter = Counter.
|
|
543
|
+
const counter = Counter.get("global") || new Counter({id: "global", value: 0});
|
|
560
544
|
counter.value++;
|
|
561
545
|
});
|
|
562
546
|
```
|
|
563
547
|
|
|
564
|
-
### setMaxRetryCount · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
548
|
+
### setMaxRetryCount · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L206)
|
|
565
549
|
|
|
566
550
|
Set the maximum number of retries for a transaction in case of conflicts.
|
|
567
551
|
The default value is 6. Setting it to 0 will disable retries and cause transactions to fail immediately on conflict.
|
|
@@ -572,7 +556,7 @@ The default value is 6. Setting it to 0 will disable retries and cause transacti
|
|
|
572
556
|
|
|
573
557
|
- `count: number` - The maximum number of retries for a transaction.
|
|
574
558
|
|
|
575
|
-
### setOnSaveCallback · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
559
|
+
### setOnSaveCallback · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L220)
|
|
576
560
|
|
|
577
561
|
Set a callback function to be called after a model is saved and committed.
|
|
578
562
|
|
|
@@ -585,11 +569,11 @@ Set a callback function to be called after a model is saved and committed.
|
|
|
585
569
|
- A sequential number. Higher numbers have been committed after lower numbers.
|
|
586
570
|
- A map of model instances to their changes. The change can be "created", "deleted", or an object containing the old values.
|
|
587
571
|
|
|
588
|
-
### deleteEverything · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
572
|
+
### deleteEverything · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L225)
|
|
589
573
|
|
|
590
574
|
**Signature:** `() => Promise<void>`
|
|
591
575
|
|
|
592
|
-
### Model · [abstract class](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
576
|
+
### Model · [abstract class](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
593
577
|
|
|
594
578
|
[object Object],[object Object],[object Object],[object Object],[object Object]
|
|
595
579
|
|
|
@@ -600,37 +584,35 @@ Set a callback function to be called after a model is saved and committed.
|
|
|
600
584
|
**Examples:**
|
|
601
585
|
|
|
602
586
|
```typescript
|
|
603
|
-
|
|
604
|
-
class User extends E.Model<User> {
|
|
605
|
-
static pk = E.primary(User, "id");
|
|
606
|
-
|
|
587
|
+
const User = E.defineModel(class {
|
|
607
588
|
id = E.field(E.identifier);
|
|
608
589
|
name = E.field(E.string);
|
|
609
590
|
email = E.field(E.string);
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
}
|
|
591
|
+
}, {
|
|
592
|
+
pk: "id",
|
|
593
|
+
unique: { byEmail: "email" },
|
|
594
|
+
});
|
|
613
595
|
```
|
|
614
596
|
|
|
615
|
-
#### Model.tableName · [static property](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
597
|
+
#### Model.tableName · [static property](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
616
598
|
|
|
617
599
|
The database table name (defaults to class name).
|
|
618
600
|
|
|
619
601
|
**Type:** `string`
|
|
620
602
|
|
|
621
|
-
#### Model.override · [static property](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
603
|
+
#### Model.override · [static property](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
622
604
|
|
|
623
|
-
When true,
|
|
605
|
+
When true, defineModel replaces an existing model with the same tableName.
|
|
624
606
|
|
|
625
607
|
**Type:** `boolean`
|
|
626
608
|
|
|
627
|
-
#### Model.fields · [static property](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
609
|
+
#### Model.fields · [static property](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
628
610
|
|
|
629
611
|
Field configuration metadata.
|
|
630
612
|
|
|
631
613
|
**Type:** `Record<string | number | symbol, FieldConfig<unknown>>`
|
|
632
614
|
|
|
633
|
-
#### Model.migrate · [static method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
615
|
+
#### Model.migrate · [static method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
634
616
|
|
|
635
617
|
Optional migration function called when deserializing rows written with an older schema version.
|
|
636
618
|
Receives a plain record with all fields (primary key fields + value fields) and should mutate it
|
|
@@ -652,9 +634,7 @@ will only be updated when `runMigration()` is run (not during lazy loading).
|
|
|
652
634
|
**Examples:**
|
|
653
635
|
|
|
654
636
|
```typescript
|
|
655
|
-
|
|
656
|
-
class User extends E.Model<User> {
|
|
657
|
-
static pk = E.primary(User, "id");
|
|
637
|
+
const User = E.defineModel(class {
|
|
658
638
|
id = E.field(E.identifier);
|
|
659
639
|
name = E.field(E.string);
|
|
660
640
|
role = E.field(E.string); // new field
|
|
@@ -662,35 +642,43 @@ class User extends E.Model<User> {
|
|
|
662
642
|
static migrate(record: Record<string, any>) {
|
|
663
643
|
record.role ??= "user"; // default for rows that predate the 'role' field
|
|
664
644
|
}
|
|
665
|
-
}
|
|
645
|
+
}, { pk: "id" });
|
|
666
646
|
```
|
|
667
647
|
|
|
668
|
-
#### Model.
|
|
648
|
+
#### Model.get · [static method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
669
649
|
|
|
670
|
-
|
|
671
|
-
automatically when using `transact()`, but in case you need to access `Model.fields` directly before the first
|
|
672
|
-
transaction, you can call this method manually.
|
|
673
|
-
|
|
674
|
-
**Signature:** `(reset?: boolean) => void`
|
|
650
|
+
**Signature:** `(...args: any[]) => any`
|
|
675
651
|
|
|
676
652
|
**Parameters:**
|
|
677
653
|
|
|
678
|
-
- `
|
|
654
|
+
- `args: any[]`
|
|
655
|
+
|
|
656
|
+
#### Model.getLazy · [static method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
657
|
+
|
|
658
|
+
**Signature:** `(...args: any[]) => any`
|
|
659
|
+
|
|
660
|
+
**Parameters:**
|
|
679
661
|
|
|
680
|
-
|
|
662
|
+
- `args: any[]`
|
|
681
663
|
|
|
682
|
-
|
|
664
|
+
#### Model.find · [static method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
683
665
|
|
|
684
|
-
**Signature:**
|
|
666
|
+
**Signature:** `(opts?: any) => any`
|
|
685
667
|
|
|
686
668
|
**Parameters:**
|
|
687
669
|
|
|
688
|
-
- `
|
|
689
|
-
|
|
670
|
+
- `opts?: any`
|
|
671
|
+
|
|
672
|
+
#### Model.batchProcess · [static method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
673
|
+
|
|
674
|
+
**Signature:** `(opts: any, callback?: any) => any`
|
|
675
|
+
|
|
676
|
+
**Parameters:**
|
|
690
677
|
|
|
691
|
-
|
|
678
|
+
- `opts: any`
|
|
679
|
+
- `callback?: any`
|
|
692
680
|
|
|
693
|
-
#### Model.replaceInto · [static method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
681
|
+
#### Model.replaceInto · [static method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
694
682
|
|
|
695
683
|
Load an existing instance by primary key and update it, or create a new one.
|
|
696
684
|
|
|
@@ -698,16 +686,16 @@ The provided object must contain all primary key fields. If a matching row exist
|
|
|
698
686
|
the remaining properties from `obj` are set on the loaded instance. Otherwise a
|
|
699
687
|
new instance is created with `obj` as its initial properties.
|
|
700
688
|
|
|
701
|
-
**Signature:** `<T extends typeof Model<any>>(this: T, obj: Partial<
|
|
689
|
+
**Signature:** `<T extends typeof Model<any>>(this: T, obj: Partial<Record<string, any>>) => InstanceType<T>`
|
|
702
690
|
|
|
703
691
|
**Parameters:**
|
|
704
692
|
|
|
705
693
|
- `this: T`
|
|
706
|
-
- `obj: Partial<
|
|
694
|
+
- `obj: Partial<Record<string, any>>` - - Partial model data that **must** include every primary key field.
|
|
707
695
|
|
|
708
696
|
**Returns:** The loaded-and-updated or newly created instance.
|
|
709
697
|
|
|
710
|
-
#### model.preCommit · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
698
|
+
#### model.preCommit · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
711
699
|
|
|
712
700
|
Optional hook called on each modified instance right before the transaction commits.
|
|
713
701
|
Runs before data is written to disk, so changes made here are included in the commit.
|
|
@@ -723,9 +711,7 @@ Common use cases:
|
|
|
723
711
|
**Examples:**
|
|
724
712
|
|
|
725
713
|
```typescript
|
|
726
|
-
|
|
727
|
-
class Post extends E.Model<Post> {
|
|
728
|
-
static pk = E.primary(Post, "id");
|
|
714
|
+
const Post = E.defineModel(class {
|
|
729
715
|
id = E.field(E.identifier);
|
|
730
716
|
title = E.field(E.string);
|
|
731
717
|
slug = E.field(E.string);
|
|
@@ -733,22 +719,22 @@ class Post extends E.Model<Post> {
|
|
|
733
719
|
preCommit() {
|
|
734
720
|
this.slug = this.title.toLowerCase().replace(/\s+/g, "-");
|
|
735
721
|
}
|
|
736
|
-
}
|
|
722
|
+
}, { pk: "id" });
|
|
737
723
|
```
|
|
738
724
|
|
|
739
|
-
#### model.getPrimaryKey · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
725
|
+
#### model.getPrimaryKey · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
740
726
|
|
|
741
727
|
**Signature:** `() => Uint8Array<ArrayBufferLike>`
|
|
742
728
|
|
|
743
729
|
**Returns:** The primary key for this instance.
|
|
744
730
|
|
|
745
|
-
#### model.getPrimaryKeyHash · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
731
|
+
#### model.getPrimaryKeyHash · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
746
732
|
|
|
747
733
|
**Signature:** `() => number`
|
|
748
734
|
|
|
749
735
|
**Returns:** A 53-bit positive integer non-cryptographic hash of the primary key, or undefined if not yet saved.
|
|
750
736
|
|
|
751
|
-
#### model.isLazyField · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
737
|
+
#### model.isLazyField · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
752
738
|
|
|
753
739
|
**Signature:** `(field: keyof this) => boolean`
|
|
754
740
|
|
|
@@ -756,7 +742,7 @@ class Post extends E.Model<Post> {
|
|
|
756
742
|
|
|
757
743
|
- `field: keyof this`
|
|
758
744
|
|
|
759
|
-
#### model.preventPersist · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
745
|
+
#### model.preventPersist · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
760
746
|
|
|
761
747
|
Prevent this instance from being persisted to the database.
|
|
762
748
|
|
|
@@ -767,12 +753,12 @@ Prevent this instance from being persisted to the database.
|
|
|
767
753
|
**Examples:**
|
|
768
754
|
|
|
769
755
|
```typescript
|
|
770
|
-
const user = User.
|
|
756
|
+
const user = User.get("user123");
|
|
771
757
|
user.name = "New Name";
|
|
772
758
|
user.preventPersist(); // Changes won't be saved
|
|
773
759
|
```
|
|
774
760
|
|
|
775
|
-
#### model.delete · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
761
|
+
#### model.delete · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
776
762
|
|
|
777
763
|
Delete this model instance from the database.
|
|
778
764
|
|
|
@@ -783,11 +769,11 @@ Removes the instance and all its index entries from the database and prevents fu
|
|
|
783
769
|
**Examples:**
|
|
784
770
|
|
|
785
771
|
```typescript
|
|
786
|
-
const user = User.
|
|
772
|
+
const user = User.get("user123");
|
|
787
773
|
user.delete(); // Removes from database
|
|
788
774
|
```
|
|
789
775
|
|
|
790
|
-
#### model.validate · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
776
|
+
#### model.validate · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
791
777
|
|
|
792
778
|
Validate all fields in this model instance.
|
|
793
779
|
|
|
@@ -809,7 +795,7 @@ if (errors.length > 0) {
|
|
|
809
795
|
}
|
|
810
796
|
```
|
|
811
797
|
|
|
812
|
-
#### model.isValid · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
798
|
+
#### model.isValid · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
813
799
|
|
|
814
800
|
Check if this model instance is valid.
|
|
815
801
|
|
|
@@ -824,46 +810,42 @@ const user = new User({name: "John"});
|
|
|
824
810
|
if (!user.isValid()) shoutAtTheUser();
|
|
825
811
|
```
|
|
826
812
|
|
|
827
|
-
#### model.getState · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
813
|
+
#### model.getState · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
828
814
|
|
|
829
815
|
**Signature:** `() => "created" | "deleted" | "loaded" | "lazy"`
|
|
830
816
|
|
|
831
|
-
#### model.toString · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
817
|
+
#### model.toString · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
832
818
|
|
|
833
819
|
**Signature:** `() => string`
|
|
834
820
|
|
|
835
|
-
#### model.[Symbol.for('nodejs.util.inspect.custom')] · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
821
|
+
#### model.[Symbol.for('nodejs.util.inspect.custom')] · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
836
822
|
|
|
837
823
|
**Signature:** `() => string`
|
|
838
824
|
|
|
839
|
-
###
|
|
825
|
+
### defineModel · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L164)
|
|
840
826
|
|
|
841
827
|
Register a model class with the Edinburgh ORM system.
|
|
842
828
|
|
|
843
|
-
|
|
829
|
+
Converts a plain class into a fully-featured model with database persistence,
|
|
830
|
+
typed fields, primary key access, and optional secondary and unique indexes.
|
|
831
|
+
|
|
832
|
+
**Signature:** `<T extends new () => any, const PK extends (keyof FieldsOf<T> & string) | readonly (keyof FieldsOf<T> & string)[], const UNIQUE extends Record<string, (keyof FieldsOf<T> & string) | readonly (keyof FieldsOf<T> & string)[] | ((instance: any) => any)>, const INDEX extends Record<string, (keyof FieldsOf<T> & string) | ...`
|
|
844
833
|
|
|
845
834
|
**Type Parameters:**
|
|
846
835
|
|
|
847
|
-
- `T extends
|
|
836
|
+
- `T extends new () => any`
|
|
837
|
+
- `PK extends (keyof FieldsOf<T> & string) | readonly (keyof FieldsOf<T> & string)[]`
|
|
838
|
+
- `UNIQUE extends Record<string, (keyof FieldsOf<T> & string) | readonly (keyof FieldsOf<T> & string)[] | ((instance: any) => any)>`
|
|
839
|
+
- `INDEX extends Record<string, (keyof FieldsOf<T> & string) | readonly (keyof FieldsOf<T> & string)[] | ((instance: any) => any)>`
|
|
848
840
|
|
|
849
841
|
**Parameters:**
|
|
850
842
|
|
|
851
|
-
- `
|
|
852
|
-
|
|
853
|
-
**Returns:** The enhanced model class with ORM capabilities.
|
|
854
|
-
|
|
855
|
-
**Examples:**
|
|
843
|
+
- `cls: T` - - A plain class whose properties use E.field().
|
|
844
|
+
- `opts?: { pk?: PK, unique?: UNIQUE, index?: INDEX, tableName?: string, override?: boolean }` - - Registration options.
|
|
856
845
|
|
|
857
|
-
|
|
858
|
-
@E.registerModel
|
|
859
|
-
class User extends E.Model<User> {
|
|
860
|
-
static pk = E.index(User, ["id"], "primary");
|
|
861
|
-
id = E.field(E.identifier);
|
|
862
|
-
name = E.field(E.string);
|
|
863
|
-
}
|
|
864
|
-
```
|
|
846
|
+
**Returns:** The enhanced model constructor.
|
|
865
847
|
|
|
866
|
-
### field · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
848
|
+
### field · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L87)
|
|
867
849
|
|
|
868
850
|
Create a field definition for a model property.
|
|
869
851
|
|
|
@@ -887,19 +869,26 @@ This allows for both runtime introspection and compile-time type safety.
|
|
|
887
869
|
**Examples:**
|
|
888
870
|
|
|
889
871
|
```typescript
|
|
890
|
-
|
|
872
|
+
const User = E.defineModel(class {
|
|
891
873
|
name = E.field(E.string, {description: "User's full name"});
|
|
892
874
|
age = E.field(E.opt(E.number), {description: "User's age", default: 25});
|
|
893
|
-
}
|
|
875
|
+
});
|
|
894
876
|
```
|
|
895
877
|
|
|
896
|
-
###
|
|
878
|
+
### currentTxn · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L21)
|
|
879
|
+
|
|
880
|
+
Returns the current transaction from AsyncLocalStorage.
|
|
881
|
+
Throws if called outside a transact() callback.
|
|
882
|
+
|
|
883
|
+
**Signature:** `() => Transaction`
|
|
884
|
+
|
|
885
|
+
### string · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
897
886
|
|
|
898
887
|
Type wrapper instance for the string type.
|
|
899
888
|
|
|
900
889
|
**Value:** `TypeWrapper<string>`
|
|
901
890
|
|
|
902
|
-
### orderedString · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
891
|
+
### orderedString · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
903
892
|
|
|
904
893
|
Type wrapper instance for the ordered string type, which is just like a string
|
|
905
894
|
except that it sorts lexicographically in the database (instead of by incrementing
|
|
@@ -909,37 +898,37 @@ may not contain null characters.
|
|
|
909
898
|
|
|
910
899
|
**Value:** `TypeWrapper<string>`
|
|
911
900
|
|
|
912
|
-
### number · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
901
|
+
### number · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
913
902
|
|
|
914
903
|
Type wrapper instance for the number type.
|
|
915
904
|
|
|
916
905
|
**Value:** `TypeWrapper<number>`
|
|
917
906
|
|
|
918
|
-
### dateTime · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
907
|
+
### dateTime · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
919
908
|
|
|
920
909
|
Type wrapper instance for the date/time type. Stored without timezone info, rounded to whole seconds.
|
|
921
910
|
|
|
922
911
|
**Value:** `TypeWrapper<Date>`
|
|
923
912
|
|
|
924
|
-
### boolean · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
913
|
+
### boolean · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
925
914
|
|
|
926
915
|
Type wrapper instance for the boolean type.
|
|
927
916
|
|
|
928
917
|
**Value:** `TypeWrapper<boolean>`
|
|
929
918
|
|
|
930
|
-
### identifier · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
919
|
+
### identifier · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
931
920
|
|
|
932
921
|
Type wrapper instance for the identifier type.
|
|
933
922
|
|
|
934
923
|
**Value:** `TypeWrapper<string>`
|
|
935
924
|
|
|
936
|
-
### undef · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
925
|
+
### undef · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
937
926
|
|
|
938
927
|
Type wrapper instance for the 'undefined' type.
|
|
939
928
|
|
|
940
929
|
**Value:** `TypeWrapper<undefined>`
|
|
941
930
|
|
|
942
|
-
### opt · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
931
|
+
### opt · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
943
932
|
|
|
944
933
|
Create an optional type wrapper (allows undefined).
|
|
945
934
|
|
|
@@ -962,7 +951,7 @@ const optionalString = E.opt(E.string);
|
|
|
962
951
|
const optionalNumber = E.opt(E.number);
|
|
963
952
|
```
|
|
964
953
|
|
|
965
|
-
### or · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
954
|
+
### or · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
966
955
|
|
|
967
956
|
Create a union type wrapper from multiple type choices.
|
|
968
957
|
|
|
@@ -985,7 +974,7 @@ const stringOrNumber = E.or(E.string, E.number);
|
|
|
985
974
|
const status = E.or("active", "inactive", "pending");
|
|
986
975
|
```
|
|
987
976
|
|
|
988
|
-
### array · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
977
|
+
### array · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
989
978
|
|
|
990
979
|
Create an array type wrapper with optional length constraints.
|
|
991
980
|
|
|
@@ -1009,7 +998,7 @@ const stringArray = E.array(E.string);
|
|
|
1009
998
|
const boundedArray = E.array(E.number, {min: 1, max: 10});
|
|
1010
999
|
```
|
|
1011
1000
|
|
|
1012
|
-
### set · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1001
|
+
### set · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
1013
1002
|
|
|
1014
1003
|
Create a Set type wrapper with optional length constraints.
|
|
1015
1004
|
|
|
@@ -1033,7 +1022,7 @@ const stringSet = E.set(E.string);
|
|
|
1033
1022
|
const boundedSet = E.set(E.number, {min: 1, max: 10});
|
|
1034
1023
|
```
|
|
1035
1024
|
|
|
1036
|
-
### record · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1025
|
+
### record · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
1037
1026
|
|
|
1038
1027
|
Create a Record type wrapper for key-value objects with string or number keys.
|
|
1039
1028
|
|
|
@@ -1055,7 +1044,7 @@ Create a Record type wrapper for key-value objects with string or number keys.
|
|
|
1055
1044
|
const scores = E.record(E.number); // Record<string | number, number>
|
|
1056
1045
|
```
|
|
1057
1046
|
|
|
1058
|
-
### literal · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1047
|
+
### literal · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
1059
1048
|
|
|
1060
1049
|
Create a literal type wrapper for a constant value.
|
|
1061
1050
|
|
|
@@ -1078,15 +1067,15 @@ const statusType = E.literal("active");
|
|
|
1078
1067
|
const countType = E.literal(42);
|
|
1079
1068
|
```
|
|
1080
1069
|
|
|
1081
|
-
### link · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1070
|
+
### link · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
1082
1071
|
|
|
1083
1072
|
Create a link type wrapper for model relationships.
|
|
1084
1073
|
|
|
1085
|
-
**Signature:**
|
|
1074
|
+
**Signature:** `{ <const T extends new (...args: any[]) => Model<any>>(TargetModel: T): TypeWrapper<InstanceType<T>>; <const T extends new (...args: any[]) => Model<any>>(TargetModel: () => T): TypeWrapper<...>; }`
|
|
1086
1075
|
|
|
1087
1076
|
**Type Parameters:**
|
|
1088
1077
|
|
|
1089
|
-
- `T extends
|
|
1078
|
+
- `T extends new (...args: any[]) => Model<any>` - The target model class.
|
|
1090
1079
|
|
|
1091
1080
|
**Parameters:**
|
|
1092
1081
|
|
|
@@ -1097,109 +1086,18 @@ Create a link type wrapper for model relationships.
|
|
|
1097
1086
|
**Examples:**
|
|
1098
1087
|
|
|
1099
1088
|
```typescript
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
class Post extends E.Model<Post> {
|
|
1105
|
-
author = E.field(E.link(User));
|
|
1106
|
-
}
|
|
1107
|
-
```
|
|
1108
|
-
|
|
1109
|
-
### index · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
1110
|
-
|
|
1111
|
-
Create a secondary index on model fields, or a computed secondary index using a function.
|
|
1112
|
-
|
|
1113
|
-
For field-based indexes, pass a field name or array of field names.
|
|
1114
|
-
For computed indexes, pass a function that takes a model instance and returns an array of
|
|
1115
|
-
index keys. Return `[]` to skip indexing for that instance. Each array element creates a
|
|
1116
|
-
separate index entry, enabling multi-value indexes (e.g., indexing by each word in a name).
|
|
1117
|
-
|
|
1118
|
-
**Signature:** `{ <M extends typeof Model, V>(MyModel: M, fn: (instance: InstanceType<M>) => V[]): SecondaryIndex<M, [], [V]>; <M extends typeof Model, const F extends (keyof InstanceType<M> & string)>(MyModel: M, field: F): SecondaryIndex<...>; <M extends typeof Model, const FS extends readonly (keyof InstanceType<M> & string)[]>(...`
|
|
1119
|
-
|
|
1120
|
-
**Type Parameters:**
|
|
1121
|
-
|
|
1122
|
-
- `M extends typeof Model` - The model class.
|
|
1123
|
-
- `V` - The computed index value type (for function-based indexes).
|
|
1124
|
-
|
|
1125
|
-
**Parameters:**
|
|
1126
|
-
|
|
1127
|
-
- `MyModel: M` - - The model class to create the index for.
|
|
1128
|
-
- `fn: (instance: InstanceType<M>) => V[]`
|
|
1129
|
-
|
|
1130
|
-
**Returns:** A new SecondaryIndex instance.
|
|
1131
|
-
|
|
1132
|
-
**Examples:**
|
|
1133
|
-
|
|
1134
|
-
```typescript
|
|
1135
|
-
class User extends E.Model<User> {
|
|
1136
|
-
static byAge = E.index(User, "age");
|
|
1137
|
-
static byTagsDate = E.index(User, ["tags", "createdAt"]);
|
|
1138
|
-
static byWord = E.index(User, (u: User) => u.name.split(" "));
|
|
1139
|
-
}
|
|
1140
|
-
```
|
|
1141
|
-
|
|
1142
|
-
### primary · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
1143
|
-
|
|
1144
|
-
Create a primary index on model fields.
|
|
1145
|
-
|
|
1146
|
-
**Signature:** `{ <M extends typeof Model, const F extends (keyof InstanceType<M> & string)>(MyModel: M, field: F): PrimaryIndex<M, [F]>; <M extends typeof Model, const FS extends readonly (keyof InstanceType<M> & string)[]>(MyModel: M, fields: FS): PrimaryIndex<...>; }`
|
|
1147
|
-
|
|
1148
|
-
**Type Parameters:**
|
|
1149
|
-
|
|
1150
|
-
- `M extends typeof Model` - The model class.
|
|
1151
|
-
- `F extends (keyof InstanceType<M> & string)` - The field name (for single field index).
|
|
1152
|
-
|
|
1153
|
-
**Parameters:**
|
|
1154
|
-
|
|
1155
|
-
- `MyModel: M` - - The model class to create the index for.
|
|
1156
|
-
- `field: F` - - Single field name for simple indexes.
|
|
1157
|
-
|
|
1158
|
-
**Returns:** A new PrimaryIndex instance.
|
|
1159
|
-
|
|
1160
|
-
**Examples:**
|
|
1161
|
-
|
|
1162
|
-
```typescript
|
|
1163
|
-
class User extends E.Model<User> {
|
|
1164
|
-
static pk = E.primary(User, ["id"]);
|
|
1165
|
-
static pkSingle = E.primary(User, "id");
|
|
1166
|
-
}
|
|
1167
|
-
```
|
|
1168
|
-
|
|
1169
|
-
### unique · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
1170
|
-
|
|
1171
|
-
Create a unique index on model fields, or a computed unique index using a function.
|
|
1172
|
-
|
|
1173
|
-
For field-based indexes, pass a field name or array of field names.
|
|
1174
|
-
For computed indexes, pass a function that takes a model instance and returns an array of
|
|
1175
|
-
index keys. Return `[]` to skip indexing for that instance. Each array element creates a
|
|
1176
|
-
separate index entry, enabling multi-value indexes (e.g., indexing by each word in a name).
|
|
1177
|
-
|
|
1178
|
-
**Signature:** `{ <M extends typeof Model, V>(MyModel: M, fn: (instance: InstanceType<M>) => V[]): UniqueIndex<M, [], [V]>; <M extends typeof Model, const F extends (keyof InstanceType<M> & string)>(MyModel: M, field: F): UniqueIndex<...>; <M extends typeof Model, const FS extends readonly (keyof InstanceType<M> & string)[]>(MyMode...`
|
|
1179
|
-
|
|
1180
|
-
**Type Parameters:**
|
|
1181
|
-
|
|
1182
|
-
- `M extends typeof Model` - The model class.
|
|
1183
|
-
- `V` - The computed index value type (for function-based indexes).
|
|
1184
|
-
|
|
1185
|
-
**Parameters:**
|
|
1186
|
-
|
|
1187
|
-
- `MyModel: M` - - The model class to create the index for.
|
|
1188
|
-
- `fn: (instance: InstanceType<M>) => V[]`
|
|
1189
|
-
|
|
1190
|
-
**Returns:** A new UniqueIndex instance.
|
|
1191
|
-
|
|
1192
|
-
**Examples:**
|
|
1089
|
+
const Author = E.defineModel(class {
|
|
1090
|
+
id = E.field(E.identifier);
|
|
1091
|
+
posts = E.field(E.array(E.link(() => Book)));
|
|
1092
|
+
}, { pk: "id" });
|
|
1193
1093
|
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
static byFullName = E.unique(User, (u: User) => [`${u.firstName} ${u.lastName}`]);
|
|
1199
|
-
}
|
|
1094
|
+
const Book = E.defineModel(class {
|
|
1095
|
+
id = E.field(E.identifier);
|
|
1096
|
+
author = E.field(E.link(Author));
|
|
1097
|
+
}, { pk: "id" });
|
|
1200
1098
|
```
|
|
1201
1099
|
|
|
1202
|
-
### dump · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1100
|
+
### dump · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
1203
1101
|
|
|
1204
1102
|
Dump database contents for debugging.
|
|
1205
1103
|
|
|
@@ -1208,7 +1106,7 @@ This is primarily useful for development and debugging purposes.
|
|
|
1208
1106
|
|
|
1209
1107
|
**Signature:** `() => void`
|
|
1210
1108
|
|
|
1211
|
-
### BaseIndex · [abstract class](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1109
|
+
### BaseIndex · [abstract class](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L130)
|
|
1212
1110
|
|
|
1213
1111
|
Base class for database indexes for efficient lookups on model fields.
|
|
1214
1112
|
|
|
@@ -1225,113 +1123,97 @@ Indexes enable fast queries on specific field combinations and enforce uniquenes
|
|
|
1225
1123
|
- `MyModel`: - The model class this index belongs to.
|
|
1226
1124
|
- `_fieldNames`: - Array of field names that make up this index.
|
|
1227
1125
|
|
|
1228
|
-
#### baseIndex.find · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1126
|
+
#### baseIndex.find · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
1229
1127
|
|
|
1230
|
-
**Signature:** `(opts?: FindOptions<ARGS>)
|
|
1128
|
+
**Signature:** `{ (opts?: FindOptions<ARGS, "first">): InstanceType<M>; (opts: FindOptions<ARGS, "single">): InstanceType<M>; (opts?: FindOptions<...>): IndexRangeIterator<...>; }`
|
|
1231
1129
|
|
|
1232
1130
|
**Parameters:**
|
|
1233
1131
|
|
|
1234
|
-
- `opts
|
|
1132
|
+
- `opts?: FindOptions<ARGS, 'first'>`
|
|
1235
1133
|
|
|
1236
|
-
#### baseIndex.
|
|
1237
|
-
|
|
1238
|
-
[object Object],[object Object],[object Object]
|
|
1134
|
+
#### baseIndex.find · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
1239
1135
|
|
|
1240
|
-
**Signature:** `(opts
|
|
1136
|
+
**Signature:** `{ (opts?: FindOptions<ARGS, "first">): InstanceType<M>; (opts: FindOptions<ARGS, "single">): InstanceType<M>; (opts?: FindOptions<...>): IndexRangeIterator<...>; }`
|
|
1241
1137
|
|
|
1242
1138
|
**Parameters:**
|
|
1243
1139
|
|
|
1244
|
-
- `opts: FindOptions<ARGS
|
|
1245
|
-
- `callback: (row: InstanceType<M>) => void | Promise<void>` - - Called for each matching row within a transaction
|
|
1246
|
-
|
|
1247
|
-
#### baseIndex.toString · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
1248
|
-
|
|
1249
|
-
**Signature:** `() => string`
|
|
1140
|
+
- `opts: FindOptions<ARGS, 'single'>`
|
|
1250
1141
|
|
|
1251
|
-
|
|
1142
|
+
#### baseIndex.find · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
1252
1143
|
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
**Type Parameters:**
|
|
1144
|
+
**Signature:** `{ (opts?: FindOptions<ARGS, "first">): InstanceType<M>; (opts: FindOptions<ARGS, "single">): InstanceType<M>; (opts?: FindOptions<...>): IndexRangeIterator<...>; }`
|
|
1256
1145
|
|
|
1257
|
-
|
|
1258
|
-
- `F extends readonly (keyof InstanceType<M> & string)[]` - The field names that make up this index.
|
|
1259
|
-
- `ARGS extends readonly any[] = IndexArgTypes<M, F>`
|
|
1146
|
+
**Parameters:**
|
|
1260
1147
|
|
|
1261
|
-
|
|
1148
|
+
- `opts?: FindOptions<ARGS>`
|
|
1262
1149
|
|
|
1263
|
-
|
|
1150
|
+
#### baseIndex.find · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
1264
1151
|
|
|
1265
|
-
**Signature:** `(
|
|
1152
|
+
**Signature:** `{ (opts?: FindOptions<ARGS, "first">): InstanceType<M>; (opts: FindOptions<ARGS, "single">): InstanceType<M>; (opts?: FindOptions<...>): IndexRangeIterator<...>; }`
|
|
1266
1153
|
|
|
1267
1154
|
**Parameters:**
|
|
1268
1155
|
|
|
1269
|
-
- `
|
|
1156
|
+
- `opts: any` (optional)
|
|
1270
1157
|
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
**Examples:**
|
|
1158
|
+
#### baseIndex.batchProcess · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
1274
1159
|
|
|
1275
|
-
|
|
1276
|
-
const userByEmail = User.byEmail.get("john@example.com");
|
|
1277
|
-
```
|
|
1160
|
+
[object Object],[object Object],[object Object]
|
|
1278
1161
|
|
|
1279
|
-
|
|
1162
|
+
**Signature:** `(opts: FindOptions<ARGS, undefined> & { limitSeconds?: number; limitRows?: number; }, callback: (row: InstanceType<M>) => void | Promise<void>) => Promise<...>`
|
|
1280
1163
|
|
|
1281
|
-
|
|
1164
|
+
**Parameters:**
|
|
1282
1165
|
|
|
1283
|
-
|
|
1166
|
+
- `opts: FindOptions<ARGS> & { limitSeconds?: number; limitRows?: number }` (optional) - - Query options (same as `find()`), plus:
|
|
1167
|
+
- `callback: (row: InstanceType<M>) => void | Promise<void>` - - Called for each matching row within a transaction
|
|
1284
1168
|
|
|
1285
|
-
|
|
1286
|
-
- `F extends readonly (keyof InstanceType<M> & string)[]` - The field names that make up this index.
|
|
1169
|
+
#### baseIndex.toString · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
1287
1170
|
|
|
1288
|
-
|
|
1171
|
+
**Signature:** `() => string`
|
|
1289
1172
|
|
|
1290
|
-
|
|
1173
|
+
### NonPrimaryIndex · [abstract class](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
1291
1174
|
|
|
1292
|
-
|
|
1175
|
+
Abstract base for all non-primary indexes (unique and secondary).
|
|
1176
|
+
Provides shared key serialization, write/delete/update logic.
|
|
1293
1177
|
|
|
1294
|
-
**Parameters:**
|
|
1178
|
+
**Type Parameters:**
|
|
1295
1179
|
|
|
1296
|
-
- `
|
|
1180
|
+
- `M extends typeof Model`
|
|
1181
|
+
- `F extends readonly (keyof InstanceType<M> & string)[]`
|
|
1182
|
+
- `ARGS extends readonly any[] = IndexArgTypes<M, F>`
|
|
1297
1183
|
|
|
1298
|
-
|
|
1184
|
+
### UniqueIndex · [class](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
1299
1185
|
|
|
1300
|
-
|
|
1186
|
+
Unique index that stores references to the primary key.
|
|
1301
1187
|
|
|
1302
|
-
|
|
1303
|
-
const user = User.pk.get("john_doe");
|
|
1304
|
-
```
|
|
1188
|
+
**Type Parameters:**
|
|
1305
1189
|
|
|
1306
|
-
|
|
1190
|
+
- `M extends typeof Model`
|
|
1191
|
+
- `F extends readonly (keyof InstanceType<M> & string)[]`
|
|
1192
|
+
- `ARGS extends readonly any[] = IndexArgTypes<M, F>`
|
|
1307
1193
|
|
|
1308
|
-
|
|
1309
|
-
property access. In case it turns out the instance doesn't exist, an error will be thrown
|
|
1310
|
-
at that time.
|
|
1194
|
+
#### uniqueIndex.get · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
1311
1195
|
|
|
1312
|
-
**Signature:** `(...args:
|
|
1196
|
+
**Signature:** `(...args: ARGS) => InstanceType<M>`
|
|
1313
1197
|
|
|
1314
1198
|
**Parameters:**
|
|
1315
1199
|
|
|
1316
|
-
- `args:
|
|
1317
|
-
|
|
1318
|
-
**Returns:** The (lazily loaded) model instance.
|
|
1200
|
+
- `args: ARGS`
|
|
1319
1201
|
|
|
1320
|
-
### SecondaryIndex · [class](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1202
|
+
### SecondaryIndex · [class](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L252)
|
|
1321
1203
|
|
|
1322
1204
|
Secondary index for non-unique lookups.
|
|
1323
1205
|
|
|
1324
1206
|
**Type Parameters:**
|
|
1325
1207
|
|
|
1326
|
-
- `M extends typeof Model`
|
|
1327
|
-
- `F extends readonly (keyof InstanceType<M> & string)[]`
|
|
1208
|
+
- `M extends typeof Model`
|
|
1209
|
+
- `F extends readonly (keyof InstanceType<M> & string)[]`
|
|
1328
1210
|
- `ARGS extends readonly any[] = IndexArgTypes<M, F>`
|
|
1329
1211
|
|
|
1330
|
-
### Change · [type](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1212
|
+
### Change · [type](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L94)
|
|
1331
1213
|
|
|
1332
1214
|
**Type:** `Record<any, any> | "created" | "deleted"`
|
|
1333
1215
|
|
|
1334
|
-
### Transaction · [interface](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1216
|
+
### Transaction · [interface](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L39)
|
|
1335
1217
|
|
|
1336
1218
|
#### transaction.id · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L41)
|
|
1337
1219
|
|
|
@@ -1341,11 +1223,11 @@ Secondary index for non-unique lookups.
|
|
|
1341
1223
|
|
|
1342
1224
|
**Type:** `Set<Model<unknown>>`
|
|
1343
1225
|
|
|
1344
|
-
#### transaction.instancesByPk · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1226
|
+
#### transaction.instancesByPk · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L44)
|
|
1345
1227
|
|
|
1346
1228
|
**Type:** `Map<number, Model<unknown>>`
|
|
1347
1229
|
|
|
1348
|
-
### DatabaseError · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1230
|
+
### DatabaseError · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L156)
|
|
1349
1231
|
|
|
1350
1232
|
The DatabaseError class is used to represent errors that occur during database operations.
|
|
1351
1233
|
It extends the built-in Error class and has a machine readable error code string property.
|
|
@@ -1355,7 +1237,7 @@ Invalid function arguments will throw TypeError.
|
|
|
1355
1237
|
|
|
1356
1238
|
**Value:** `DatabaseErrorConstructor`
|
|
1357
1239
|
|
|
1358
|
-
### runMigration · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1240
|
+
### runMigration · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L122)
|
|
1359
1241
|
|
|
1360
1242
|
Run database migration: populate secondary indexes for old-version rows,
|
|
1361
1243
|
convert old primary indices, rewrite row data, and clean up orphaned indices.
|
|
@@ -1366,71 +1248,71 @@ convert old primary indices, rewrite row data, and clean up orphaned indices.
|
|
|
1366
1248
|
|
|
1367
1249
|
- `options: MigrationOptions` (optional)
|
|
1368
1250
|
|
|
1369
|
-
### MigrationOptions · [interface](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1251
|
+
### MigrationOptions · [interface](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L13)
|
|
1370
1252
|
|
|
1371
|
-
#### migrationOptions.tables · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1253
|
+
#### migrationOptions.tables · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L17)
|
|
1372
1254
|
|
|
1373
1255
|
Limit migration to specific table names.
|
|
1374
1256
|
|
|
1375
1257
|
**Type:** `string[]`
|
|
1376
1258
|
|
|
1377
|
-
#### migrationOptions.populateSecondaries · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1259
|
+
#### migrationOptions.populateSecondaries · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L21)
|
|
1378
1260
|
|
|
1379
1261
|
Populate secondary indexes for rows at old schema versions (default: true).
|
|
1380
1262
|
|
|
1381
1263
|
**Type:** `boolean`
|
|
1382
1264
|
|
|
1383
|
-
#### migrationOptions.migratePrimaries · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1265
|
+
#### migrationOptions.migratePrimaries · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L29)
|
|
1384
1266
|
|
|
1385
1267
|
Convert old primary indices when primary key fields changed (default: true).
|
|
1386
1268
|
|
|
1387
1269
|
**Type:** `boolean`
|
|
1388
1270
|
|
|
1389
|
-
#### migrationOptions.rewriteData · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1271
|
+
#### migrationOptions.rewriteData · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L37)
|
|
1390
1272
|
|
|
1391
1273
|
Rewrite all row data to the latest schema version (default: false).
|
|
1392
1274
|
|
|
1393
1275
|
**Type:** `boolean`
|
|
1394
1276
|
|
|
1395
|
-
#### migrationOptions.removeOrphans · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1277
|
+
#### migrationOptions.removeOrphans · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L44)
|
|
1396
1278
|
|
|
1397
1279
|
Delete orphaned secondary/unique index entries (default: true).
|
|
1398
1280
|
|
|
1399
1281
|
**Type:** `boolean`
|
|
1400
1282
|
|
|
1401
|
-
#### migrationOptions.onProgress · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1283
|
+
#### migrationOptions.onProgress · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L44)
|
|
1402
1284
|
|
|
1403
1285
|
Progress callback.
|
|
1404
1286
|
|
|
1405
1287
|
**Type:** `(info: ProgressInfo) => void`
|
|
1406
1288
|
|
|
1407
|
-
### MigrationResult · [interface](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1289
|
+
### MigrationResult · [interface](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L49)
|
|
1408
1290
|
|
|
1409
|
-
#### migrationResult.secondaries · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1291
|
+
#### migrationResult.secondaries · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L50)
|
|
1410
1292
|
|
|
1411
1293
|
Per-table counts of secondary index entries populated.
|
|
1412
1294
|
|
|
1413
1295
|
**Type:** `Record<string, number>`
|
|
1414
1296
|
|
|
1415
|
-
#### migrationResult.primaries · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1297
|
+
#### migrationResult.primaries · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L56)
|
|
1416
1298
|
|
|
1417
1299
|
Per-table counts of old primary rows migrated.
|
|
1418
1300
|
|
|
1419
1301
|
**Type:** `Record<string, number>`
|
|
1420
1302
|
|
|
1421
|
-
#### migrationResult.conversionFailures · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1303
|
+
#### migrationResult.conversionFailures · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L57)
|
|
1422
1304
|
|
|
1423
1305
|
Per-table conversion failure counts by reason.
|
|
1424
1306
|
|
|
1425
1307
|
**Type:** `Record<string, Record<string, number>>`
|
|
1426
1308
|
|
|
1427
|
-
#### migrationResult.rewritten · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1309
|
+
#### migrationResult.rewritten · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L60)
|
|
1428
1310
|
|
|
1429
1311
|
Per-table counts of rows rewritten to latest version.
|
|
1430
1312
|
|
|
1431
1313
|
**Type:** `Record<string, number>`
|
|
1432
1314
|
|
|
1433
|
-
#### migrationResult.orphans · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1315
|
+
#### migrationResult.orphans · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L65)
|
|
1434
1316
|
|
|
1435
1317
|
Number of orphaned index entries deleted.
|
|
1436
1318
|
|