edinburgh 0.4.4 → 0.4.6
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 +119 -150
- package/build/src/edinburgh.js +4 -2
- package/build/src/edinburgh.js.map +1 -1
- package/build/src/indexes.d.ts +2 -3
- package/build/src/indexes.js +3 -5
- package/build/src/indexes.js.map +1 -1
- package/build/src/migrate-cli.d.ts +1 -16
- package/build/src/migrate-cli.js +56 -42
- package/build/src/migrate-cli.js.map +1 -1
- package/build/src/migrate.d.ts +15 -11
- package/build/src/migrate.js +53 -39
- package/build/src/migrate.js.map +1 -1
- package/build/src/models.d.ts +8 -2
- package/build/src/models.js +59 -51
- package/build/src/models.js.map +1 -1
- package/build/src/types.d.ts +2 -1
- package/package.json +6 -4
- package/skill/BaseIndex.md +16 -0
- package/skill/BaseIndex_batchProcess.md +10 -0
- package/skill/BaseIndex_find.md +7 -0
- package/skill/DatabaseError.md +9 -0
- package/skill/Model.md +22 -0
- package/skill/Model_delete.md +14 -0
- package/skill/Model_findAll.md +12 -0
- package/skill/Model_getPrimaryKeyHash.md +5 -0
- package/skill/Model_isValid.md +14 -0
- package/skill/Model_migrate.md +34 -0
- package/skill/Model_preCommit.md +28 -0
- package/skill/Model_preventPersist.md +15 -0
- package/skill/Model_replaceInto.md +16 -0
- package/skill/Model_validate.md +21 -0
- package/skill/PrimaryIndex.md +8 -0
- package/skill/PrimaryIndex_get.md +17 -0
- package/skill/PrimaryIndex_getLazy.md +13 -0
- package/skill/SKILL.md +96 -714
- package/skill/SecondaryIndex.md +9 -0
- package/skill/UniqueIndex.md +9 -0
- package/skill/UniqueIndex_get.md +17 -0
- package/skill/array.md +23 -0
- package/skill/dump.md +8 -0
- package/skill/field.md +29 -0
- package/skill/index.md +32 -0
- package/skill/init.md +17 -0
- package/skill/link.md +27 -0
- package/skill/literal.md +22 -0
- package/skill/opt.md +22 -0
- package/skill/or.md +22 -0
- package/skill/primary.md +26 -0
- package/skill/record.md +21 -0
- package/skill/registerModel.md +26 -0
- package/skill/runMigration.md +10 -0
- package/skill/set.md +23 -0
- package/skill/setMaxRetryCount.md +10 -0
- package/skill/setOnSaveCallback.md +12 -0
- package/skill/transact.md +49 -0
- package/skill/unique.md +32 -0
- package/src/edinburgh.ts +4 -2
- package/src/indexes.ts +3 -6
- package/src/migrate-cli.ts +44 -46
- package/src/migrate.ts +64 -46
- package/src/models.ts +59 -51
package/README.md
CHANGED
|
@@ -388,13 +388,9 @@ await Product.byCategory.batchProcess({is: "old"}, (product) => {
|
|
|
388
388
|
// Commits every ~1 second or 4096 rows (configurable via limitSeconds, limitRows)
|
|
389
389
|
```
|
|
390
390
|
|
|
391
|
-
### Schema
|
|
391
|
+
### Lazy Schema Migrations
|
|
392
392
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
- **Adding/removing fields**: Old rows are lazily migrated on read. New fields use their default value.
|
|
396
|
-
- **Changing field types**: Requires a `static migrate()` function.
|
|
397
|
-
- **Adding/removing indexes**: Requires running `npx migrate-edinburgh`.
|
|
393
|
+
When you change a model's schema, Edinburgh will lazily try to migrate old records on access. This allows you to deploy code changes without downtime or a separate migration step. Optionally, you may provide a `static migrate(record: Record<string, any>)` function on the model to transform old records during lazy migration. If there is a migration error (like a new field without a default value, or an incompatible type change), a run-time error is thrown when loading the affected model instance.
|
|
398
394
|
|
|
399
395
|
```typescript
|
|
400
396
|
@E.registerModel
|
|
@@ -402,15 +398,40 @@ class User extends E.Model<User> {
|
|
|
402
398
|
static pk = E.primary(User, "id");
|
|
403
399
|
id = E.field(E.identifier);
|
|
404
400
|
name = E.field(E.string);
|
|
405
|
-
role = E.field(E.string
|
|
401
|
+
role = E.field(E.string); // newly added field
|
|
406
402
|
|
|
407
403
|
static migrate(record: Record<string, any>) {
|
|
408
|
-
record.role ??= "user";
|
|
404
|
+
record.role ??= record.name.indexOf("admin") >= 0 ? "admin" : "user"; // set role based on name for old records
|
|
409
405
|
}
|
|
410
406
|
}
|
|
411
407
|
```
|
|
412
408
|
|
|
413
|
-
|
|
409
|
+
Edinburgh will lazily (re)run the `migrate` function on an instance whenever its implementation (the literal function code) has changed. For robustness, make sure that your `migrate` function...
|
|
410
|
+
- Is idempotent (meaning it can be safely run multiple times on the same row without changing the result after the first run), and
|
|
411
|
+
- Should perform *all* transformation steps starting from the oldest version that could possibly still be in the database. (See the next section.)
|
|
412
|
+
|
|
413
|
+
While lazy migration is convenient and often sufficient, in some cases you need migrations to happen immediately...
|
|
414
|
+
|
|
415
|
+
### Forced Schema Migrations
|
|
416
|
+
|
|
417
|
+
The `migrate-edinburgh` CLI tool will scan the entire database, pro-actively performing the following migrations:
|
|
418
|
+
- **Populate secondary indexes**: If you added or changed secondary indexes, it will build them. Until you do, the indexes will be empty (or only contain instances that have been saved since the index was created).
|
|
419
|
+
- **Migrate primary indexes**: In case you changed the primary key fields or field types (not recommended!) of a model, it will build the new primary index, as well as all secondary indexes (to point at the new primary keys). Until you do, all of your old data will appear to be missing! Note that this may fail on duplicates.
|
|
420
|
+
- **Remove orphaned indexes**: If you removed or changed an index, the stale data will be deleted from the database.
|
|
421
|
+
- **Rewrite primary data**: These are the types of migrations that would normally be done lazily on instance access. As there's usually not much benefit to doing this forcibly, and it can be very time-consuming (and generates a lot of I/O), this is *not* done by default. It may however be useful if you want to clean up the contents of your `migrate()` function, if you have control over all application deployments. Use the `--rewrite-data` flag to enable this.
|
|
422
|
+
|
|
423
|
+
```bash
|
|
424
|
+
npx migrate-edinburgh ./src/models.ts
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
Run `npx migrate-edinburgh` without arguments to see all options. You can also call `runMigration()` programmatically:
|
|
428
|
+
|
|
429
|
+
```typescript
|
|
430
|
+
import { runMigration } from "edinburgh";
|
|
431
|
+
|
|
432
|
+
const result = await runMigration({ tables: ["User"] });
|
|
433
|
+
console.log(result.secondaries); // { User: 1500 }
|
|
434
|
+
```
|
|
414
435
|
|
|
415
436
|
### preCommit Hook
|
|
416
437
|
|
|
@@ -540,7 +561,7 @@ await E.transact(() => {
|
|
|
540
561
|
});
|
|
541
562
|
```
|
|
542
563
|
|
|
543
|
-
### setMaxRetryCount · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
564
|
+
### setMaxRetryCount · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L209)
|
|
544
565
|
|
|
545
566
|
Set the maximum number of retries for a transaction in case of conflicts.
|
|
546
567
|
The default value is 6. Setting it to 0 will disable retries and cause transactions to fail immediately on conflict.
|
|
@@ -551,7 +572,7 @@ The default value is 6. Setting it to 0 will disable retries and cause transacti
|
|
|
551
572
|
|
|
552
573
|
- `count: number` - The maximum number of retries for a transaction.
|
|
553
574
|
|
|
554
|
-
### setOnSaveCallback · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
575
|
+
### setOnSaveCallback · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L223)
|
|
555
576
|
|
|
556
577
|
Set a callback function to be called after a model is saved and committed.
|
|
557
578
|
|
|
@@ -564,11 +585,11 @@ Set a callback function to be called after a model is saved and committed.
|
|
|
564
585
|
- A sequential number. Higher numbers have been committed after lower numbers.
|
|
565
586
|
- A map of model instances to their changes. The change can be "created", "deleted", or an object containing the old values.
|
|
566
587
|
|
|
567
|
-
### deleteEverything · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
588
|
+
### deleteEverything · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L228)
|
|
568
589
|
|
|
569
590
|
**Signature:** `() => Promise<void>`
|
|
570
591
|
|
|
571
|
-
### Model · [abstract class](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
592
|
+
### Model · [abstract class](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L221)
|
|
572
593
|
|
|
573
594
|
[object Object],[object Object],[object Object],[object Object],[object Object]
|
|
574
595
|
|
|
@@ -591,7 +612,7 @@ class User extends E.Model<User> {
|
|
|
591
612
|
}
|
|
592
613
|
```
|
|
593
614
|
|
|
594
|
-
#### Model.tableName · [static property](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
615
|
+
#### Model.tableName · [static property](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L225)
|
|
595
616
|
|
|
596
617
|
The database table name (defaults to class name).
|
|
597
618
|
|
|
@@ -603,13 +624,13 @@ When true, registerModel replaces an existing model with the same tableName.
|
|
|
603
624
|
|
|
604
625
|
**Type:** `boolean`
|
|
605
626
|
|
|
606
|
-
#### Model.fields · [static property](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
627
|
+
#### Model.fields · [static property](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L233)
|
|
607
628
|
|
|
608
629
|
Field configuration metadata.
|
|
609
630
|
|
|
610
631
|
**Type:** `Record<string | number | symbol, FieldConfig<unknown>>`
|
|
611
632
|
|
|
612
|
-
#### Model.migrate · [static method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
633
|
+
#### Model.migrate · [static method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
613
634
|
|
|
614
635
|
Optional migration function called when deserializing rows written with an older schema version.
|
|
615
636
|
Receives a plain record with all fields (primary key fields + value fields) and should mutate it
|
|
@@ -644,7 +665,19 @@ class User extends E.Model<User> {
|
|
|
644
665
|
}
|
|
645
666
|
```
|
|
646
667
|
|
|
647
|
-
#### Model.
|
|
668
|
+
#### Model.initFields · [static method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
669
|
+
|
|
670
|
+
Transform the model's `E.field` properties into the appropriate JavaScript properties. Normally this is done
|
|
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`
|
|
675
|
+
|
|
676
|
+
**Parameters:**
|
|
677
|
+
|
|
678
|
+
- `reset?: boolean`
|
|
679
|
+
|
|
680
|
+
#### Model.findAll · [static method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
648
681
|
|
|
649
682
|
Find all instances of this model in the database, ordered by primary key.
|
|
650
683
|
|
|
@@ -657,7 +690,7 @@ Find all instances of this model in the database, ordered by primary key.
|
|
|
657
690
|
|
|
658
691
|
**Returns:** An iterator.
|
|
659
692
|
|
|
660
|
-
#### Model.replaceInto · [static method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
693
|
+
#### Model.replaceInto · [static method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
661
694
|
|
|
662
695
|
Load an existing instance by primary key and update it, or create a new one.
|
|
663
696
|
|
|
@@ -674,7 +707,7 @@ new instance is created with `obj` as its initial properties.
|
|
|
674
707
|
|
|
675
708
|
**Returns:** The loaded-and-updated or newly created instance.
|
|
676
709
|
|
|
677
|
-
#### model.preCommit · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
710
|
+
#### model.preCommit · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
678
711
|
|
|
679
712
|
Optional hook called on each modified instance right before the transaction commits.
|
|
680
713
|
Runs before data is written to disk, so changes made here are included in the commit.
|
|
@@ -687,9 +720,6 @@ Common use cases:
|
|
|
687
720
|
|
|
688
721
|
**Signature:** `() => void`
|
|
689
722
|
|
|
690
|
-
**Parameters:**
|
|
691
|
-
|
|
692
|
-
|
|
693
723
|
**Examples:**
|
|
694
724
|
|
|
695
725
|
```typescript
|
|
@@ -706,25 +736,19 @@ class Post extends E.Model<Post> {
|
|
|
706
736
|
}
|
|
707
737
|
```
|
|
708
738
|
|
|
709
|
-
#### model.getPrimaryKey · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
739
|
+
#### model.getPrimaryKey · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
710
740
|
|
|
711
741
|
**Signature:** `() => Uint8Array<ArrayBufferLike>`
|
|
712
742
|
|
|
713
|
-
**Parameters:**
|
|
714
|
-
|
|
715
|
-
|
|
716
743
|
**Returns:** The primary key for this instance.
|
|
717
744
|
|
|
718
|
-
#### model.getPrimaryKeyHash · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
745
|
+
#### model.getPrimaryKeyHash · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
719
746
|
|
|
720
747
|
**Signature:** `() => number`
|
|
721
748
|
|
|
722
|
-
**Parameters:**
|
|
723
|
-
|
|
724
|
-
|
|
725
749
|
**Returns:** A 53-bit positive integer non-cryptographic hash of the primary key, or undefined if not yet saved.
|
|
726
750
|
|
|
727
|
-
#### model.isLazyField · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
751
|
+
#### model.isLazyField · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
728
752
|
|
|
729
753
|
**Signature:** `(field: keyof this) => boolean`
|
|
730
754
|
|
|
@@ -732,15 +756,12 @@ class Post extends E.Model<Post> {
|
|
|
732
756
|
|
|
733
757
|
- `field: keyof this`
|
|
734
758
|
|
|
735
|
-
#### model.preventPersist · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
759
|
+
#### model.preventPersist · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
736
760
|
|
|
737
761
|
Prevent this instance from being persisted to the database.
|
|
738
762
|
|
|
739
763
|
**Signature:** `() => this`
|
|
740
764
|
|
|
741
|
-
**Parameters:**
|
|
742
|
-
|
|
743
|
-
|
|
744
765
|
**Returns:** This model instance for chaining.
|
|
745
766
|
|
|
746
767
|
**Examples:**
|
|
@@ -751,7 +772,7 @@ user.name = "New Name";
|
|
|
751
772
|
user.preventPersist(); // Changes won't be saved
|
|
752
773
|
```
|
|
753
774
|
|
|
754
|
-
#### model.delete · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
775
|
+
#### model.delete · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
755
776
|
|
|
756
777
|
Delete this model instance from the database.
|
|
757
778
|
|
|
@@ -759,9 +780,6 @@ Removes the instance and all its index entries from the database and prevents fu
|
|
|
759
780
|
|
|
760
781
|
**Signature:** `() => void`
|
|
761
782
|
|
|
762
|
-
**Parameters:**
|
|
763
|
-
|
|
764
|
-
|
|
765
783
|
**Examples:**
|
|
766
784
|
|
|
767
785
|
```typescript
|
|
@@ -769,7 +787,7 @@ const user = User.load("user123");
|
|
|
769
787
|
user.delete(); // Removes from database
|
|
770
788
|
```
|
|
771
789
|
|
|
772
|
-
#### model.validate · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
790
|
+
#### model.validate · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
773
791
|
|
|
774
792
|
Validate all fields in this model instance.
|
|
775
793
|
|
|
@@ -791,15 +809,12 @@ if (errors.length > 0) {
|
|
|
791
809
|
}
|
|
792
810
|
```
|
|
793
811
|
|
|
794
|
-
#### model.isValid · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
812
|
+
#### model.isValid · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
795
813
|
|
|
796
814
|
Check if this model instance is valid.
|
|
797
815
|
|
|
798
816
|
**Signature:** `() => boolean`
|
|
799
817
|
|
|
800
|
-
**Parameters:**
|
|
801
|
-
|
|
802
|
-
|
|
803
818
|
**Returns:** true if all validations pass.
|
|
804
819
|
|
|
805
820
|
**Examples:**
|
|
@@ -809,27 +824,18 @@ const user = new User({name: "John"});
|
|
|
809
824
|
if (!user.isValid()) shoutAtTheUser();
|
|
810
825
|
```
|
|
811
826
|
|
|
812
|
-
#### model.getState · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
827
|
+
#### model.getState · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
813
828
|
|
|
814
829
|
**Signature:** `() => "created" | "deleted" | "loaded" | "lazy"`
|
|
815
830
|
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
#### model.toString · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L253)
|
|
831
|
+
#### model.toString · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
820
832
|
|
|
821
833
|
**Signature:** `() => string`
|
|
822
834
|
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
#### model.[Symbol.for('nodejs.util.inspect.custom')] · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L253)
|
|
835
|
+
#### model.[Symbol.for('nodejs.util.inspect.custom')] · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
827
836
|
|
|
828
837
|
**Signature:** `() => string`
|
|
829
838
|
|
|
830
|
-
**Parameters:**
|
|
831
|
-
|
|
832
|
-
|
|
833
839
|
### registerModel · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L113)
|
|
834
840
|
|
|
835
841
|
Register a model class with the Edinburgh ORM system.
|
|
@@ -887,13 +893,13 @@ class User extends E.Model<User> {
|
|
|
887
893
|
}
|
|
888
894
|
```
|
|
889
895
|
|
|
890
|
-
### string · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
896
|
+
### string · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
891
897
|
|
|
892
898
|
Type wrapper instance for the string type.
|
|
893
899
|
|
|
894
900
|
**Value:** `TypeWrapper<string>`
|
|
895
901
|
|
|
896
|
-
### orderedString · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
902
|
+
### orderedString · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
897
903
|
|
|
898
904
|
Type wrapper instance for the ordered string type, which is just like a string
|
|
899
905
|
except that it sorts lexicographically in the database (instead of by incrementing
|
|
@@ -903,37 +909,37 @@ may not contain null characters.
|
|
|
903
909
|
|
|
904
910
|
**Value:** `TypeWrapper<string>`
|
|
905
911
|
|
|
906
|
-
### number · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
912
|
+
### number · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
907
913
|
|
|
908
914
|
Type wrapper instance for the number type.
|
|
909
915
|
|
|
910
916
|
**Value:** `TypeWrapper<number>`
|
|
911
917
|
|
|
912
|
-
### dateTime · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
918
|
+
### dateTime · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
913
919
|
|
|
914
920
|
Type wrapper instance for the date/time type. Stored without timezone info, rounded to whole seconds.
|
|
915
921
|
|
|
916
922
|
**Value:** `TypeWrapper<Date>`
|
|
917
923
|
|
|
918
|
-
### boolean · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
924
|
+
### boolean · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
919
925
|
|
|
920
926
|
Type wrapper instance for the boolean type.
|
|
921
927
|
|
|
922
928
|
**Value:** `TypeWrapper<boolean>`
|
|
923
929
|
|
|
924
|
-
### identifier · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
930
|
+
### identifier · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
925
931
|
|
|
926
932
|
Type wrapper instance for the identifier type.
|
|
927
933
|
|
|
928
934
|
**Value:** `TypeWrapper<string>`
|
|
929
935
|
|
|
930
|
-
### undef · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
936
|
+
### undef · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
931
937
|
|
|
932
938
|
Type wrapper instance for the 'undefined' type.
|
|
933
939
|
|
|
934
940
|
**Value:** `TypeWrapper<undefined>`
|
|
935
941
|
|
|
936
|
-
### opt · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
942
|
+
### opt · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
937
943
|
|
|
938
944
|
Create an optional type wrapper (allows undefined).
|
|
939
945
|
|
|
@@ -956,7 +962,7 @@ const optionalString = E.opt(E.string);
|
|
|
956
962
|
const optionalNumber = E.opt(E.number);
|
|
957
963
|
```
|
|
958
964
|
|
|
959
|
-
### or · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
965
|
+
### or · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
960
966
|
|
|
961
967
|
Create a union type wrapper from multiple type choices.
|
|
962
968
|
|
|
@@ -979,7 +985,7 @@ const stringOrNumber = E.or(E.string, E.number);
|
|
|
979
985
|
const status = E.or("active", "inactive", "pending");
|
|
980
986
|
```
|
|
981
987
|
|
|
982
|
-
### array · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
988
|
+
### array · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
983
989
|
|
|
984
990
|
Create an array type wrapper with optional length constraints.
|
|
985
991
|
|
|
@@ -1003,7 +1009,7 @@ const stringArray = E.array(E.string);
|
|
|
1003
1009
|
const boundedArray = E.array(E.number, {min: 1, max: 10});
|
|
1004
1010
|
```
|
|
1005
1011
|
|
|
1006
|
-
### set · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1012
|
+
### set · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
1007
1013
|
|
|
1008
1014
|
Create a Set type wrapper with optional length constraints.
|
|
1009
1015
|
|
|
@@ -1027,7 +1033,7 @@ const stringSet = E.set(E.string);
|
|
|
1027
1033
|
const boundedSet = E.set(E.number, {min: 1, max: 10});
|
|
1028
1034
|
```
|
|
1029
1035
|
|
|
1030
|
-
### record · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1036
|
+
### record · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
1031
1037
|
|
|
1032
1038
|
Create a Record type wrapper for key-value objects with string or number keys.
|
|
1033
1039
|
|
|
@@ -1049,7 +1055,7 @@ Create a Record type wrapper for key-value objects with string or number keys.
|
|
|
1049
1055
|
const scores = E.record(E.number); // Record<string | number, number>
|
|
1050
1056
|
```
|
|
1051
1057
|
|
|
1052
|
-
### literal · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1058
|
+
### literal · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
1053
1059
|
|
|
1054
1060
|
Create a literal type wrapper for a constant value.
|
|
1055
1061
|
|
|
@@ -1072,7 +1078,7 @@ const statusType = E.literal("active");
|
|
|
1072
1078
|
const countType = E.literal(42);
|
|
1073
1079
|
```
|
|
1074
1080
|
|
|
1075
|
-
### link · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1081
|
+
### link · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
1076
1082
|
|
|
1077
1083
|
Create a link type wrapper for model relationships.
|
|
1078
1084
|
|
|
@@ -1100,7 +1106,7 @@ class Post extends E.Model<Post> {
|
|
|
1100
1106
|
}
|
|
1101
1107
|
```
|
|
1102
1108
|
|
|
1103
|
-
### index · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1109
|
+
### index · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
1104
1110
|
|
|
1105
1111
|
Create a secondary index on model fields, or a computed secondary index using a function.
|
|
1106
1112
|
|
|
@@ -1133,7 +1139,7 @@ class User extends E.Model<User> {
|
|
|
1133
1139
|
}
|
|
1134
1140
|
```
|
|
1135
1141
|
|
|
1136
|
-
### primary · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1142
|
+
### primary · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
1137
1143
|
|
|
1138
1144
|
Create a primary index on model fields.
|
|
1139
1145
|
|
|
@@ -1160,7 +1166,7 @@ class User extends E.Model<User> {
|
|
|
1160
1166
|
}
|
|
1161
1167
|
```
|
|
1162
1168
|
|
|
1163
|
-
### unique · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1169
|
+
### unique · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
1164
1170
|
|
|
1165
1171
|
Create a unique index on model fields, or a computed unique index using a function.
|
|
1166
1172
|
|
|
@@ -1193,7 +1199,7 @@ class User extends E.Model<User> {
|
|
|
1193
1199
|
}
|
|
1194
1200
|
```
|
|
1195
1201
|
|
|
1196
|
-
### dump · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1202
|
+
### dump · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
1197
1203
|
|
|
1198
1204
|
Dump database contents for debugging.
|
|
1199
1205
|
|
|
@@ -1202,7 +1208,7 @@ This is primarily useful for development and debugging purposes.
|
|
|
1202
1208
|
|
|
1203
1209
|
**Signature:** `() => void`
|
|
1204
1210
|
|
|
1205
|
-
### BaseIndex · [abstract class](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1211
|
+
### BaseIndex · [abstract class](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L123)
|
|
1206
1212
|
|
|
1207
1213
|
Base class for database indexes for efficient lookups on model fields.
|
|
1208
1214
|
|
|
@@ -1219,7 +1225,7 @@ Indexes enable fast queries on specific field combinations and enforce uniquenes
|
|
|
1219
1225
|
- `MyModel`: - The model class this index belongs to.
|
|
1220
1226
|
- `_fieldNames`: - Array of field names that make up this index.
|
|
1221
1227
|
|
|
1222
|
-
#### baseIndex.find · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1228
|
+
#### baseIndex.find · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
1223
1229
|
|
|
1224
1230
|
**Signature:** `(opts?: FindOptions<ARGS>) => IndexRangeIterator<M>`
|
|
1225
1231
|
|
|
@@ -1227,7 +1233,7 @@ Indexes enable fast queries on specific field combinations and enforce uniquenes
|
|
|
1227
1233
|
|
|
1228
1234
|
- `opts: FindOptions<ARGS>` (optional)
|
|
1229
1235
|
|
|
1230
|
-
#### baseIndex.batchProcess · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1236
|
+
#### baseIndex.batchProcess · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
1231
1237
|
|
|
1232
1238
|
[object Object],[object Object],[object Object]
|
|
1233
1239
|
|
|
@@ -1238,14 +1244,11 @@ Indexes enable fast queries on specific field combinations and enforce uniquenes
|
|
|
1238
1244
|
- `opts: FindOptions<ARGS> & { limitSeconds?: number; limitRows?: number }` (optional) - - Query options (same as `find()`), plus:
|
|
1239
1245
|
- `callback: (row: InstanceType<M>) => void | Promise<void>` - - Called for each matching row within a transaction
|
|
1240
1246
|
|
|
1241
|
-
#### baseIndex.toString · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1247
|
+
#### baseIndex.toString · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
1242
1248
|
|
|
1243
1249
|
**Signature:** `() => string`
|
|
1244
1250
|
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
### UniqueIndex · [class](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L253)
|
|
1251
|
+
### UniqueIndex · [class](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
1249
1252
|
|
|
1250
1253
|
Unique index that stores references to the primary key.
|
|
1251
1254
|
|
|
@@ -1255,7 +1258,7 @@ Unique index that stores references to the primary key.
|
|
|
1255
1258
|
- `F extends readonly (keyof InstanceType<M> & string)[]` - The field names that make up this index.
|
|
1256
1259
|
- `ARGS extends readonly any[] = IndexArgTypes<M, F>`
|
|
1257
1260
|
|
|
1258
|
-
#### uniqueIndex.get · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1261
|
+
#### uniqueIndex.get · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
1259
1262
|
|
|
1260
1263
|
Get a model instance by unique index key values.
|
|
1261
1264
|
|
|
@@ -1273,7 +1276,7 @@ Get a model instance by unique index key values.
|
|
|
1273
1276
|
const userByEmail = User.byEmail.get("john@example.com");
|
|
1274
1277
|
```
|
|
1275
1278
|
|
|
1276
|
-
### PrimaryIndex · [class](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1279
|
+
### PrimaryIndex · [class](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
1277
1280
|
|
|
1278
1281
|
Primary index that stores the actual model data.
|
|
1279
1282
|
|
|
@@ -1282,7 +1285,7 @@ Primary index that stores the actual model data.
|
|
|
1282
1285
|
- `M extends typeof Model` - The model class this index belongs to.
|
|
1283
1286
|
- `F extends readonly (keyof InstanceType<M> & string)[]` - The field names that make up this index.
|
|
1284
1287
|
|
|
1285
|
-
#### primaryIndex.get · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1288
|
+
#### primaryIndex.get · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
1286
1289
|
|
|
1287
1290
|
Get a model instance by primary key values.
|
|
1288
1291
|
|
|
@@ -1300,7 +1303,7 @@ Get a model instance by primary key values.
|
|
|
1300
1303
|
const user = User.pk.get("john_doe");
|
|
1301
1304
|
```
|
|
1302
1305
|
|
|
1303
|
-
#### primaryIndex.getLazy · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1306
|
+
#### primaryIndex.getLazy · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
1304
1307
|
|
|
1305
1308
|
Does the same as as `get()`, but will delay loading the instance from disk until the first
|
|
1306
1309
|
property access. In case it turns out the instance doesn't exist, an error will be thrown
|
|
@@ -1314,7 +1317,7 @@ at that time.
|
|
|
1314
1317
|
|
|
1315
1318
|
**Returns:** The (lazily loaded) model instance.
|
|
1316
1319
|
|
|
1317
|
-
### SecondaryIndex · [class](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1320
|
+
### SecondaryIndex · [class](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L255)
|
|
1318
1321
|
|
|
1319
1322
|
Secondary index for non-unique lookups.
|
|
1320
1323
|
|
|
@@ -1342,7 +1345,7 @@ Secondary index for non-unique lookups.
|
|
|
1342
1345
|
|
|
1343
1346
|
**Type:** `Map<number, Model<unknown>>`
|
|
1344
1347
|
|
|
1345
|
-
### DatabaseError · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1348
|
+
### DatabaseError · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L158)
|
|
1346
1349
|
|
|
1347
1350
|
The DatabaseError class is used to represent errors that occur during database operations.
|
|
1348
1351
|
It extends the built-in Error class and has a machine readable error code string property.
|
|
@@ -1352,10 +1355,10 @@ Invalid function arguments will throw TypeError.
|
|
|
1352
1355
|
|
|
1353
1356
|
**Value:** `DatabaseErrorConstructor`
|
|
1354
1357
|
|
|
1355
|
-
### runMigration · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1358
|
+
### runMigration · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L124)
|
|
1356
1359
|
|
|
1357
|
-
Run database migration:
|
|
1358
|
-
convert old primary indices, and clean up orphaned
|
|
1360
|
+
Run database migration: populate secondary indexes for old-version rows,
|
|
1361
|
+
convert old primary indices, rewrite row data, and clean up orphaned indices.
|
|
1359
1362
|
|
|
1360
1363
|
**Signature:** `(options?: MigrationOptions) => Promise<MigrationResult>`
|
|
1361
1364
|
|
|
@@ -1371,99 +1374,65 @@ Limit migration to specific table names.
|
|
|
1371
1374
|
|
|
1372
1375
|
**Type:** `string[]`
|
|
1373
1376
|
|
|
1374
|
-
#### migrationOptions.
|
|
1377
|
+
#### migrationOptions.populateSecondaries · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L23)
|
|
1378
|
+
|
|
1379
|
+
Populate secondary indexes for rows at old schema versions (default: true).
|
|
1380
|
+
|
|
1381
|
+
**Type:** `boolean`
|
|
1382
|
+
|
|
1383
|
+
#### migrationOptions.migratePrimaries · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L32)
|
|
1375
1384
|
|
|
1376
|
-
|
|
1385
|
+
Convert old primary indices when primary key fields changed (default: true).
|
|
1377
1386
|
|
|
1378
1387
|
**Type:** `boolean`
|
|
1379
1388
|
|
|
1380
|
-
#### migrationOptions.
|
|
1389
|
+
#### migrationOptions.rewriteData · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L40)
|
|
1381
1390
|
|
|
1382
|
-
|
|
1391
|
+
Rewrite all row data to the latest schema version (default: false).
|
|
1383
1392
|
|
|
1384
1393
|
**Type:** `boolean`
|
|
1385
1394
|
|
|
1386
|
-
#### migrationOptions.
|
|
1395
|
+
#### migrationOptions.removeOrphans · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L46)
|
|
1387
1396
|
|
|
1388
|
-
|
|
1397
|
+
Delete orphaned secondary/unique index entries (default: true).
|
|
1389
1398
|
|
|
1390
1399
|
**Type:** `boolean`
|
|
1391
1400
|
|
|
1392
|
-
#### migrationOptions.onProgress · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1401
|
+
#### migrationOptions.onProgress · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L48)
|
|
1393
1402
|
|
|
1394
1403
|
Progress callback.
|
|
1395
1404
|
|
|
1396
1405
|
**Type:** `(info: ProgressInfo) => void`
|
|
1397
1406
|
|
|
1398
|
-
### MigrationResult · [interface](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1407
|
+
### MigrationResult · [interface](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L51)
|
|
1399
1408
|
|
|
1400
|
-
#### migrationResult.secondaries · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1409
|
+
#### migrationResult.secondaries · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L54)
|
|
1401
1410
|
|
|
1402
|
-
Per-table
|
|
1411
|
+
Per-table counts of secondary index entries populated.
|
|
1403
1412
|
|
|
1404
1413
|
**Type:** `Record<string, number>`
|
|
1405
1414
|
|
|
1406
|
-
#### migrationResult.primaries · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1415
|
+
#### migrationResult.primaries · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L59)
|
|
1407
1416
|
|
|
1408
|
-
Per-table
|
|
1417
|
+
Per-table counts of old primary rows migrated.
|
|
1409
1418
|
|
|
1410
1419
|
**Type:** `Record<string, number>`
|
|
1411
1420
|
|
|
1412
|
-
#### migrationResult.conversionFailures · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#
|
|
1421
|
+
#### migrationResult.conversionFailures · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L59)
|
|
1413
1422
|
|
|
1414
1423
|
Per-table conversion failure counts by reason.
|
|
1415
1424
|
|
|
1416
1425
|
**Type:** `Record<string, Record<string, number>>`
|
|
1417
1426
|
|
|
1418
|
-
#### migrationResult.
|
|
1419
|
-
|
|
1420
|
-
Number of orphaned index entries deleted.
|
|
1421
|
-
|
|
1422
|
-
**Type:** `number`
|
|
1423
|
-
|
|
1424
|
-
## Schema Migrations
|
|
1425
|
-
|
|
1426
|
-
Edinburgh automatically tracks the schema version of each model. When you change fields, field types, indexes, or the `migrate()` function, Edinburgh detects a new schema version.
|
|
1427
|
-
|
|
1428
|
-
### What happens automatically (lazy migration)
|
|
1429
|
-
|
|
1430
|
-
Changes to regular (non-index) field values are migrated lazily. When a row with an old schema version is loaded from disk, it is deserialized using the old field types and transformed by the optional static `migrate()` function. This is transparent and requires no downtime.
|
|
1431
|
-
|
|
1432
|
-
```typescript
|
|
1433
|
-
@E.registerModel
|
|
1434
|
-
class User extends E.Model<User> {
|
|
1435
|
-
static pk = E.primary(User, "id");
|
|
1436
|
-
id = E.field(E.identifier);
|
|
1437
|
-
name = E.field(E.string);
|
|
1438
|
-
role = E.field(E.string); // newly added field
|
|
1439
|
-
|
|
1440
|
-
static migrate(record: Record<string, any>) {
|
|
1441
|
-
record.role ??= "user"; // provide a default for old rows
|
|
1442
|
-
}
|
|
1443
|
-
}
|
|
1444
|
-
```
|
|
1445
|
-
|
|
1446
|
-
### What requires `migrate-edinburgh`
|
|
1427
|
+
#### migrationResult.rewritten · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L64)
|
|
1447
1428
|
|
|
1448
|
-
|
|
1429
|
+
Per-table counts of rows rewritten to latest version.
|
|
1449
1430
|
|
|
1450
|
-
|
|
1451
|
-
- **Changing the fields or types** of an existing index
|
|
1452
|
-
- A **`migrate()` function changes values** that are used in index fields
|
|
1453
|
-
|
|
1454
|
-
The tool populates new indexes, removes orphaned ones, and updates index entries whose values were changed by `migrate()`. It does *not* rewrite primary data rows - lazy migration handles that on read.
|
|
1455
|
-
|
|
1456
|
-
```bash
|
|
1457
|
-
npx migrate-edinburgh --import ./src/models.ts
|
|
1458
|
-
```
|
|
1431
|
+
**Type:** `Record<string, number>`
|
|
1459
1432
|
|
|
1460
|
-
|
|
1433
|
+
#### migrationResult.orphans · [member](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L68)
|
|
1461
1434
|
|
|
1462
|
-
|
|
1435
|
+
Number of orphaned index entries deleted.
|
|
1463
1436
|
|
|
1464
|
-
|
|
1465
|
-
import { runMigration } from "edinburgh";
|
|
1437
|
+
**Type:** `number`
|
|
1466
1438
|
|
|
1467
|
-
const result = await runMigration({ tables: ["User"] });
|
|
1468
|
-
console.log(result.upgraded); // { User: 1500 }
|
|
1469
|
-
```
|