@effectstream/db 0.100.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/assets-config.json +28 -0
- package/migrations/assets.ts +35 -0
- package/migrations/readme.md +37 -0
- package/migrations/system-down-v-0.0.0.sql +2 -0
- package/migrations/system-down-v-0.0.1.sql +14 -0
- package/migrations/system-up-v-0.0.0.sql +40 -0
- package/migrations/system-up-v-0.0.1.sql +117 -0
- package/migrations/system-up-v-0.0.2.sql +22 -0
- package/migrations/system-up-v-0.8.1.sql +5 -0
- package/migrations/system-version.ts +147 -0
- package/package.json +33 -0
- package/pgtypedconfig.json +21 -0
- package/scripts/Dockerfile +13 -0
- package/scripts/apply-migrations.ts +49 -0
- package/scripts/pgtyped-internal.ts +43 -0
- package/scripts/pgtyped-update.ts +119 -0
- package/scripts/start-pglite.ts +71 -0
- package/scripts/wait-for-db.ts +43 -0
- package/src/dynamic-tables.ts +110 -0
- package/src/event-indexing.ts +31 -0
- package/src/migrations.ts +28 -0
- package/src/mod.ts +65 -0
- package/src/pg-connection.test.ts +99 -0
- package/src/pg-connection.ts +211 -0
- package/src/register-events.ts +40 -0
- package/src/scheduled-constructors.ts +117 -0
- package/src/snapshot-handler.ts +164 -0
- package/src/sql/accounts.queries.ts +350 -0
- package/src/sql/accounts.sql +77 -0
- package/src/sql/achievements.queries.ts +74 -0
- package/src/sql/achievements.sql +17 -0
- package/src/sql/block-heights.queries.ts +205 -0
- package/src/sql/block-heights.sql +45 -0
- package/src/sql/events.queries.ts +201 -0
- package/src/sql/events.sql +41 -0
- package/src/sql/nonces.queries.ts +85 -0
- package/src/sql/nonces.sql +11 -0
- package/src/sql/primitives.queries.ts +35 -0
- package/src/sql/primitives.sql +4 -0
- package/src/sql/rollup_inputs.queries.ts +654 -0
- package/src/sql/rollup_inputs.sql +227 -0
- package/src/sql/statistics.queries.ts +160 -0
- package/src/sql/statistics.sql +55 -0
- package/src/sql/sync-protocols/page.queries.ts +140 -0
- package/src/sql/sync-protocols/page.sql +39 -0
- package/src/sql/system.queries.ts +356 -0
- package/src/sql/system.sql +75 -0
- package/src/sql/tables.queries.ts +89 -0
- package/src/sql/tables.sql +17 -0
- package/src/system.ts +41 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"files": [
|
|
3
|
+
{
|
|
4
|
+
"importPath": "./migrations/system-up-v-0.0.0.sql",
|
|
5
|
+
"calledName": "system-up-v-0-0-0"
|
|
6
|
+
},
|
|
7
|
+
{
|
|
8
|
+
"importPath": "./migrations/system-up-v-0.0.1.sql",
|
|
9
|
+
"calledName": "system-up-v-0-0-1"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"importPath": "./migrations/system-up-v-0.0.2.sql",
|
|
13
|
+
"calledName": "system-up-v-0-0-2"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"importPath": "./migrations/system-up-v-0.8.1.sql",
|
|
17
|
+
"calledName": "system-up-v-0-8-1"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"importPath": "./migrations/system-down-v-0.0.0.sql",
|
|
21
|
+
"calledName": "system-down-v-0-0-0"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"importPath": "./migrations/system-down-v-0.0.1.sql",
|
|
25
|
+
"calledName": "system-down-v-0-0-1"
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
|
|
2
|
+
function decodeBase64(b64: string): Uint8Array {
|
|
3
|
+
return Uint8Array.from(atob(b64), c => c.charCodeAt(0));
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
const bundledObject = {
|
|
7
|
+
files:{
|
|
8
|
+
"system-up-v-0-0-0":{
|
|
9
|
+
content:decodeBase64("Q1JFQVRFIFNDSEVNQSBJRiBOT1QgRVhJU1RTIGVmZmVjdHN0cmVhbTsKCkNSRUFURSBFWFRFTlNJT04gSUYgTk9UIEVYSVNUUyBwZ19pdm07CgpDUkVBVEUgVEFCTEUgZWZmZWN0c3RyZWFtLmVmZmVjdHN0cmVhbV9leHBlY3RlZF92ZXJzaW9uICgKICBhcHBfdmVyc2lvbl9tYWpvciBJTlRFR0VSIE5PVCBOVUxMLAogIGFwcF92ZXJzaW9uX21pbm9yIElOVEVHRVIgTk9UIE5VTEwsCiAgYXBwX3ZlcnNpb25fcGF0Y2ggSU5URUdFUiBOT1QgTlVMTCwKICBlbmdpbmVfdmVyc2lvbl9tYWpvciBJTlRFR0VSIE5PVCBOVUxMLAogIGVuZ2luZV92ZXJzaW9uX21pbm9yIElOVEVHRVIgTk9UIE5VTEwsCiAgZW5naW5lX3ZlcnNpb25fcGF0Y2ggSU5URUdFUiBOT1QgTlVMTCwKICBibG9ja19oZWlnaHQgSU5URUdFUiBOT1QgTlVMTAopOwoKQ1JFQVRFIFVOSVFVRSBJTkRFWCBlZmZlY3RzdHJlYW1fZXhwZWN0ZWRfdmVyc2lvbl91bmlxdWVfdmVyc2lvbl9ibG9ja19oZWlnaHQgCk9OIGVmZmVjdHN0cmVhbS5lZmZlY3RzdHJlYW1fZXhwZWN0ZWRfdmVyc2lvbiAKKGFwcF92ZXJzaW9uX21ham9yLCBhcHBfdmVyc2lvbl9taW5vciwgYXBwX3ZlcnNpb25fcGF0Y2gsIAplbmdpbmVfdmVyc2lvbl9tYWpvciwgZW5naW5lX3ZlcnNpb25fbWlub3IsIGVuZ2luZV92ZXJzaW9uX3BhdGNoKTsKCkNSRUFURSBUQUJMRSBlZmZlY3RzdHJlYW0uZWZmZWN0c3RyZWFtX3ZlcnNpb25faGlzdG9yeSAoCiAgYXBwX3ZlcnNpb25fbWFqb3IgSU5URUdFUiBOT1QgTlVMTCwKICBhcHBfdmVyc2lvbl9taW5vciBJTlRFR0VSIE5PVCBOVUxMLAogIGFwcF92ZXJzaW9uX3BhdGNoIElOVEVHRVIgTk9UIE5VTEwsCiAgZW5naW5lX3ZlcnNpb25fbWFqb3IgSU5URUdFUiBOT1QgTlVMTCwKICBlbmdpbmVfdmVyc2lvbl9taW5vciBJTlRFR0VSIE5PVCBOVUxMLAogIGVuZ2luZV92ZXJzaW9uX3BhdGNoIElOVEVHRVIgTk9UIE5VTEwsCiAgYmxvY2tfaGVpZ2h0IElOVEVHRVIgTk9UIE5VTEwKKTsKCkNSRUFURSBVTklRVUUgSU5ERVggZWZmZWN0c3RyZWFtX3ZlcnNpb25faGlzdG9yeV91bmlxdWVfdmVyc2lvbl9ibG9ja19oZWlnaHQgCk9OIGVmZmVjdHN0cmVhbS5lZmZlY3RzdHJlYW1fdmVyc2lvbl9oaXN0b3J5IAooYXBwX3ZlcnNpb25fbWFqb3IsIGFwcF92ZXJzaW9uX21pbm9yLCBhcHBfdmVyc2lvbl9wYXRjaCwgCmVuZ2luZV92ZXJzaW9uX21ham9yLCBlbmdpbmVfdmVyc2lvbl9taW5vciwgZW5naW5lX3ZlcnNpb25fcGF0Y2gpOwoKQ1JFQVRFIFRBQkxFIGVmZmVjdHN0cmVhbS5lZmZlY3RzdHJlYW1fbWlncmF0aW9uX2hpc3RvcnkgKAogIG5hbWUgVEVYVCBOT1QgTlVMTCwKICBibG9ja19oZWlnaHQgSU5URUdFUiBOT1QgTlVMTCwKICBpc19zeXN0ZW1fbWlncmF0aW9uIEJPT0xFQU4gTk9UIE5VTEwKKTsKCg=="),
|
|
10
|
+
extension: "sql"
|
|
11
|
+
},
|
|
12
|
+
"system-up-v-0-0-1":{
|
|
13
|
+
content:decodeBase64("Q1JFQVRFIFNDSEVNQSBJRiBOT1QgRVhJU1RTIGVmZmVjdHN0cmVhbTsKQ1JFQVRFIFNDSEVNQSBJRiBOT1QgRVhJU1RTIHByaW1pdGl2ZXM7CgpDUkVBVEUgVEFCTEUgZWZmZWN0c3RyZWFtLmVmZmVjdHN0cmVhbV9ibG9ja3MgKAogIGJsb2NrX2hlaWdodCBJTlRFR0VSIFBSSU1BUlkgS0VZLAogIHZlciBJTlRFR0VSIE5PVCBOVUxMLAogIG1haW5fY2hhaW5fYmxvY2tfaGFzaCBCWVRFQSBOT1QgTlVMTCwKICBzZWVkIFRFWFQgTk9UIE5VTEwsCiAgbXNfdGltZXN0YW1wIFRJTUVTVEFNUCB3aXRob3V0IHRpbWUgem9uZSBOT1QgTlVMTCwKICBlZmZlY3RzdHJlYW1fYmxvY2tfaGFzaCBCWVRFQQopOwoKQ1JFQVRFIFRBQkxFIGVmZmVjdHN0cmVhbS5yb2xsdXBfaW5wdXRzICgKICBpZCBTRVJJQUwgUFJJTUFSWSBLRVksCiAgZnJvbV9hZGRyZXNzIFRFWFQgTk9UIE5VTEwsCiAgZnJvbV9hZGRyZXNzX3R5cGUgSU5URUdFUiBOT1QgTlVMTCwKICBpbnB1dF9kYXRhIFRFWFQgTk9UIE5VTEwKKTsKCkNSRUFURSBUQUJMRSBlZmZlY3RzdHJlYW0ucm9sbHVwX2lucHV0X2Z1dHVyZV9ibG9jayAoCiAgaWQgSU5URUdFUiBQUklNQVJZIEtFWSBSRUZFUkVOQ0VTIGVmZmVjdHN0cmVhbS5yb2xsdXBfaW5wdXRzKGlkKSBPTiBERUxFVEUgQ0FTQ0FERSwKICBmdXR1cmVfYmxvY2tfaGVpZ2h0IElOVEVHRVIgTk9UIE5VTEwKKTsKQ1JFQVRFIFRBQkxFIGVmZmVjdHN0cmVhbS5yb2xsdXBfaW5wdXRfZnV0dXJlX3RpbWVzdGFtcCAoCiAgaWQgSU5URUdFUiBQUklNQVJZIEtFWSBSRUZFUkVOQ0VTIGVmZmVjdHN0cmVhbS5yb2xsdXBfaW5wdXRzKGlkKSBPTiBERUxFVEUgQ0FTQ0FERSwKICBmdXR1cmVfbXNfdGltZXN0YW1wIFRJTUVTVEFNUCB3aXRob3V0IHRpbWUgem9uZSBOT1QgTlVMTAopOwoKQ1JFQVRFIFRBQkxFIGVmZmVjdHN0cmVhbS5yb2xsdXBfaW5wdXRfcmVzdWx0ICgKICBpZCBJTlRFR0VSIFBSSU1BUlkgS0VZIFJFRkVSRU5DRVMgZWZmZWN0c3RyZWFtLnJvbGx1cF9pbnB1dHMoaWQpIE9OIERFTEVURSBDQVNDQURFLAogIHN1Y2Nlc3MgQk9PTEVBTiBOT1QgTlVMTCwKICBlZmZlY3RzdHJlYW1fdHhfaGFzaCBCWVRFQSBOT1QgTlVMTCwKICBibG9ja19oZWlnaHQgSU5URUdFUiBOT1QgTlVMTCBSRUZFUkVOQ0VTIGVmZmVjdHN0cmVhbS5lZmZlY3RzdHJlYW1fYmxvY2tzKGJsb2NrX2hlaWdodCksCiAgaW5kZXhfaW5fYmxvY2sgSU5URUdFUiBOT1QgTlVMTAopOwoKQ1JFQVRFIFRBQkxFIGVmZmVjdHN0cmVhbS5yb2xsdXBfaW5wdXRfb3JpZ2luICgKICBpZCBJTlRFR0VSIFBSSU1BUlkgS0VZIFJFRkVSRU5DRVMgZWZmZWN0c3RyZWFtLnJvbGx1cF9pbnB1dHMoaWQpIE9OIERFTEVURSBDQVNDQURFLAogIHByaW1pdGl2ZV9uYW1lIFRFWFQsCiAgY2FpcDIgVEVYVCwKICB0eF9oYXNoIEJZVEVBLAogIGNvbnRyYWN0X2FkZHJlc3MgVEVYVAopOwoKQ1JFQVRFIFRBQkxFIGVmZmVjdHN0cmVhbS5wcmltaXRpdmVfYWNjb3VudGluZyAoCiAgcHJpbWl0aXZlX25hbWUgVEVYVCBOT1QgTlVMTCwKICBpZCBTRVJJQUwsCiAgZWZmZWN0c3RyZWFtX2Jsb2NrX2hlaWdodCBJTlRFR0VSIE5PVCBOVUxMIFJFRkVSRU5DRVMgZWZmZWN0c3RyZWFtLmVmZmVjdHN0cmVhbV9ibG9ja3MoYmxvY2tfaGVpZ2h0KSwKICBwYXlsb2FkX3R5cGUgVEVYVCBOT1QgTlVMTCwKICBwYXlsb2FkIEpTT04gTk9UIE5VTEwsCiAgcGF5bG9hZF9oYXNoIFRFWFQgR0VORVJBVEVEIEFMV0FZUyBBUyAobWQ1KHBheWxvYWQ6OnRleHQpKSBTVE9SRUQsCiAgUFJJTUFSWSBLRVkgKHByaW1pdGl2ZV9uYW1lLCBpZCkKKTsKCkNSRUFURSBUQUJMRSBlZmZlY3RzdHJlYW0ubm9uY2VzICgKICBub25jZSBURVhUIFBSSU1BUlkgS0VZLAogIGJsb2NrX2hlaWdodCBJTlRFR0VSIE5PVCBOVUxMIFJFRkVSRU5DRVMgZWZmZWN0c3RyZWFtLmVmZmVjdHN0cmVhbV9ibG9ja3MoYmxvY2tfaGVpZ2h0KQopOwoKQ1JFQVRFIFRBQkxFIGVmZmVjdHN0cmVhbS5zeW5jX3Byb3RvY29sX3BhZ2luYXRpb24gKAogIHByb3RvY29sX25hbWUgVEVYVCBOT1QgTlVMTCwKICBwYWdlX251bWJlciBJTlRFR0VSIE5PVCBOVUxMLAogIHBhZ2UgSlNPTkIgTk9UIE5VTEwsCiAgUFJJTUFSWSBLRVkgKHByb3RvY29sX25hbWUsIHBhZ2VfbnVtYmVyKQopOwoKQ1JFQVRFIElOREVYIHN5bmNfcHJvdG9jb2xfcGFnaW5hdGlvbl9wYWdlX251bWJlcl9pZHggb24gZWZmZWN0c3RyZWFtLnN5bmNfcHJvdG9jb2xfcGFnaW5hdGlvbihwcm90b2NvbF9uYW1lLCBwYWdlX251bWJlcik7CgpDUkVBVEUgVEFCTEUgZWZmZWN0c3RyZWFtLnByaW1pdGl2ZV9jb25maWcgKAogIHByaW1pdGl2ZV9uYW1lIFRFWFQgUFJJTUFSWSBLRVksCiAgcHJpbWl0aXZlX3R5cGUgVEVYVCBOT1QgTlVMTCwKICBwcmltaXRpdmVfY2FpcDIgVEVYVCBOT1QgTlVMTCwKICBwcm90b2NvbF9uYW1lIFRFWFQgTk9UIE5VTEwsCiAgY29uZmlnIEpTT05CIE5PVCBOVUxMLAogIGNvbmZpZ19oYXNoIElOVEVHRVIgTk9UIE5VTEwsCiAgcGFyZW50X25hbWUgVEVYVAopOwoKQ1JFQVRFIFRBQkxFIGVmZmVjdHN0cmVhbS5hY2NvdW50cyAoCiAgaWQgU0VSSUFMIFBSSU1BUlkgS0VZLAogIHByaW1hcnlfYWRkcmVzcyBURVhUCik7CgpDUkVBVEUgVEFCTEUgZWZmZWN0c3RyZWFtLmFkZHJlc3NlcyAoCiAgYWRkcmVzcyBURVhUIE5PVCBOVUxMIFVOSVFVRSwKICBhZGRyZXNzX3R5cGUgSU5URUdFUiBOT1QgTlVMTCwKICBhY2NvdW50X2lkIElOVEVHRVIgUkVGRVJFTkNFUyBlZmZlY3RzdHJlYW0uYWNjb3VudHMoaWQpCik7CgpDUkVBVEUgSU5ERVggYWRkcmVzc2VzX2FjY291bnRfaWRfaWR4IE9OIGVmZmVjdHN0cmVhbS5hZGRyZXNzZXMoYWNjb3VudF9pZCk7CgpBTFRFUiBUQUJMRSBlZmZlY3RzdHJlYW0uYWNjb3VudHMgQUREIENPTlNUUkFJTlQgZmtfcHJpbWFyeV9hZGRyZXNzX2FkZHJlc3MgRk9SRUlHTiBLRVkgKHByaW1hcnlfYWRkcmVzcykgUkVGRVJFTkNFUyBlZmZlY3RzdHJlYW0uYWRkcmVzc2VzKGFkZHJlc3MpOwoKQ1JFQVRFIFRBQkxFIGVmZmVjdHN0cmVhbS5hY2hpZXZlbWVudF9wcm9ncmVzcygKICBhY2NvdW50X2lkIElOVEVHRVIgTk9UIE5VTEwgUkVGRVJFTkNFUyBlZmZlY3RzdHJlYW0uYWNjb3VudHMoaWQpLAogIG5hbWUgVEVYVCBOT1QgTlVMTCwKICBjb21wbGV0ZWRfZGF0ZSBUSU1FU1RBTVAsCiAgcHJvZ3Jlc3MgSU5URUdFUiwKICB0b3RhbCBJTlRFR0VSLAogIFBSSU1BUlkgS0VZIChhY2NvdW50X2lkLCBuYW1lKQopOwoKQ1JFQVRFIFRBQkxFIGVmZmVjdHN0cmVhbS5ldmVudCAoCiAgaWQgU0VSSUFMIFBSSU1BUlkgS0VZLAogIHRvcGljIFRFWFQgTk9UIE5VTEwsCiAgYWRkcmVzcyBURVhUIE5PVCBOVUxMLAogIGRhdGEgSlNPTkIgTk9UIE5VTEwsCiAgYmxvY2tfaGVpZ2h0IElOVEVHRVIgTk9UIE5VTEwsCiAgdHhfaW5kZXggSU5URUdFUiBOT1QgTlVMTCwKICBsb2dfaW5kZXggSU5URUdFUiBOT1QgTlVMTAopOwoKQ1JFQVRFIFRBQkxFIGVmZmVjdHN0cmVhbS5yZWdpc3RlcmVkX2V2ZW50ICgKICBuYW1lIFRFWFQgTk9UIE5VTEwsCiAgdG9waWMgVEVYVCBOT1QgTlVMTCwKICBQUklNQVJZIEtFWShuYW1lLCB0b3BpYykKKTsK"),
|
|
14
|
+
extension: "sql"
|
|
15
|
+
},
|
|
16
|
+
"system-up-v-0-0-2":{
|
|
17
|
+
content:decodeBase64("LS0gRW5mb3JjZSB1bmlxdWVuZXNzIGZvciBtaWdyYXRpb24gaGlzdG9yeSBlbnRyaWVzCkNSRUFURSBVTklRVUUgSU5ERVggSUYgTk9UIEVYSVNUUyBlZmZlY3RzdHJlYW1fbWlncmF0aW9uX2hpc3RvcnlfdW5pcXVlX25hbWVfc3lzdGVtCk9OIGVmZmVjdHN0cmVhbS5lZmZlY3RzdHJlYW1fbWlncmF0aW9uX2hpc3RvcnkgKG5hbWUsIGlzX3N5c3RlbV9taWdyYXRpb24pOwoKLS0gQWRkIGlkZW1wb3RlbmN5IHN1cHBvcnQgZm9yIHByaW1pdGl2ZSBhY2NvdW50aW5nIGVudHJpZXMKRE8gJCQKQkVHSU4KICBJRiBOT1QgRVhJU1RTICgKICAgIFNFTEVDVCAxCiAgICBGUk9NIGluZm9ybWF0aW9uX3NjaGVtYS5jb2x1bW5zCiAgICBXSEVSRSB0YWJsZV9zY2hlbWEgPSAnZWZmZWN0c3RyZWFtJwogICAgICBBTkQgdGFibGVfbmFtZSA9ICdwcmltaXRpdmVfYWNjb3VudGluZycKICAgICAgQU5EIGNvbHVtbl9uYW1lID0gJ3BheWxvYWRfaGFzaCcKICApIFRIRU4KICAgIEFMVEVSIFRBQkxFIGVmZmVjdHN0cmVhbS5wcmltaXRpdmVfYWNjb3VudGluZwogICAgICBBREQgQ09MVU1OIHBheWxvYWRfaGFzaCBURVhUIEdFTkVSQVRFRCBBTFdBWVMgQVMgKG1kNShwYXlsb2FkOjp0ZXh0KSkgU1RPUkVEOwogIEVORCBJRjsKRU5ECiQkOwoKQ1JFQVRFIFVOSVFVRSBJTkRFWCBJRiBOT1QgRVhJU1RTIHByaW1pdGl2ZV9hY2NvdW50aW5nX3VuaXF1ZV9wYXlsb2FkX3Blcl9ibG9jawpPTiBlZmZlY3RzdHJlYW0ucHJpbWl0aXZlX2FjY291bnRpbmcgKHByaW1pdGl2ZV9uYW1lLCBlZmZlY3RzdHJlYW1fYmxvY2tfaGVpZ2h0LCBwYXlsb2FkX2hhc2gpOwo="),
|
|
18
|
+
extension: "sql"
|
|
19
|
+
},
|
|
20
|
+
"system-up-v-0-8-1":{
|
|
21
|
+
content:decodeBase64("Q1JFQVRFIFRBQkxFIGVmZmVjdHN0cmVhbS5zeW5jX3Byb3RvY29sX2NvbmZpZ19zbmFwc2hvdCAoCiAgcHJvdG9jb2xfbmFtZSBURVhUIFBSSU1BUlkgS0VZLAogIG5ldHdvcmtfdHlwZSBURVhUIE5PVCBOVUxMLAogIGltbXV0YWJsZV9jb25maWcgSlNPTkIgTk9UIE5VTEwKKTsK"),
|
|
22
|
+
extension: "sql"
|
|
23
|
+
},
|
|
24
|
+
"system-down-v-0-0-0":{
|
|
25
|
+
content:decodeBase64("RFJPUCBUQUJMRSBlZmZlY3RzdHJlYW0uZWZmZWN0c3RyZWFtX3ZlcnNpb25faGlzdG9yeTsKRFJPUCBUQUJMRSBlZmZlY3RzdHJlYW0uZWZmZWN0c3RyZWFtX21pZ3JhdGlvbl9oaXN0b3J5Ow=="),
|
|
26
|
+
extension: "sql"
|
|
27
|
+
},
|
|
28
|
+
"system-down-v-0-0-1":{
|
|
29
|
+
content:decodeBase64("RFJPUCBUQUJMRSBlZmZlY3RzdHJlYW0uZWZmZWN0c3RyZWFtX2Jsb2NrczsKRFJPUCBUQUJMRSBlZmZlY3RzdHJlYW0ucm9sbHVwX2lucHV0czsKRFJPUCBUQUJMRSBlZmZlY3RzdHJlYW0ucm9sbHVwX2lucHV0X2Z1dHVyZV9ibG9jazsKRFJPUCBUQUJMRSBlZmZlY3RzdHJlYW0ucm9sbHVwX2lucHV0X2Z1dHVyZV90aW1lc3RhbXA7CkRST1AgVEFCTEUgZWZmZWN0c3RyZWFtLnJvbGx1cF9pbnB1dF9yZXN1bHQ7CkRST1AgVEFCTEUgZWZmZWN0c3RyZWFtLnJvbGx1cF9pbnB1dF9vcmlnaW47CkRST1AgVEFCTEUgZWZmZWN0c3RyZWFtLm5vbmNlczsKRFJPUCBUQUJMRSBlZmZlY3RzdHJlYW0uc3luY19wcm90b2NvbF9wYWdpbmF0aW9uOwpEUk9QIFRBQkxFIGVmZmVjdHN0cmVhbS5wcmltaXRpdmVfY29uZmlnOwpEUk9QIFRBQkxFIGVmZmVjdHN0cmVhbS5hZGRyZXNzZXM7CkRST1AgVEFCTEUgZWZmZWN0c3RyZWFtLmRlbGVnYXRpb25zOwpEUk9QIFRBQkxFIGVmZmVjdHN0cmVhbS5hY2hpZXZlbWVudF9wcm9ncmVzczsKRFJPUCBUQUJMRSBlZmZlY3RzdHJlYW0uZXZlbnQ7CkRST1AgVEFCTEUgZWZmZWN0c3RyZWFtLnJlZ2lzdGVyZWRfZXZlbnQ7Cg=="),
|
|
30
|
+
extension: "sql"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export default bundledObject;
|
|
35
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Effectstream DB Management
|
|
2
|
+
|
|
3
|
+
`System Migrations` create and update the DB structure to run with specific
|
|
4
|
+
versions of Effectstream.\
|
|
5
|
+
All migrations are applied that are <= than the current version.
|
|
6
|
+
|
|
7
|
+
> Note v0.0.0 is a special migration that gets applied once before the chain
|
|
8
|
+
> sync
|
|
9
|
+
|
|
10
|
+
### Migration Files
|
|
11
|
+
|
|
12
|
+
Files must be named as the version where they will be applied.\
|
|
13
|
+
E.g.,
|
|
14
|
+
|
|
15
|
+
- system-up-v-0.3.20
|
|
16
|
+
- system-up-v-1.0.0
|
|
17
|
+
|
|
18
|
+
### Version
|
|
19
|
+
|
|
20
|
+
Package Version is the System Version.\
|
|
21
|
+
Version in root `deno.json` must be kept in sync with `system-version.ts`, as we
|
|
22
|
+
cannot read this file from the executing engine.
|
|
23
|
+
|
|
24
|
+
### Deno JSR
|
|
25
|
+
|
|
26
|
+
At the time JSR requires to bundle assets in TS. This is automatically applied
|
|
27
|
+
when the Pgtyped is called
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
deno task pgtyped:update
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
generate assets.ts from packages/node-sdk/db directory
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
rm ./migrations/assets.ts && deno run --allow-read jsr:@codemonument/asset-builder --import-file assets-config.json >> ./migrations/assets.ts
|
|
37
|
+
```
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
DROP TABLE effectstream.effectstream_blocks;
|
|
2
|
+
DROP TABLE effectstream.rollup_inputs;
|
|
3
|
+
DROP TABLE effectstream.rollup_input_future_block;
|
|
4
|
+
DROP TABLE effectstream.rollup_input_future_timestamp;
|
|
5
|
+
DROP TABLE effectstream.rollup_input_result;
|
|
6
|
+
DROP TABLE effectstream.rollup_input_origin;
|
|
7
|
+
DROP TABLE effectstream.nonces;
|
|
8
|
+
DROP TABLE effectstream.sync_protocol_pagination;
|
|
9
|
+
DROP TABLE effectstream.primitive_config;
|
|
10
|
+
DROP TABLE effectstream.addresses;
|
|
11
|
+
DROP TABLE effectstream.delegations;
|
|
12
|
+
DROP TABLE effectstream.achievement_progress;
|
|
13
|
+
DROP TABLE effectstream.event;
|
|
14
|
+
DROP TABLE effectstream.registered_event;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
CREATE SCHEMA IF NOT EXISTS effectstream;
|
|
2
|
+
|
|
3
|
+
CREATE EXTENSION IF NOT EXISTS pg_ivm;
|
|
4
|
+
|
|
5
|
+
CREATE TABLE effectstream.effectstream_expected_version (
|
|
6
|
+
app_version_major INTEGER NOT NULL,
|
|
7
|
+
app_version_minor INTEGER NOT NULL,
|
|
8
|
+
app_version_patch INTEGER NOT NULL,
|
|
9
|
+
engine_version_major INTEGER NOT NULL,
|
|
10
|
+
engine_version_minor INTEGER NOT NULL,
|
|
11
|
+
engine_version_patch INTEGER NOT NULL,
|
|
12
|
+
block_height INTEGER NOT NULL
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
CREATE UNIQUE INDEX effectstream_expected_version_unique_version_block_height
|
|
16
|
+
ON effectstream.effectstream_expected_version
|
|
17
|
+
(app_version_major, app_version_minor, app_version_patch,
|
|
18
|
+
engine_version_major, engine_version_minor, engine_version_patch);
|
|
19
|
+
|
|
20
|
+
CREATE TABLE effectstream.effectstream_version_history (
|
|
21
|
+
app_version_major INTEGER NOT NULL,
|
|
22
|
+
app_version_minor INTEGER NOT NULL,
|
|
23
|
+
app_version_patch INTEGER NOT NULL,
|
|
24
|
+
engine_version_major INTEGER NOT NULL,
|
|
25
|
+
engine_version_minor INTEGER NOT NULL,
|
|
26
|
+
engine_version_patch INTEGER NOT NULL,
|
|
27
|
+
block_height INTEGER NOT NULL
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
CREATE UNIQUE INDEX effectstream_version_history_unique_version_block_height
|
|
31
|
+
ON effectstream.effectstream_version_history
|
|
32
|
+
(app_version_major, app_version_minor, app_version_patch,
|
|
33
|
+
engine_version_major, engine_version_minor, engine_version_patch);
|
|
34
|
+
|
|
35
|
+
CREATE TABLE effectstream.effectstream_migration_history (
|
|
36
|
+
name TEXT NOT NULL,
|
|
37
|
+
block_height INTEGER NOT NULL,
|
|
38
|
+
is_system_migration BOOLEAN NOT NULL
|
|
39
|
+
);
|
|
40
|
+
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
CREATE SCHEMA IF NOT EXISTS effectstream;
|
|
2
|
+
CREATE SCHEMA IF NOT EXISTS primitives;
|
|
3
|
+
|
|
4
|
+
CREATE TABLE effectstream.effectstream_blocks (
|
|
5
|
+
block_height INTEGER PRIMARY KEY,
|
|
6
|
+
ver INTEGER NOT NULL,
|
|
7
|
+
main_chain_block_hash BYTEA NOT NULL,
|
|
8
|
+
seed TEXT NOT NULL,
|
|
9
|
+
ms_timestamp TIMESTAMP without time zone NOT NULL,
|
|
10
|
+
effectstream_block_hash BYTEA
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
CREATE TABLE effectstream.rollup_inputs (
|
|
14
|
+
id SERIAL PRIMARY KEY,
|
|
15
|
+
from_address TEXT NOT NULL,
|
|
16
|
+
from_address_type INTEGER NOT NULL,
|
|
17
|
+
input_data TEXT NOT NULL
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
CREATE TABLE effectstream.rollup_input_future_block (
|
|
21
|
+
id INTEGER PRIMARY KEY REFERENCES effectstream.rollup_inputs(id) ON DELETE CASCADE,
|
|
22
|
+
future_block_height INTEGER NOT NULL
|
|
23
|
+
);
|
|
24
|
+
CREATE TABLE effectstream.rollup_input_future_timestamp (
|
|
25
|
+
id INTEGER PRIMARY KEY REFERENCES effectstream.rollup_inputs(id) ON DELETE CASCADE,
|
|
26
|
+
future_ms_timestamp TIMESTAMP without time zone NOT NULL
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
CREATE TABLE effectstream.rollup_input_result (
|
|
30
|
+
id INTEGER PRIMARY KEY REFERENCES effectstream.rollup_inputs(id) ON DELETE CASCADE,
|
|
31
|
+
success BOOLEAN NOT NULL,
|
|
32
|
+
effectstream_tx_hash BYTEA NOT NULL,
|
|
33
|
+
block_height INTEGER NOT NULL REFERENCES effectstream.effectstream_blocks(block_height),
|
|
34
|
+
index_in_block INTEGER NOT NULL
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
CREATE TABLE effectstream.rollup_input_origin (
|
|
38
|
+
id INTEGER PRIMARY KEY REFERENCES effectstream.rollup_inputs(id) ON DELETE CASCADE,
|
|
39
|
+
primitive_name TEXT,
|
|
40
|
+
caip2 TEXT,
|
|
41
|
+
tx_hash BYTEA,
|
|
42
|
+
contract_address TEXT
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
CREATE TABLE effectstream.primitive_accounting (
|
|
46
|
+
primitive_name TEXT NOT NULL,
|
|
47
|
+
id SERIAL,
|
|
48
|
+
effectstream_block_height INTEGER NOT NULL REFERENCES effectstream.effectstream_blocks(block_height),
|
|
49
|
+
payload_type TEXT NOT NULL,
|
|
50
|
+
payload JSON NOT NULL,
|
|
51
|
+
payload_hash TEXT GENERATED ALWAYS AS (md5(payload::text)) STORED,
|
|
52
|
+
PRIMARY KEY (primitive_name, id)
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
CREATE TABLE effectstream.nonces (
|
|
56
|
+
nonce TEXT PRIMARY KEY,
|
|
57
|
+
block_height INTEGER NOT NULL REFERENCES effectstream.effectstream_blocks(block_height)
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
CREATE TABLE effectstream.sync_protocol_pagination (
|
|
61
|
+
protocol_name TEXT NOT NULL,
|
|
62
|
+
page_number INTEGER NOT NULL,
|
|
63
|
+
page JSONB NOT NULL,
|
|
64
|
+
PRIMARY KEY (protocol_name, page_number)
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
CREATE INDEX sync_protocol_pagination_page_number_idx on effectstream.sync_protocol_pagination(protocol_name, page_number);
|
|
68
|
+
|
|
69
|
+
CREATE TABLE effectstream.primitive_config (
|
|
70
|
+
primitive_name TEXT PRIMARY KEY,
|
|
71
|
+
primitive_type TEXT NOT NULL,
|
|
72
|
+
primitive_caip2 TEXT NOT NULL,
|
|
73
|
+
protocol_name TEXT NOT NULL,
|
|
74
|
+
config JSONB NOT NULL,
|
|
75
|
+
config_hash INTEGER NOT NULL,
|
|
76
|
+
parent_name TEXT
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
CREATE TABLE effectstream.accounts (
|
|
80
|
+
id SERIAL PRIMARY KEY,
|
|
81
|
+
primary_address TEXT
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
CREATE TABLE effectstream.addresses (
|
|
85
|
+
address TEXT NOT NULL UNIQUE,
|
|
86
|
+
address_type INTEGER NOT NULL,
|
|
87
|
+
account_id INTEGER REFERENCES effectstream.accounts(id)
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
CREATE INDEX addresses_account_id_idx ON effectstream.addresses(account_id);
|
|
91
|
+
|
|
92
|
+
ALTER TABLE effectstream.accounts ADD CONSTRAINT fk_primary_address_address FOREIGN KEY (primary_address) REFERENCES effectstream.addresses(address);
|
|
93
|
+
|
|
94
|
+
CREATE TABLE effectstream.achievement_progress(
|
|
95
|
+
account_id INTEGER NOT NULL REFERENCES effectstream.accounts(id),
|
|
96
|
+
name TEXT NOT NULL,
|
|
97
|
+
completed_date TIMESTAMP,
|
|
98
|
+
progress INTEGER,
|
|
99
|
+
total INTEGER,
|
|
100
|
+
PRIMARY KEY (account_id, name)
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
CREATE TABLE effectstream.event (
|
|
104
|
+
id SERIAL PRIMARY KEY,
|
|
105
|
+
topic TEXT NOT NULL,
|
|
106
|
+
address TEXT NOT NULL,
|
|
107
|
+
data JSONB NOT NULL,
|
|
108
|
+
block_height INTEGER NOT NULL,
|
|
109
|
+
tx_index INTEGER NOT NULL,
|
|
110
|
+
log_index INTEGER NOT NULL
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
CREATE TABLE effectstream.registered_event (
|
|
114
|
+
name TEXT NOT NULL,
|
|
115
|
+
topic TEXT NOT NULL,
|
|
116
|
+
PRIMARY KEY(name, topic)
|
|
117
|
+
);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
-- Enforce uniqueness for migration history entries
|
|
2
|
+
CREATE UNIQUE INDEX IF NOT EXISTS effectstream_migration_history_unique_name_system
|
|
3
|
+
ON effectstream.effectstream_migration_history (name, is_system_migration);
|
|
4
|
+
|
|
5
|
+
-- Add idempotency support for primitive accounting entries
|
|
6
|
+
DO $$
|
|
7
|
+
BEGIN
|
|
8
|
+
IF NOT EXISTS (
|
|
9
|
+
SELECT 1
|
|
10
|
+
FROM information_schema.columns
|
|
11
|
+
WHERE table_schema = 'effectstream'
|
|
12
|
+
AND table_name = 'primitive_accounting'
|
|
13
|
+
AND column_name = 'payload_hash'
|
|
14
|
+
) THEN
|
|
15
|
+
ALTER TABLE effectstream.primitive_accounting
|
|
16
|
+
ADD COLUMN payload_hash TEXT GENERATED ALWAYS AS (md5(payload::text)) STORED;
|
|
17
|
+
END IF;
|
|
18
|
+
END
|
|
19
|
+
$$;
|
|
20
|
+
|
|
21
|
+
CREATE UNIQUE INDEX IF NOT EXISTS primitive_accounting_unique_payload_per_block
|
|
22
|
+
ON effectstream.primitive_accounting (primitive_name, effectstream_block_height, payload_hash);
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import type { Client } from "pg";
|
|
2
|
+
import type { Operation } from "effection";
|
|
3
|
+
import { until } from "effection";
|
|
4
|
+
import * as migrationFiles from "./assets.ts";
|
|
5
|
+
import {
|
|
6
|
+
acquireDBMutex,
|
|
7
|
+
getLatestProcessedBlockHeight,
|
|
8
|
+
getLatestVersion,
|
|
9
|
+
releaseDBMutex,
|
|
10
|
+
tableExists,
|
|
11
|
+
} from "@effectstream/db";
|
|
12
|
+
type VERSION = `${number}.${number}.${number}`;
|
|
13
|
+
type VERSION_NUMBER = [number, number, number];
|
|
14
|
+
// NOTE This must match the version of the root deno.json
|
|
15
|
+
export const EFFECTSTREAM_ENGINE_VERSION: VERSION = "0.8.1";
|
|
16
|
+
|
|
17
|
+
export { applyMigrations } from "../scripts/apply-migrations.ts";
|
|
18
|
+
|
|
19
|
+
export function parseVersion(version: VERSION): VERSION_NUMBER {
|
|
20
|
+
const parts = version.split(".").map((part) => Number(part));
|
|
21
|
+
if (parts.length !== 3 || parts.some((n) => Number.isNaN(n))) {
|
|
22
|
+
throw new Error(`Invalid version string: ${version}`);
|
|
23
|
+
}
|
|
24
|
+
const [major, minor, patch] = parts;
|
|
25
|
+
return [major, minor, patch];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export async function getMigrations(
|
|
29
|
+
from_version: VERSION | undefined = undefined,
|
|
30
|
+
to_version: VERSION = EFFECTSTREAM_ENGINE_VERSION,
|
|
31
|
+
): Promise<{
|
|
32
|
+
version: VERSION;
|
|
33
|
+
sql: string;
|
|
34
|
+
}[]> {
|
|
35
|
+
const toVersion: VERSION_NUMBER = parseVersion(to_version);
|
|
36
|
+
const fromVersion: VERSION_NUMBER | undefined = from_version
|
|
37
|
+
? parseVersion(from_version)
|
|
38
|
+
: undefined;
|
|
39
|
+
|
|
40
|
+
const upMigrations: { version: VERSION_NUMBER; sql: string }[] = [];
|
|
41
|
+
Object.entries(migrationFiles.default.files).map(([key, value]) => {
|
|
42
|
+
const [s, type, v, major, minor, patch] = key.split("-");
|
|
43
|
+
if (s === "system" && type === "up" && v === "v") {
|
|
44
|
+
upMigrations.push({
|
|
45
|
+
version: [
|
|
46
|
+
parseInt(major, 10),
|
|
47
|
+
parseInt(minor, 10),
|
|
48
|
+
parseInt(patch, 10),
|
|
49
|
+
],
|
|
50
|
+
sql: new TextDecoder().decode(value.content),
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const filteredAndSorted = upMigrations
|
|
56
|
+
.filter((migration) => {
|
|
57
|
+
return (
|
|
58
|
+
(!fromVersion || (
|
|
59
|
+
// Return all migrations that are greater to the from version
|
|
60
|
+
migration.version[0] > fromVersion[0] ||
|
|
61
|
+
(migration.version[0] === fromVersion[0] &&
|
|
62
|
+
migration.version[1] > fromVersion[1]) ||
|
|
63
|
+
(migration.version[0] === fromVersion[0] &&
|
|
64
|
+
migration.version[1] === fromVersion[1] &&
|
|
65
|
+
migration.version[2] > fromVersion[2])
|
|
66
|
+
)) &&
|
|
67
|
+
// Return all migrations that are less or equal to the target version
|
|
68
|
+
(
|
|
69
|
+
migration.version[0] < toVersion[0] ||
|
|
70
|
+
(migration.version[0] === toVersion[0] &&
|
|
71
|
+
migration.version[1] < toVersion[1]) ||
|
|
72
|
+
(migration.version[0] === toVersion[0] &&
|
|
73
|
+
migration.version[1] === toVersion[1] &&
|
|
74
|
+
migration.version[2] <= toVersion[2])
|
|
75
|
+
)
|
|
76
|
+
);
|
|
77
|
+
})
|
|
78
|
+
.sort((a, b) => {
|
|
79
|
+
// Sort from oldest to newest
|
|
80
|
+
return (
|
|
81
|
+
a.version[0] - b.version[0] ||
|
|
82
|
+
a.version[1] - b.version[1] ||
|
|
83
|
+
a.version[2] - b.version[2]
|
|
84
|
+
);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
return filteredAndSorted.map((migration) => ({
|
|
88
|
+
version: `${migration.version[0]}.${migration.version[1]}.${
|
|
89
|
+
migration.version[2]
|
|
90
|
+
}`,
|
|
91
|
+
sql: migration.sql,
|
|
92
|
+
}));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export type VersionInfo = {
|
|
96
|
+
engine_current_version: VERSION;
|
|
97
|
+
engine_previous_version: VERSION;
|
|
98
|
+
app_previous_version: VERSION;
|
|
99
|
+
is_empty: boolean;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
export function* getLastBlockHeight(
|
|
103
|
+
versionInfo: VersionInfo,
|
|
104
|
+
dbConn: Client,
|
|
105
|
+
): Operation<number> {
|
|
106
|
+
yield* acquireDBMutex("get-last-block-height");
|
|
107
|
+
const v = versionInfo.is_empty
|
|
108
|
+
? 0
|
|
109
|
+
: (yield* until(getLatestProcessedBlockHeight.run(undefined, dbConn)))[0]
|
|
110
|
+
.block_height;
|
|
111
|
+
releaseDBMutex("get-last-block-height");
|
|
112
|
+
return v;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function* getVersionInfo(dbConn: Client): Operation<VersionInfo> {
|
|
116
|
+
// 1. Let's check if the database is empty.
|
|
117
|
+
yield* acquireDBMutex("get-version-info");
|
|
118
|
+
const [result] = yield* until(tableExists.run(undefined, dbConn));
|
|
119
|
+
releaseDBMutex("get-version-info");
|
|
120
|
+
|
|
121
|
+
if (!result.exists) {
|
|
122
|
+
return {
|
|
123
|
+
engine_current_version: EFFECTSTREAM_ENGINE_VERSION,
|
|
124
|
+
engine_previous_version: "0.0.0",
|
|
125
|
+
app_previous_version: "0.0.0",
|
|
126
|
+
is_empty: true,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// So let's check what is the latest version from the `effectstream_version_history` table.
|
|
131
|
+
yield* acquireDBMutex("get-version-info");
|
|
132
|
+
const [latestVersion] = yield* until(getLatestVersion.run(undefined, dbConn));
|
|
133
|
+
releaseDBMutex("get-version-info");
|
|
134
|
+
|
|
135
|
+
if (!latestVersion) {
|
|
136
|
+
throw new Error("Internal error: No version found in the database");
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
engine_current_version: EFFECTSTREAM_ENGINE_VERSION,
|
|
141
|
+
engine_previous_version:
|
|
142
|
+
`${latestVersion.engine_version_major}.${latestVersion.engine_version_minor}.${latestVersion.engine_version_patch}`,
|
|
143
|
+
app_previous_version:
|
|
144
|
+
`${latestVersion.app_version_major}.${latestVersion.app_version_minor}.${latestVersion.app_version_patch}`,
|
|
145
|
+
is_empty: false,
|
|
146
|
+
};
|
|
147
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@effectstream/db",
|
|
3
|
+
"version": "0.100.0",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"exports": {
|
|
6
|
+
".": "./src/mod.ts",
|
|
7
|
+
"./start-pglite": "./scripts/start-pglite.ts",
|
|
8
|
+
"./apply-migrations": "./scripts/apply-migrations.ts",
|
|
9
|
+
"./db-up": "./scripts/start-pglite.ts",
|
|
10
|
+
"./db-wait": "./scripts/wait-for-db.ts",
|
|
11
|
+
"./pgtyped-update": "./scripts/pgtyped-update.ts",
|
|
12
|
+
"./version": "./migrations/system-version.ts"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@effectstream/coroutine": "0.100.0",
|
|
16
|
+
"@effectstream/log": "0.100.0",
|
|
17
|
+
"@effectstream/runtime": "0.100.0",
|
|
18
|
+
"@effectstream/sync": "0.100.0",
|
|
19
|
+
"@effectstream/utils": "0.100.0",
|
|
20
|
+
"@electric-sql/pglite": "^0.3.14",
|
|
21
|
+
"@pgtyped/runtime": "2.4.2",
|
|
22
|
+
"@pgtyped/parser": "2.4.2",
|
|
23
|
+
"pg": "8.17.2",
|
|
24
|
+
"pg-tx": "^1.0.1",
|
|
25
|
+
"effection": "^3.5.0",
|
|
26
|
+
"pg-gateway": "^0.3.0-beta.4"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@paima/pgtyped-cli": "^2.4.5",
|
|
30
|
+
"wait-on": "8.0.3",
|
|
31
|
+
"concurrently": "9.1.2"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"transforms": [
|
|
3
|
+
{
|
|
4
|
+
"mode": "sql",
|
|
5
|
+
"include": "**/*.sql",
|
|
6
|
+
"emitTemplate": "{{dir}}/{{name}}.queries.ts"
|
|
7
|
+
}
|
|
8
|
+
],
|
|
9
|
+
"srcDir": "./src/sql",
|
|
10
|
+
"failOnError": false,
|
|
11
|
+
"camelCaseColumnNames": false,
|
|
12
|
+
"db": {
|
|
13
|
+
"dbName": "postgres",
|
|
14
|
+
"user": "postgres",
|
|
15
|
+
"password": "postgres",
|
|
16
|
+
"host": "localhost",
|
|
17
|
+
"port": 5432,
|
|
18
|
+
"ssl": false
|
|
19
|
+
},
|
|
20
|
+
"maxWorkerThreads": 1
|
|
21
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
FROM postgres:15.9 AS builder
|
|
2
|
+
|
|
3
|
+
RUN apt-get update && apt-get -y install git postgresql-server-dev-15 build-essential && rm -rf /var/lib/apt/lists/*
|
|
4
|
+
|
|
5
|
+
RUN git clone https://github.com/sraoss/pg_ivm
|
|
6
|
+
WORKDIR /pg_ivm
|
|
7
|
+
|
|
8
|
+
RUN git checkout v1.11
|
|
9
|
+
RUN make
|
|
10
|
+
RUN make DESTDIR=/pg_ivm/output install
|
|
11
|
+
|
|
12
|
+
FROM postgres:15.9
|
|
13
|
+
COPY --from=builder /pg_ivm/output /
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { getConnection } from "../src/pg-connection.ts";
|
|
2
|
+
import { getMigrations } from "../migrations/system-version.ts";
|
|
3
|
+
import type { Client } from "pg";
|
|
4
|
+
import { insertPaimaEngineMigration } from "@effectstream/db";
|
|
5
|
+
|
|
6
|
+
export async function applyMigrations(
|
|
7
|
+
db: Client,
|
|
8
|
+
blockHeight: number,
|
|
9
|
+
name: string,
|
|
10
|
+
sql: string,
|
|
11
|
+
isSystemMigration: boolean,
|
|
12
|
+
) {
|
|
13
|
+
console.log(
|
|
14
|
+
`[APPLY MIGRATION] Block height: ${blockHeight} | Migration: ${name}`,
|
|
15
|
+
);
|
|
16
|
+
await db.query(sql);
|
|
17
|
+
await insertPaimaEngineMigration.run(
|
|
18
|
+
{
|
|
19
|
+
name,
|
|
20
|
+
blockHeight,
|
|
21
|
+
isSystemMigration,
|
|
22
|
+
},
|
|
23
|
+
db,
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Functions for standalone execution
|
|
28
|
+
async function standAloneApplyInitialMigrations(
|
|
29
|
+
db: any, // Client,
|
|
30
|
+
blockHeight: number,
|
|
31
|
+
) {
|
|
32
|
+
const migrations = await getMigrations();
|
|
33
|
+
for (const migration of migrations) {
|
|
34
|
+
await applyMigrations(
|
|
35
|
+
db,
|
|
36
|
+
blockHeight,
|
|
37
|
+
migration.version,
|
|
38
|
+
migration.sql,
|
|
39
|
+
true,
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (import.meta.main) {
|
|
45
|
+
const db = await getConnection();
|
|
46
|
+
await standAloneApplyInitialMigrations(db, 0);
|
|
47
|
+
console.log("✅ System migrations applied");
|
|
48
|
+
process.exit(0);
|
|
49
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import { spawn } from "node:child_process";
|
|
3
|
+
import { waitForDb } from "./wait-for-db.ts";
|
|
4
|
+
import { dirname, join } from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
|
|
7
|
+
async function runPgtyped() {
|
|
8
|
+
try {
|
|
9
|
+
console.log("🔄 Running pgtyped...");
|
|
10
|
+
const __dirname = dirname(import.meta.url?.startsWith("file:") ? fileURLToPath(import.meta.url) : import.meta.url.replace("file://", ""));
|
|
11
|
+
const configPath = join(__dirname, "../pgtypedconfig.json");
|
|
12
|
+
const child = spawn("npx", ["pgtyped", "-c", configPath], {
|
|
13
|
+
stdio: "inherit",
|
|
14
|
+
shell: true,
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const code = await new Promise<number | null>((resolve) => {
|
|
18
|
+
child.on("close", (code) => resolve(code));
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
if (code === 0) {
|
|
22
|
+
console.log("✅ pgtyped completed successfully");
|
|
23
|
+
} else {
|
|
24
|
+
console.error("❌ pgtyped failed");
|
|
25
|
+
process.exit(code ?? 1);
|
|
26
|
+
}
|
|
27
|
+
} catch (error) {
|
|
28
|
+
console.error("❌ Error running pgtyped:", error);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async function main() {
|
|
34
|
+
// First wait for the database
|
|
35
|
+
await waitForDb();
|
|
36
|
+
|
|
37
|
+
// Then run pgtyped
|
|
38
|
+
await runPgtyped();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (import.meta.main) {
|
|
42
|
+
await main();
|
|
43
|
+
}
|