envio 3.11.0 → 3.12.1
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/index.d.ts +3 -0
- package/package.json +6 -6
- package/src/Batch.res +111 -78
- package/src/Batch.res.mjs +53 -46
- package/src/BatchProcessing.res +1 -11
- package/src/BatchProcessing.res.mjs +1 -4
- package/src/ChainFetching.res +7 -3
- package/src/ChainFetching.res.mjs +1 -1
- package/src/ChainState.res +82 -20
- package/src/ChainState.res.mjs +51 -13
- package/src/ChainState.resi +6 -1
- package/src/Config.res +58 -37
- package/src/Config.res.mjs +63 -53
- package/src/CrossChainState.res +50 -53
- package/src/CrossChainState.res.mjs +25 -23
- package/src/CrossChainState.resi +6 -13
- package/src/EffectState.res +13 -4
- package/src/EffectState.resi +7 -1
- package/src/EventProcessing.res +6 -6
- package/src/EventProcessing.res.mjs +6 -6
- package/src/FetchState.res +65 -46
- package/src/FetchState.res.mjs +68 -36
- package/src/FinalizeBackfill.res +16 -12
- package/src/FinalizeBackfill.res.mjs +3 -3
- package/src/HistoryPolicy.res +46 -0
- package/src/HistoryPolicy.res.mjs +50 -0
- package/src/InMemoryStore.res +30 -32
- package/src/InMemoryStore.res.mjs +33 -28
- package/src/InMemoryTable.res +155 -67
- package/src/InMemoryTable.res.mjs +151 -60
- package/src/IndexerState.res +66 -45
- package/src/IndexerState.res.mjs +57 -29
- package/src/IndexerState.resi +8 -13
- package/src/Internal.res +4 -2
- package/src/LoadLayer.res +68 -38
- package/src/LoadLayer.res.mjs +50 -64
- package/src/LoadLayer.resi +1 -1
- package/src/Main.res +25 -24
- package/src/Main.res.mjs +24 -25
- package/src/Metrics.res +49 -1
- package/src/Metrics.res.mjs +26 -3
- package/src/Persistence.res +55 -16
- package/src/Persistence.res.mjs +18 -3
- package/src/PgStorage.res +286 -180
- package/src/PgStorage.res.mjs +209 -122
- package/src/PruneStaleHistory.res +9 -15
- package/src/PruneStaleHistory.res.mjs +11 -20
- package/src/Rollback.res +9 -14
- package/src/Rollback.res.mjs +5 -3
- package/src/Sink.res +7 -5
- package/src/Sink.res.mjs +4 -4
- package/src/Staging.res +298 -0
- package/src/Staging.res.mjs +257 -0
- package/src/TestIndexer.res +14 -30
- package/src/TestIndexer.res.mjs +11 -9
- package/src/UserContext.res +20 -36
- package/src/UserContext.res.mjs +6 -9
- package/src/Utils.res +10 -4
- package/src/Utils.res.mjs +16 -16
- package/src/Writing.res +34 -20
- package/src/Writing.res.mjs +15 -20
- package/src/bindings/ClickHouse.res +41 -34
- package/src/bindings/ClickHouse.res.mjs +36 -30
- package/src/bindings/ClickHouseSink.res +45 -186
- package/src/bindings/ClickHouseSink.res.mjs +21 -174
- package/src/db/CheckpointSequence.res +109 -0
- package/src/db/CheckpointSequence.res.mjs +99 -0
- package/src/db/EntityFilter.res +487 -275
- package/src/db/EntityFilter.res.mjs +557 -309
- package/src/db/EntityHistory.res +6 -5
- package/src/db/EntityHistory.res.mjs +5 -5
- package/src/db/Frontier.res +86 -0
- package/src/db/Frontier.res.mjs +126 -0
- package/src/db/InternalTable.res +145 -27
- package/src/db/InternalTable.res.mjs +115 -29
- package/src/db/RollbackFloors.res +34 -41
- package/src/db/RollbackFloors.res.mjs +27 -71
- package/src/db/Table.res +21 -6
- package/src/db/Table.res.mjs +13 -4
- package/src/sources/BlockStore.res +8 -0
- package/src/sources/EvmHyperSyncSource.res +5 -1
- package/src/sources/EvmHyperSyncSource.res.mjs +4 -3
- package/src/sources/FuelHyperSyncSource.res +1 -0
- package/src/sources/FuelHyperSyncSource.res.mjs +1 -1
- package/src/sources/HyperSync.res +6 -0
- package/src/sources/HyperSync.res.mjs +5 -2
- package/src/sources/HyperSync.resi +2 -0
- package/src/sources/HyperSyncClient.res +6 -0
- package/src/sources/HyperSyncSSE.res +1 -1
- package/src/sources/HyperSyncSSE.res.mjs +4 -10
- package/src/sources/RequestStat.res +8 -1
- package/src/sources/RpcSource.res +1 -0
- package/src/sources/RpcSource.res.mjs +1 -1
- package/src/sources/SimulateSource.res +1 -0
- package/src/sources/SimulateSource.res.mjs +1 -1
- package/src/sources/Source.res +11 -3
- package/src/sources/SourceManager.res +34 -13
- package/src/sources/SourceManager.res.mjs +26 -9
- package/src/sources/SourceManager.resi +2 -0
- package/src/sources/SvmHyperSyncClient.res +5 -0
- package/src/sources/SvmHyperSyncSource.res +3 -0
- package/src/sources/SvmHyperSyncSource.res.mjs +4 -2
- package/src/tui/Tui.res +56 -143
- package/src/tui/Tui.res.mjs +70 -166
- package/src/tui/components/TuiData.res +61 -16
- package/src/tui/components/TuiData.res.mjs +53 -15
- package/svm.schema.json +0 -7
- package/src/db/CheckpointBounds.res +0 -53
- package/src/db/CheckpointBounds.res.mjs +0 -44
package/src/PgStorage.res.mjs
CHANGED
|
@@ -12,16 +12,19 @@ import * as Schema from "./db/Schema.res.mjs";
|
|
|
12
12
|
import * as ChainId from "./ChainId.res.mjs";
|
|
13
13
|
import * as Logging from "./Logging.res.mjs";
|
|
14
14
|
import * as EntityId from "./EntityId.res.mjs";
|
|
15
|
+
import * as Frontier from "./db/Frontier.res.mjs";
|
|
15
16
|
import * as Internal from "./Internal.res.mjs";
|
|
16
17
|
import Postgres from "postgres";
|
|
17
18
|
import * as ChainState from "./ChainState.res.mjs";
|
|
18
19
|
import * as AddressRows from "./AddressRows.res.mjs";
|
|
19
20
|
import * as Performance from "./bindings/Performance.res.mjs";
|
|
20
21
|
import * as Persistence from "./Persistence.res.mjs";
|
|
22
|
+
import * as EntityFilter from "./db/EntityFilter.res.mjs";
|
|
21
23
|
import * as IndexCatalog from "./db/IndexCatalog.res.mjs";
|
|
22
24
|
import * as IndexManager from "./db/IndexManager.res.mjs";
|
|
23
25
|
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
24
26
|
import * as EntityHistory from "./db/EntityHistory.res.mjs";
|
|
27
|
+
import * as HistoryPolicy from "./HistoryPolicy.res.mjs";
|
|
25
28
|
import * as InternalTable from "./db/InternalTable.res.mjs";
|
|
26
29
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
27
30
|
import * as Child_process from "child_process";
|
|
@@ -29,10 +32,10 @@ import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
|
|
|
29
32
|
import * as Stdlib_Promise from "@rescript/runtime/lib/es6/Stdlib_Promise.js";
|
|
30
33
|
import * as ContractMapping from "./ContractMapping.res.mjs";
|
|
31
34
|
import * as IndexDefinition from "./db/IndexDefinition.res.mjs";
|
|
32
|
-
import * as CheckpointBounds from "./db/CheckpointBounds.res.mjs";
|
|
33
35
|
import * as Primitive_object from "@rescript/runtime/lib/es6/Primitive_object.js";
|
|
34
36
|
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
35
37
|
import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
|
|
38
|
+
import * as CheckpointSequence from "./db/CheckpointSequence.res.mjs";
|
|
36
39
|
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
37
40
|
|
|
38
41
|
function makeClient() {
|
|
@@ -57,7 +60,25 @@ function formatSeconds(timeRef) {
|
|
|
57
60
|
|
|
58
61
|
let slowOnLargeDatabaseNotice = "This can take a long time on a large database.";
|
|
59
62
|
|
|
60
|
-
function
|
|
63
|
+
function partitionTableName(entityConfig, chainId) {
|
|
64
|
+
let chainIdStr = ChainId.toString(chainId);
|
|
65
|
+
return Table.fitPgTableName(entityConfig.table.tableName + `$` + chainIdStr, `$` + entityConfig.index.toString() + `$` + chainIdStr);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function indexTableNames(entityConfig, partitionChainIds) {
|
|
69
|
+
let match = Table.getChainIdField(entityConfig.table);
|
|
70
|
+
if (match !== undefined) {
|
|
71
|
+
if (partitionChainIds !== undefined) {
|
|
72
|
+
return partitionChainIds.map(chainId => partitionTableName(entityConfig, chainId));
|
|
73
|
+
} else {
|
|
74
|
+
return [entityConfig.table.tableName];
|
|
75
|
+
}
|
|
76
|
+
} else {
|
|
77
|
+
return [entityConfig.table.tableName];
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function getSchemaIndexes(entities, partitionChainIds) {
|
|
61
82
|
let derivedSchema = Schema.make(entities.map(e => e.table));
|
|
62
83
|
let all = [];
|
|
63
84
|
entities.forEach(param => {
|
|
@@ -76,6 +97,10 @@ function getSchemaIndexes(entities) {
|
|
|
76
97
|
});
|
|
77
98
|
});
|
|
78
99
|
let seen = new Set();
|
|
100
|
+
let entityByTableName = {};
|
|
101
|
+
entities.forEach(entityConfig => {
|
|
102
|
+
entityByTableName[entityConfig.table.tableName] = entityConfig;
|
|
103
|
+
});
|
|
79
104
|
return all.filter(definition => {
|
|
80
105
|
let key = IndexDefinition.key(definition);
|
|
81
106
|
if (seen.has(key)) {
|
|
@@ -84,7 +109,11 @@ function getSchemaIndexes(entities) {
|
|
|
84
109
|
seen.add(key);
|
|
85
110
|
return true;
|
|
86
111
|
}
|
|
87
|
-
})
|
|
112
|
+
}).flatMap(definition => indexTableNames(Stdlib_Option.getOrThrow(entityByTableName[definition.tableName], undefined), partitionChainIds).map(tableName => ({
|
|
113
|
+
tableName: tableName,
|
|
114
|
+
columns: definition.columns,
|
|
115
|
+
method: definition.method
|
|
116
|
+
})));
|
|
88
117
|
}
|
|
89
118
|
|
|
90
119
|
function makeCreateTableQuery(table, pgSchema, isNumericArrayAsText, chainIdModeOpt, partitionByColumn) {
|
|
@@ -108,11 +137,6 @@ function makeCreateTableQuery(table, pgSchema, isNumericArrayAsText, chainIdMode
|
|
|
108
137
|
) + `;`;
|
|
109
138
|
}
|
|
110
139
|
|
|
111
|
-
function partitionTableName(entityConfig, chainId) {
|
|
112
|
-
let chainIdStr = ChainId.toString(chainId);
|
|
113
|
-
return Table.fitPgTableName(entityConfig.table.tableName + `$` + chainIdStr, `$` + entityConfig.index.toString() + `$` + chainIdStr);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
140
|
let rowSchemaCache = new WeakMap();
|
|
117
141
|
|
|
118
142
|
function getRowSchema(entityConfig) {
|
|
@@ -228,7 +252,7 @@ function makeCreateEntityTableQueries(entityConfig, pgSchema, isNumericArrayAsTe
|
|
|
228
252
|
).concat([createTable(getEntityHistory(entityConfig).table, undefined)]);
|
|
229
253
|
}
|
|
230
254
|
|
|
231
|
-
function makeInitializeTransaction(pgSchema, pgUser, isHasuraEnabled, chainConfigsOpt, entitiesOpt, enumsOpt, isEmptyPgSchemaOpt, deferSchemaIndexesOpt, chainIdModeOpt) {
|
|
255
|
+
function makeInitializeTransaction(pgSchema, pgUser, isHasuraEnabled, checkpointSequence, chainConfigsOpt, entitiesOpt, enumsOpt, isEmptyPgSchemaOpt, deferSchemaIndexesOpt, chainIdModeOpt) {
|
|
232
256
|
let chainConfigs = chainConfigsOpt !== undefined ? chainConfigsOpt : [];
|
|
233
257
|
let entities = entitiesOpt !== undefined ? entitiesOpt : [];
|
|
234
258
|
let enums = enumsOpt !== undefined ? enumsOpt : [];
|
|
@@ -240,12 +264,12 @@ function makeInitializeTransaction(pgSchema, pgUser, isHasuraEnabled, chainConfi
|
|
|
240
264
|
InternalTable.EnvioInfo.table,
|
|
241
265
|
InternalTable.EnvioContracts.table,
|
|
242
266
|
InternalTable.EnvioAddresses.table,
|
|
243
|
-
InternalTable.Checkpoints.
|
|
267
|
+
InternalTable.Checkpoints.tableFor(checkpointSequence),
|
|
244
268
|
InternalTable.RawEvents.table
|
|
245
269
|
];
|
|
246
270
|
let chainIds = chainConfigs.map(chainConfig => chainConfig.id);
|
|
247
271
|
let tableQueries = generalTables.map(table => makeCreateTableQuery(table, pgSchema, isHasuraEnabled, chainIdMode, undefined)).concat(entities.flatMap(entityConfig => makeCreateEntityTableQueries(entityConfig, pgSchema, isHasuraEnabled, chainIdMode, chainIds)));
|
|
248
|
-
let schemaIndexes = getSchemaIndexes(entities);
|
|
272
|
+
let schemaIndexes = getSchemaIndexes(entities, undefined);
|
|
249
273
|
let query = {
|
|
250
274
|
contents: (
|
|
251
275
|
isEmptyPgSchema && pgSchema === "public" ? `CREATE SCHEMA IF NOT EXISTS "` + pgSchema + `";\n` : `DROP SCHEMA IF EXISTS "` + pgSchema + `" CASCADE;
|
|
@@ -278,7 +302,7 @@ function makeLoadQuery(pgSchema, tableName, condition) {
|
|
|
278
302
|
return `SELECT * FROM "` + pgSchema + `"."` + tableName + `" WHERE ` + condition + `;`;
|
|
279
303
|
}
|
|
280
304
|
|
|
281
|
-
function makeFilterCondition(filter, table, params) {
|
|
305
|
+
function makeFilterCondition(filter, table, pgSchema, params) {
|
|
282
306
|
let getQueryFieldOrThrow = fieldName => {
|
|
283
307
|
let queryField = Table.queryFields(table)[fieldName];
|
|
284
308
|
if (queryField !== undefined) {
|
|
@@ -310,39 +334,76 @@ function makeFilterCondition(filter, table, params) {
|
|
|
310
334
|
params.push(param);
|
|
311
335
|
return `$` + params.length.toString();
|
|
312
336
|
};
|
|
313
|
-
let
|
|
314
|
-
|
|
315
|
-
return `"` + queryField.pgDbFieldName + `" ` + op + ` ` + serializeParamOrThrow(queryField, fieldName, fieldValue, false);
|
|
337
|
+
let condition = {
|
|
338
|
+
contents: ""
|
|
316
339
|
};
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
let
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
340
|
+
Utils.Dict.forEachWithKey(EntityFilter.entries(filter), (operators, fieldName) => {
|
|
341
|
+
let queryField = getQueryFieldOrThrow(fieldName);
|
|
342
|
+
Utils.Dict.forEachWithKey(operators, (fieldValue, operator) => {
|
|
343
|
+
let column = `"` + queryField.pgDbFieldName + `"`;
|
|
344
|
+
let part;
|
|
345
|
+
let exit = 0;
|
|
346
|
+
switch (operator) {
|
|
347
|
+
case "_eq" :
|
|
348
|
+
if (queryField.isChainId) {
|
|
349
|
+
part = column + ` = ` + ChainId.toString(ChainId.normalizeOrThrow(fieldValue));
|
|
350
|
+
} else {
|
|
351
|
+
exit = 1;
|
|
352
|
+
}
|
|
353
|
+
break;
|
|
354
|
+
case "_in" :
|
|
355
|
+
if (queryField.isArray || queryField.fieldType === "Boolean") {
|
|
356
|
+
let candidates = EntityFilter.asArray(fieldValue);
|
|
357
|
+
part = candidates.length !== 0 ? `(` + candidates.map(candidate => column + ` = ` + serializeParamOrThrow(queryField, fieldName, candidate, false)).join(" OR ") + `)` : "FALSE";
|
|
358
|
+
} else {
|
|
359
|
+
let param = serializeParamOrThrow(queryField, fieldName, fieldValue, true);
|
|
360
|
+
let match = queryField.fieldType;
|
|
361
|
+
let exit$1 = 0;
|
|
362
|
+
if (typeof match !== "object" || match.type !== "Enum") {
|
|
363
|
+
exit$1 = 2;
|
|
364
|
+
} else {
|
|
365
|
+
part = column + ` = ANY(` + param + `::TEXT[]::"` + pgSchema + `".` + match.config.name + `[])`;
|
|
366
|
+
}
|
|
367
|
+
if (exit$1 === 2) {
|
|
368
|
+
part = column + ` = ANY(` + param + `)`;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
break;
|
|
372
|
+
default:
|
|
373
|
+
exit = 1;
|
|
325
374
|
}
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
375
|
+
if (exit === 1) {
|
|
376
|
+
let sqlOperator;
|
|
377
|
+
switch (operator) {
|
|
378
|
+
case "_eq" :
|
|
379
|
+
sqlOperator = "=";
|
|
380
|
+
break;
|
|
381
|
+
case "_gt" :
|
|
382
|
+
sqlOperator = ">";
|
|
383
|
+
break;
|
|
384
|
+
case "_gte" :
|
|
385
|
+
sqlOperator = ">=";
|
|
386
|
+
break;
|
|
387
|
+
case "_lt" :
|
|
388
|
+
sqlOperator = "<";
|
|
389
|
+
break;
|
|
390
|
+
case "_lte" :
|
|
391
|
+
sqlOperator = "<=";
|
|
392
|
+
break;
|
|
393
|
+
default:
|
|
394
|
+
throw {
|
|
395
|
+
RE_EXN_ID: Persistence.StorageError,
|
|
396
|
+
message: `Failed loading "` + table.tableName + `" from storage. Unknown filter operator "` + operator + `".`,
|
|
397
|
+
reason: new Error(`Unknown filter operator "` + operator + `"`),
|
|
398
|
+
Error: new Error()
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
part = column + ` ` + sqlOperator + ` ` + serializeParamOrThrow(queryField, fieldName, fieldValue, false);
|
|
338
402
|
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
Error: new Error()
|
|
344
|
-
};
|
|
345
|
-
}
|
|
403
|
+
condition.contents = condition.contents === "" ? part : condition.contents + " AND " + part;
|
|
404
|
+
});
|
|
405
|
+
});
|
|
406
|
+
return condition.contents;
|
|
346
407
|
}
|
|
347
408
|
|
|
348
409
|
function makeChainIdCondition(table, chainId) {
|
|
@@ -687,10 +748,29 @@ function executeSet(sql, items, dbFunction) {
|
|
|
687
748
|
}
|
|
688
749
|
}
|
|
689
750
|
|
|
690
|
-
|
|
751
|
+
function pickCheckpoints(column, picked) {
|
|
752
|
+
if (typeof picked !== "object") {
|
|
753
|
+
return column;
|
|
754
|
+
} else {
|
|
755
|
+
return picked._0.map(index => column[index]);
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
async function writeBatch(sql, batch, pgSchema, rollback, config, allEntities, setEffectCacheOrThrow, setQueryCache, updatedEffectsCache, updatedEntities, registeredAddresses, sinkPromise, chainMetaData, escapeTables) {
|
|
691
760
|
try {
|
|
692
761
|
let chainIdMode = config.chainIdMode;
|
|
693
|
-
let
|
|
762
|
+
let indexes = Stdlib_Array.filterMapWithIndex(batch.checkpointChainIds, (chainId, index) => {
|
|
763
|
+
if (HistoryPolicy.forChain(batch.history, chainId)) {
|
|
764
|
+
return index;
|
|
765
|
+
}
|
|
766
|
+
});
|
|
767
|
+
let pickedCheckpoints = Utils.$$Array.isEmpty(indexes) ? undefined : (
|
|
768
|
+
indexes.length === batch.checkpointIds.length ? "AllCheckpoints" : ({
|
|
769
|
+
TAG: "CheckpointIndexes",
|
|
770
|
+
_0: indexes
|
|
771
|
+
})
|
|
772
|
+
);
|
|
773
|
+
let writtenFrontier = Persistence.writtenFrontier(batch, rollback);
|
|
694
774
|
let specificError = {
|
|
695
775
|
contents: undefined
|
|
696
776
|
};
|
|
@@ -725,6 +805,7 @@ async function writeBatch(sql, batch, pgSchema, rollback, isInReorgThreshold, co
|
|
|
725
805
|
}
|
|
726
806
|
};
|
|
727
807
|
let setEntities = updatedEntities.map(param => {
|
|
808
|
+
let shouldSaveHistory = param.shouldSaveHistory;
|
|
728
809
|
let changes = param.changes;
|
|
729
810
|
let scope = param.scope;
|
|
730
811
|
let entityConfig = param.entityConfig;
|
|
@@ -732,7 +813,6 @@ async function writeBatch(sql, batch, pgSchema, rollback, isInReorgThreshold, co
|
|
|
732
813
|
let idsToDelete = [];
|
|
733
814
|
let scopeChainId;
|
|
734
815
|
scopeChainId = scope === "crossChain" ? undefined : Primitive_option.some(scope);
|
|
735
|
-
let shouldSaveHistory = Config.shouldSaveHistory(config, isInReorgThreshold, scopeChainId);
|
|
736
816
|
let match = Table.getChainIdField(entityConfig.table);
|
|
737
817
|
let changes$1;
|
|
738
818
|
if (match !== undefined && scopeChainId !== undefined) {
|
|
@@ -756,7 +836,7 @@ async function writeBatch(sql, batch, pgSchema, rollback, isInReorgThreshold, co
|
|
|
756
836
|
let chainIdParams = match$1 !== undefined ? (
|
|
757
837
|
scopeChainId !== undefined ? [Primitive_option.valFromOption(scopeChainId)] : []
|
|
758
838
|
) : [];
|
|
759
|
-
let diffCheckpointId = Stdlib_Option.
|
|
839
|
+
let diffCheckpointId = Stdlib_Option.flatMap(rollback, r => CheckpointSequence.findForScope(config.checkpointSequence, r.diffFrontier, scope));
|
|
760
840
|
let batchSetUpdates = [];
|
|
761
841
|
let batchDeleteEntityIds = [];
|
|
762
842
|
let batchDeleteCheckpointIds = [];
|
|
@@ -872,6 +952,7 @@ async function writeBatch(sql, batch, pgSchema, rollback, isInReorgThreshold, co
|
|
|
872
952
|
sql => InternalTable.Chains.setProgressedChains(sql, pgSchema, Utils.Dict.mapValuesToArray(batch.progressedChainsById, chainAfterBatch => ({
|
|
873
953
|
chainId: chainAfterBatch.fetchState.chainId,
|
|
874
954
|
progressBlockNumber: chainAfterBatch.progressBlockNumber,
|
|
955
|
+
progressBlockTime: chainAfterBatch.progressBlockTime,
|
|
875
956
|
sourceBlockNumber: chainAfterBatch.sourceBlockNumber,
|
|
876
957
|
totalEventsProcessed: chainAfterBatch.totalEventsProcessed
|
|
877
958
|
}))),
|
|
@@ -883,8 +964,11 @@ async function writeBatch(sql, batch, pgSchema, rollback, isInReorgThreshold, co
|
|
|
883
964
|
if (Utils.$$Array.notEmpty(registeredAddresses)) {
|
|
884
965
|
setOperations.push(sql => InternalTable.EnvioAddresses.insert(sql, pgSchema, registeredAddresses.map(staged => staged.row), chainIdMode));
|
|
885
966
|
}
|
|
886
|
-
if (
|
|
887
|
-
setOperations.push(sql => InternalTable.
|
|
967
|
+
if (!Utils.Dict.isEmpty(writtenFrontier)) {
|
|
968
|
+
setOperations.push(sql => InternalTable.Chains.setCheckpointFrontier(sql, pgSchema, writtenFrontier, chainIdMode));
|
|
969
|
+
}
|
|
970
|
+
if (pickedCheckpoints !== undefined) {
|
|
971
|
+
setOperations.push(sql => InternalTable.Checkpoints.insert(sql, pgSchema, pickCheckpoints(batch.checkpointIds, pickedCheckpoints), pickCheckpoints(batch.checkpointChainIds, pickedCheckpoints), pickCheckpoints(batch.checkpointBlockNumbers, pickedCheckpoints), pickCheckpoints(batch.checkpointBlockHashes, pickedCheckpoints), pickCheckpoints(batch.checkpointEventsProcessed, pickedCheckpoints), chainIdMode));
|
|
888
972
|
}
|
|
889
973
|
await Promise.all(setOperations.map(dbFunc => dbFunc(sql)));
|
|
890
974
|
if (sinkPromise === undefined) {
|
|
@@ -913,7 +997,7 @@ async function writeBatch(sql, batch, pgSchema, rollback, isInReorgThreshold, co
|
|
|
913
997
|
if (exn$1.RE_EXN_ID === PgEncodingError) {
|
|
914
998
|
let escapeTables$1 = escapeTables !== undefined ? Primitive_option.valFromOption(escapeTables) : new Set();
|
|
915
999
|
escapeTables$1.add(exn$1.table);
|
|
916
|
-
return await writeBatch(sql, batch, pgSchema, rollback,
|
|
1000
|
+
return await writeBatch(sql, batch, pgSchema, rollback, config, allEntities, setEffectCacheOrThrow, setQueryCache, updatedEffectsCache, updatedEntities, registeredAddresses, sinkPromise, chainMetaData, Primitive_option.some(escapeTables$1));
|
|
917
1001
|
}
|
|
918
1002
|
throw exn$1;
|
|
919
1003
|
}
|
|
@@ -943,7 +1027,7 @@ function makeGetRollbackPreTargetRowsQuery(entityConfig, pgSchema, floors) {
|
|
|
943
1027
|
let keyColumns = rollbackKeyColumns(entityConfig);
|
|
944
1028
|
let keyColumnsCommaSeparated = keyColumns.map(c => tableRef + `."` + c + `"`).join(", ");
|
|
945
1029
|
let keyMatch = keyColumns.map(c => `h."` + c + `" = ` + tableRef + `."` + c + `"`).join(" AND ");
|
|
946
|
-
let bounds =
|
|
1030
|
+
let bounds = CheckpointSequence.sql(floors.checkpointBounds, Table.getPgChainIdColumn(entityConfig.table), tableRef);
|
|
947
1031
|
return `SELECT DISTINCT ON (` + keyColumnsCommaSeparated + `) ` + dataFieldsCommaSeparated + `, ` + tableRef + `."` + EntityHistory.changeFieldName + `"
|
|
948
1032
|
FROM "` + pgSchema + `"."` + historyTableName + `"` + bounds.join + `
|
|
949
1033
|
WHERE ` + tableRef + `."` + EntityHistory.checkpointIdFieldName + `" <= ` + bounds.checkpointId + `
|
|
@@ -961,7 +1045,7 @@ function makeGetRollbackRemovedIdsQuery(entityConfig, pgSchema, floors) {
|
|
|
961
1045
|
let tableRef = `"` + historyTableName + `"`;
|
|
962
1046
|
let keyColumns = rollbackKeyColumns(entityConfig);
|
|
963
1047
|
let keyMatch = keyColumns.map(c => `h."` + c + `" = ` + tableRef + `."` + c + `"`).join(" AND ");
|
|
964
|
-
let bounds =
|
|
1048
|
+
let bounds = CheckpointSequence.sql(floors.checkpointBounds, Table.getPgChainIdColumn(entityConfig.table), tableRef);
|
|
965
1049
|
return `SELECT DISTINCT ` + keyColumns.map(c => tableRef + `."` + c + `"`).join(", ") + `
|
|
966
1050
|
FROM "` + pgSchema + `"."` + historyTableName + `"` + bounds.join + `
|
|
967
1051
|
WHERE ` + tableRef + `."` + EntityHistory.checkpointIdFieldName + `" > ` + bounds.checkpointId + `
|
|
@@ -982,19 +1066,14 @@ let rollbackChainIdSchema = Utils.$$WeakMap.memoize(table => Stdlib_Option.map(T
|
|
|
982
1066
|
|
|
983
1067
|
let rollbackRemovedIdSchema = Utils.$$WeakMap.memoize(table => S$RescriptSchema.object(s => s.f(Table.idFieldName, Table.getIdSchema(table))));
|
|
984
1068
|
|
|
985
|
-
function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isHasuraEnabled, chainIdModeOpt, ecosystem, sink,
|
|
1069
|
+
function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isHasuraEnabled, chainIdModeOpt, ecosystem, sink, isolatedOpt, onInitialize) {
|
|
986
1070
|
let chainIdMode = chainIdModeOpt !== undefined ? chainIdModeOpt : "int32";
|
|
1071
|
+
let isolated = isolatedOpt !== undefined ? isolatedOpt : false;
|
|
987
1072
|
let containerName = "envio-postgres";
|
|
988
|
-
let psqlExecOptions_env =
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
],
|
|
993
|
-
[
|
|
994
|
-
"PATH",
|
|
995
|
-
process.env.PATH
|
|
996
|
-
]
|
|
997
|
-
]);
|
|
1073
|
+
let psqlExecOptions_env = {
|
|
1074
|
+
PGPASSWORD: pgPassword,
|
|
1075
|
+
PATH: process.env.PATH
|
|
1076
|
+
};
|
|
998
1077
|
let psqlExecOptions = {
|
|
999
1078
|
env: psqlExecOptions_env
|
|
1000
1079
|
};
|
|
@@ -1107,9 +1186,6 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
|
|
|
1107
1186
|
}
|
|
1108
1187
|
}
|
|
1109
1188
|
let cacheTableInfo = await queryCacheTableInfo();
|
|
1110
|
-
if (withUpload && Utils.$$Array.notEmpty(cacheTableInfo) && onNewTables !== undefined) {
|
|
1111
|
-
await onNewTables(cacheTableInfo.map(info => info.table_name));
|
|
1112
|
-
}
|
|
1113
1189
|
let cache = {};
|
|
1114
1190
|
cacheTableInfo.forEach(param => {
|
|
1115
1191
|
let tableName = param.table_name;
|
|
@@ -1138,7 +1214,7 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
|
|
|
1138
1214
|
if (sink !== undefined) {
|
|
1139
1215
|
await sink.initialize(entities);
|
|
1140
1216
|
}
|
|
1141
|
-
let queries = makeInitializeTransaction(pgSchema, pgUser, isHasuraEnabled, chainConfigs, pgEntities, enums, Utils.$$Array.isEmpty(schemaTableNames), true, chainIdMode);
|
|
1217
|
+
let queries = makeInitializeTransaction(pgSchema, pgUser, isHasuraEnabled, CheckpointSequence.fromEntities(entities), chainConfigs, pgEntities, enums, Utils.$$Array.isEmpty(schemaTableNames), true, chainIdMode);
|
|
1142
1218
|
let rowsByChain = chainConfigs.map(chainConfig => ChainState.configStorageRows(chainConfig, ecosystem, contractMapping));
|
|
1143
1219
|
let configAddressRows = rowsByChain.flat();
|
|
1144
1220
|
await sql.begin(async sql => {
|
|
@@ -1165,19 +1241,20 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
|
|
|
1165
1241
|
endBlock: chainConfig.endBlock,
|
|
1166
1242
|
maxReorgDepth: chainConfig.maxReorgDepth,
|
|
1167
1243
|
progressBlockNumber: -1,
|
|
1244
|
+
progressBlockTime: undefined,
|
|
1168
1245
|
numEventsProcessed: 0,
|
|
1169
1246
|
firstEventBlockNumber: undefined,
|
|
1170
1247
|
timestampCaughtUpToHeadOrEndblock: undefined,
|
|
1171
1248
|
addressRows: AddressRows.seedRowsOf(rowsByChain[idx]),
|
|
1172
1249
|
sourceBlockNumber: 0
|
|
1173
1250
|
})),
|
|
1174
|
-
|
|
1251
|
+
checkpointFrontier: Frontier.empty(),
|
|
1175
1252
|
reorgCheckpoints: []
|
|
1176
1253
|
};
|
|
1177
1254
|
};
|
|
1178
1255
|
let loadOrThrow = async (filter, table) => {
|
|
1179
1256
|
let params = [];
|
|
1180
|
-
let condition = makeFilterCondition(filter, table, params);
|
|
1257
|
+
let condition = makeFilterCondition(filter, table, pgSchema, params);
|
|
1181
1258
|
let rows;
|
|
1182
1259
|
try {
|
|
1183
1260
|
rows = await sql.unsafe(makeLoadQuery(pgSchema, table.tableName, condition), params, {prepare: true});
|
|
@@ -1206,12 +1283,8 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
|
|
|
1206
1283
|
let queryFields = Table.queryFields(table);
|
|
1207
1284
|
let columns = [];
|
|
1208
1285
|
let seen = new Set();
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
filter.filters.forEach(collect);
|
|
1212
|
-
return;
|
|
1213
|
-
}
|
|
1214
|
-
let match = queryFields[filter.fieldName];
|
|
1286
|
+
filters.forEach(filter => Utils.Dict.forEachWithKey(EntityFilter.entries(filter), (param, fieldName) => {
|
|
1287
|
+
let match = queryFields[fieldName];
|
|
1215
1288
|
if (match === undefined) {
|
|
1216
1289
|
return;
|
|
1217
1290
|
}
|
|
@@ -1221,8 +1294,7 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
|
|
|
1221
1294
|
columns.push(pgDbFieldName);
|
|
1222
1295
|
return;
|
|
1223
1296
|
}
|
|
1224
|
-
};
|
|
1225
|
-
filters.forEach(collect);
|
|
1297
|
+
}));
|
|
1226
1298
|
return columns;
|
|
1227
1299
|
};
|
|
1228
1300
|
let runAndVerify = async (sql, prepared) => {
|
|
@@ -1246,10 +1318,23 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
|
|
|
1246
1318
|
}
|
|
1247
1319
|
return IndexManager.resync(indexManager, name, rows);
|
|
1248
1320
|
};
|
|
1249
|
-
let
|
|
1250
|
-
|
|
1321
|
+
let partitionChainIds = chainIds => {
|
|
1322
|
+
if (isolated) {
|
|
1323
|
+
return Primitive_option.some(chainIds);
|
|
1324
|
+
}
|
|
1325
|
+
};
|
|
1326
|
+
let queryTableName = (entityConfig, scope) => {
|
|
1327
|
+
if (scope === "crossChain") {
|
|
1328
|
+
return entityConfig.table.tableName;
|
|
1329
|
+
} else {
|
|
1330
|
+
return indexTableNames(entityConfig, partitionChainIds([scope]))[0];
|
|
1331
|
+
}
|
|
1332
|
+
};
|
|
1333
|
+
let ensureQueryIndexes = async (entityConfig, scope, filters) => {
|
|
1334
|
+
let tableName = queryTableName(entityConfig, scope);
|
|
1335
|
+
let columns = filterColumns(entityConfig.table, filters);
|
|
1251
1336
|
await Promise.all(columns.map(column => {
|
|
1252
|
-
let definition = IndexDefinition.single(
|
|
1337
|
+
let definition = IndexDefinition.single(tableName, column);
|
|
1253
1338
|
return Stdlib_Promise.$$catch(IndexManager.ensure(indexManager, definition, "LeadingColumns", async () => {
|
|
1254
1339
|
let prepared = IndexManager.prepare(indexManager, definition, "LeadingColumns", pgSchema);
|
|
1255
1340
|
if (prepared === undefined) {
|
|
@@ -1258,7 +1343,7 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
|
|
|
1258
1343
|
let verb = prepared.isRebuild ? "Rebuilding unusable index" : "Creating index";
|
|
1259
1344
|
Logging.info({
|
|
1260
1345
|
storage: storageName,
|
|
1261
|
-
msg: verb + ` "` + prepared.name + `" to serve a getWhere query on "` +
|
|
1346
|
+
msg: verb + ` "` + prepared.name + `" to serve a getWhere query on "` + tableName + `". Writes to the table are paused until it completes. ` + slowOnLargeDatabaseNotice
|
|
1262
1347
|
});
|
|
1263
1348
|
let timeRef = Performance.now();
|
|
1264
1349
|
let entry = await runAndVerify(sql, prepared);
|
|
@@ -1270,15 +1355,15 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
|
|
|
1270
1355
|
}), async exn => {
|
|
1271
1356
|
Logging.warn({
|
|
1272
1357
|
storage: storageName,
|
|
1273
|
-
msg: `Failed to create an index on "` +
|
|
1358
|
+
msg: `Failed to create an index on "` + tableName + `"("` + column + `") for a getWhere query. The query runs without it.`,
|
|
1274
1359
|
err: Utils.prettifyExn(exn)
|
|
1275
1360
|
});
|
|
1276
1361
|
return await resyncIndex(IndexDefinition.name(definition));
|
|
1277
1362
|
});
|
|
1278
1363
|
}));
|
|
1279
1364
|
};
|
|
1280
|
-
let ensureSchemaIndexes = async entities => {
|
|
1281
|
-
let schemaIndexes = getSchemaIndexes(entities.filter(e => e.storage.postgres));
|
|
1365
|
+
let ensureSchemaIndexes = async (entities, chainIds) => {
|
|
1366
|
+
let schemaIndexes = getSchemaIndexes(entities.filter(e => e.storage.postgres), partitionChainIds(chainIds));
|
|
1282
1367
|
await Promise.all(schemaIndexes.map(definition => Stdlib_Promise.$$catch(IndexManager.ensure(indexManager, definition, "Exact", async () => {
|
|
1283
1368
|
let prepared = IndexManager.prepare(indexManager, definition, "Exact", pgSchema);
|
|
1284
1369
|
if (prepared === undefined) {
|
|
@@ -1306,7 +1391,7 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
|
|
|
1306
1391
|
})));
|
|
1307
1392
|
};
|
|
1308
1393
|
let finalizeBackfill = async (entities, chainIds, readyAt) => {
|
|
1309
|
-
let schemaIndexes = getSchemaIndexes(entities.filter(e => e.storage.postgres));
|
|
1394
|
+
let schemaIndexes = getSchemaIndexes(entities.filter(e => e.storage.postgres), partitionChainIds(chainIds));
|
|
1310
1395
|
let missing = Stdlib_Array.filterMap(schemaIndexes, definition => IndexManager.prepare(indexManager, definition, "Exact", pgSchema));
|
|
1311
1396
|
let rebuilt = missing.filter(prepared => prepared.isRebuild);
|
|
1312
1397
|
if (rebuilt.length !== 0) {
|
|
@@ -1362,9 +1447,6 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
|
|
|
1362
1447
|
let setEffectCacheOrThrow = async (table, itemSchema, items, initialize) => {
|
|
1363
1448
|
if (initialize) {
|
|
1364
1449
|
await sql.unsafe(makeCreateTableQuery(table, pgSchema, false, undefined, undefined));
|
|
1365
|
-
if (onNewTables !== undefined) {
|
|
1366
|
-
await onNewTables([table.tableName]);
|
|
1367
|
-
}
|
|
1368
1450
|
}
|
|
1369
1451
|
return await setOrThrow$1(items, table, itemSchema);
|
|
1370
1452
|
};
|
|
@@ -1415,22 +1497,31 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
|
|
|
1415
1497
|
return Logging.errorWithExn(Utils.prettifyExn(exn$1), `Failed to dump cache.`);
|
|
1416
1498
|
}
|
|
1417
1499
|
};
|
|
1418
|
-
let resumeInitialState = async (entities, throwIfIncompatible) => {
|
|
1500
|
+
let resumeInitialState = async (entities, chainIds, throwIfIncompatible) => {
|
|
1419
1501
|
let match = await Promise.all([
|
|
1420
1502
|
restoreEffectCache(false),
|
|
1421
|
-
InternalTable.Chains.getInitialState(sql, pgSchema).then(rawInitialStates =>
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1503
|
+
InternalTable.Chains.getInitialState(sql, pgSchema).then(rawInitialStates => {
|
|
1504
|
+
let rawInitialStates$1 = rawInitialStates.filter(rawInitialState => chainIds.includes(rawInitialState.id));
|
|
1505
|
+
return [
|
|
1506
|
+
rawInitialStates$1.map(rawInitialState => ({
|
|
1507
|
+
id: rawInitialState.id,
|
|
1508
|
+
startBlock: rawInitialState.startBlock,
|
|
1509
|
+
endBlock: Primitive_option.fromNull(rawInitialState.endBlock),
|
|
1510
|
+
maxReorgDepth: rawInitialState.maxReorgDepth,
|
|
1511
|
+
progressBlockNumber: rawInitialState.progressBlockNumber,
|
|
1512
|
+
progressBlockTime: InternalTable.Chains.blockTimeFromDb(rawInitialState.progressBlockTime),
|
|
1513
|
+
numEventsProcessed: rawInitialState.numEventsProcessed,
|
|
1514
|
+
firstEventBlockNumber: Primitive_option.fromNull(rawInitialState.firstEventBlockNumber),
|
|
1515
|
+
timestampCaughtUpToHeadOrEndblock: Primitive_option.fromNull(rawInitialState.timestampCaughtUpToHeadOrEndblock),
|
|
1516
|
+
addressRows: rawInitialState.addressRows,
|
|
1517
|
+
sourceBlockNumber: rawInitialState.sourceBlockNumber
|
|
1518
|
+
})),
|
|
1519
|
+
Frontier.fromEntries(rawInitialStates$1.map(rawInitialState => [
|
|
1520
|
+
rawInitialState.id,
|
|
1521
|
+
BigInt(rawInitialState.checkpointId)
|
|
1522
|
+
]))
|
|
1523
|
+
];
|
|
1524
|
+
}),
|
|
1434
1525
|
sql.unsafe(InternalTable.Checkpoints.makeGetReorgCheckpointsQuery(pgSchema)),
|
|
1435
1526
|
Promise.all([
|
|
1436
1527
|
InternalTable.EnvioInfo.read(sql, pgSchema),
|
|
@@ -1451,21 +1542,22 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
|
|
|
1451
1542
|
}
|
|
1452
1543
|
})
|
|
1453
1544
|
]);
|
|
1454
|
-
let match$1 = match[
|
|
1545
|
+
let match$1 = match[3];
|
|
1455
1546
|
let storedContractMapping = match$1[1];
|
|
1456
1547
|
let storedEnvioInfo = match$1[0];
|
|
1457
|
-
let
|
|
1548
|
+
let match$2 = match[1];
|
|
1549
|
+
let checkpointFrontier = match$2[1];
|
|
1550
|
+
let chains = match$2[0];
|
|
1458
1551
|
throwIfIncompatible(storedEnvioInfo, storedContractMapping);
|
|
1459
1552
|
await reloadIndexCatalog();
|
|
1460
|
-
let
|
|
1461
|
-
let reorgCheckpoints = match[3].map(raw => ({
|
|
1553
|
+
let reorgCheckpoints = match[2].map(raw => ({
|
|
1462
1554
|
id: BigInt(raw.id),
|
|
1463
1555
|
chain_id: ChainId.normalizeOrThrow(raw.chain_id),
|
|
1464
1556
|
block_number: raw.block_number,
|
|
1465
1557
|
block_hash: raw.block_hash
|
|
1466
1558
|
}));
|
|
1467
1559
|
if (sink !== undefined) {
|
|
1468
|
-
await sink.resume(
|
|
1560
|
+
await sink.resume(checkpointFrontier, chains, entities);
|
|
1469
1561
|
}
|
|
1470
1562
|
return {
|
|
1471
1563
|
cleanRun: false,
|
|
@@ -1473,7 +1565,7 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
|
|
|
1473
1565
|
envioInfo: storedEnvioInfo,
|
|
1474
1566
|
cache: match[0],
|
|
1475
1567
|
chains: chains,
|
|
1476
|
-
|
|
1568
|
+
checkpointFrontier: checkpointFrontier,
|
|
1477
1569
|
reorgCheckpoints: reorgCheckpoints
|
|
1478
1570
|
};
|
|
1479
1571
|
};
|
|
@@ -1487,7 +1579,7 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
|
|
|
1487
1579
|
let getRollbackTargetCheckpoint = (reorgChainId, lastKnownValidBlockNumber) => InternalTable.Checkpoints.getRollbackTargetCheckpoint(sql, pgSchema, reorgChainId, lastKnownValidBlockNumber);
|
|
1488
1580
|
let getRollbackProgressDiff = floors => InternalTable.Checkpoints.getRollbackProgressDiff(sql, pgSchema, floors);
|
|
1489
1581
|
let getRollbackData = async (entityConfig, floors) => {
|
|
1490
|
-
let params =
|
|
1582
|
+
let params = CheckpointSequence.params(floors.checkpointBounds);
|
|
1491
1583
|
let match = await Promise.all([
|
|
1492
1584
|
sql.unsafe(makeGetRollbackRemovedIdsQuery(entityConfig, pgSchema, floors), params, {prepare: true}),
|
|
1493
1585
|
sql.unsafe(makeGetRollbackPreTargetRowsQuery(entityConfig, pgSchema, floors), params, {prepare: true})
|
|
@@ -1521,7 +1613,7 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
|
|
|
1521
1613
|
S$RescriptSchema.parseOrThrow(restoredEntitiesResult, Table.pgRowsSchema(entityConfig.table))
|
|
1522
1614
|
];
|
|
1523
1615
|
};
|
|
1524
|
-
let writeBatchMethod = async (batch, rollback,
|
|
1616
|
+
let writeBatchMethod = async (batch, rollback, config, allEntities, updatedEffectsCache, updatedEntities, registeredAddresses, chainMetaData, onWrite) => {
|
|
1525
1617
|
let pgUpdates = [];
|
|
1526
1618
|
let chUpdates = [];
|
|
1527
1619
|
for (let i = 0, i_finish = updatedEntities.length; i < i_finish; ++i) {
|
|
@@ -1537,14 +1629,14 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
|
|
|
1537
1629
|
let sinkPromise;
|
|
1538
1630
|
if (sink !== undefined) {
|
|
1539
1631
|
let timerRef = Performance.now();
|
|
1540
|
-
sinkPromise = sink.writeBatch(batch, chUpdates).then(() => {
|
|
1632
|
+
sinkPromise = sink.writeBatch(batch, rollback !== undefined ? rollback.diffCheckpoints : [], chUpdates).then(() => {
|
|
1541
1633
|
onWrite(sink.name, Performance.secondsSince(timerRef));
|
|
1542
1634
|
}).catch(exn => exn);
|
|
1543
1635
|
} else {
|
|
1544
1636
|
sinkPromise = undefined;
|
|
1545
1637
|
}
|
|
1546
1638
|
let primaryTimerRef = Performance.now();
|
|
1547
|
-
await writeBatch(sql, batch, pgSchema, rollback,
|
|
1639
|
+
await writeBatch(sql, batch, pgSchema, rollback, config, allEntities, setEffectCacheOrThrow, setQueryCache, updatedEffectsCache, pgUpdates, registeredAddresses, sinkPromise, chainMetaData, undefined);
|
|
1548
1640
|
return onWrite(storageName, Performance.secondsSince(primaryTimerRef));
|
|
1549
1641
|
};
|
|
1550
1642
|
let close = () => sql.end();
|
|
@@ -1596,21 +1688,14 @@ function makeStorageFromEnv(config, sqlOpt, pgSchemaOpt, isHasuraEnabledOpt) {
|
|
|
1596
1688
|
if (missing.length !== 0) {
|
|
1597
1689
|
Stdlib_JsError.throwWithMessage(`ClickHouse storage is enabled but required env vars are not set: ` + missing.join(", ") + `. Please set them, disable clickhouse in the \`storage\` config, or run \`envio dev\` for a pre-configured local ClickHouse.`);
|
|
1598
1690
|
}
|
|
1599
|
-
tmp = Sink.makeClickHouse(host, database, username, password, config.chainIdMode);
|
|
1691
|
+
tmp = Sink.makeClickHouse(host, database, username, password, config.checkpointSequence, config.chainIdMode);
|
|
1600
1692
|
} else {
|
|
1601
1693
|
tmp = undefined;
|
|
1602
1694
|
}
|
|
1603
|
-
return make(sql, Env.Db.host, pgSchema, Env.Db.port, Env.Db.user, Env.Db.database, Env.Db.password, isHasuraEnabled, config.chainIdMode, config.ecosystem.name, tmp, isHasuraEnabled ? () => Stdlib_Promise.$$catch(Hasura.trackDatabase(Env.Hasura.graphqlEndpoint, {
|
|
1695
|
+
return make(sql, Env.Db.host, pgSchema, Env.Db.port, Env.Db.user, Env.Db.database, Env.Db.password, isHasuraEnabled, config.chainIdMode, config.ecosystem.name, tmp, config.isolated, isHasuraEnabled ? () => Stdlib_Promise.$$catch(Hasura.trackDatabase(Env.Hasura.graphqlEndpoint, {
|
|
1604
1696
|
role: Env.Hasura.role,
|
|
1605
1697
|
secret: Env.Hasura.secret
|
|
1606
|
-
}, pgSchema, Config.getPgUserEntities(config), Env.Hasura.aggregateEntities, Env.Hasura.responseLimit, Schema.make(config.userEntities.map(e => e.table))), err => Promise.resolve(Logging.errorWithExn(Utils.prettifyExn(err), `Error tracking tables`))) : undefined
|
|
1607
|
-
role: Env.Hasura.role,
|
|
1608
|
-
secret: Env.Hasura.secret
|
|
1609
|
-
}, pgSchema, tableNames.map(tableName => ({
|
|
1610
|
-
tableName: tableName,
|
|
1611
|
-
description: undefined,
|
|
1612
|
-
columnConfigs: {}
|
|
1613
|
-
}))), err => Promise.resolve(Logging.errorWithExn(Utils.prettifyExn(err), `Error tracking new tables`))) : undefined);
|
|
1698
|
+
}, pgSchema, Config.getPgUserEntities(config), Env.Hasura.aggregateEntities, Env.Hasura.responseLimit, Schema.make(config.userEntities.map(e => e.table))), err => Promise.resolve(Logging.errorWithExn(Utils.prettifyExn(err), `Error tracking tables`))) : undefined);
|
|
1614
1699
|
}
|
|
1615
1700
|
|
|
1616
1701
|
function makePersistenceFromConfig(config, storageOpt) {
|
|
@@ -1624,9 +1709,10 @@ export {
|
|
|
1624
1709
|
makeClient,
|
|
1625
1710
|
formatSeconds,
|
|
1626
1711
|
slowOnLargeDatabaseNotice,
|
|
1712
|
+
partitionTableName,
|
|
1713
|
+
indexTableNames,
|
|
1627
1714
|
getSchemaIndexes,
|
|
1628
1715
|
makeCreateTableQuery,
|
|
1629
|
-
partitionTableName,
|
|
1630
1716
|
rowSchemaCache,
|
|
1631
1717
|
getRowSchema,
|
|
1632
1718
|
entityHistoryCache,
|
|
@@ -1658,6 +1744,7 @@ export {
|
|
|
1658
1744
|
deleteByIdsOrThrow,
|
|
1659
1745
|
makeInsertDeleteUpdatesQuery,
|
|
1660
1746
|
executeSet,
|
|
1747
|
+
pickCheckpoints,
|
|
1661
1748
|
writeBatch,
|
|
1662
1749
|
rollbackKeyColumns,
|
|
1663
1750
|
makeGetRollbackPreTargetRowsQuery,
|