envio 3.15.0-subgraph → 3.16.0-subgraph
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 +40 -34
- package/evm.schema.json +3 -3
- package/fuel.schema.json +2 -2
- package/index.d.ts +3 -3
- package/licenses/README.md +1 -1
- package/package.json +8 -8
- package/src/Batch.res.mjs +5 -5
- package/src/BatchProcessing.res +1 -0
- package/src/BatchProcessing.res.mjs +1 -0
- package/src/ChainFetching.res +1 -6
- package/src/ChainFetching.res.mjs +1 -1
- package/src/ChainState.res +48 -7
- package/src/ChainState.res.mjs +21 -8
- package/src/Clock.res +57 -0
- package/src/Clock.res.mjs +72 -0
- package/src/Config.res +16 -4
- package/src/Config.res.mjs +5 -3
- package/src/Core.res +4 -40
- package/src/CrossChainState.res +10 -6
- package/src/CrossChainState.res.mjs +1 -1
- package/src/EffectState.res +10 -2
- package/src/EffectState.res.mjs +8 -4
- package/src/EffectState.resi +3 -1
- package/src/EntityId.res +2 -7
- package/src/EntityId.res.mjs +1 -8
- package/src/EntityTables.res +4 -1
- package/src/EntityTables.res.mjs +1 -1
- package/src/Env.res +4 -0
- package/src/Env.res.mjs +5 -0
- package/src/FetchState.res +157 -69
- package/src/FetchState.res.mjs +112 -47
- package/src/FinalizeBackfill.res +2 -4
- package/src/FinalizeBackfill.res.mjs +3 -4
- package/src/InMemoryTable.res +17 -16
- package/src/InMemoryTable.res.mjs +14 -15
- package/src/IndexerState.res +28 -4
- package/src/IndexerState.res.mjs +19 -6
- package/src/IndexerState.resi +4 -0
- package/src/Internal.res +0 -49
- package/src/Internal.res.mjs +1 -80
- package/src/LoadLayer.res +17 -10
- package/src/LoadLayer.res.mjs +11 -8
- package/src/Main.res.mjs +1 -1
- package/src/Persistence.res +3 -23
- package/src/Persistence.res.mjs +3 -3
- package/src/PreloadLookahead.res +42 -24
- package/src/PreloadLookahead.res.mjs +51 -30
- package/src/Rollback.res +0 -1
- package/src/Rollback.res.mjs +1 -1
- package/src/SafeCheckpointTracking.res +4 -4
- package/src/SafeCheckpointTracking.res.mjs +1 -1
- package/src/StagedRows.res +106 -0
- package/src/StagedRows.res.mjs +102 -0
- package/src/Staging.res +32 -14
- package/src/Staging.res.mjs +17 -20
- package/src/Storage.res +278 -973
- package/src/Storage.res.mjs +218 -720
- package/src/Supervisor.res +75 -56
- package/src/Supervisor.res.mjs +55 -26
- package/src/SyncWrites.res +24 -18
- package/src/SyncWrites.res.mjs +11 -11
- package/src/TestIndexer.res +22 -27
- package/src/TestIndexer.res.mjs +20 -17
- package/src/Throttler.res +15 -8
- package/src/Throttler.res.mjs +9 -6
- package/src/Throttler.resi +1 -1
- package/src/UserContext.res +13 -4
- package/src/UserContext.res.mjs +5 -5
- package/src/Utils.res +0 -6
- package/src/Utils.res.mjs +0 -5
- package/src/Writing.res +0 -1
- package/src/Writing.res.mjs +1 -1
- package/src/bindings/ClickHouse.res +0 -322
- package/src/bindings/ClickHouse.res.mjs +0 -338
- package/src/bindings/StorageClient.res +107 -174
- package/src/bindings/StorageClient.res.mjs +19 -8
- package/src/bindings/Vitest.res +0 -26
- package/src/bindings/Vitest.res.mjs +0 -3
- package/src/db/Table.res +24 -150
- package/src/db/Table.res.mjs +38 -272
- package/src/sources/ChainSources.res +2 -0
- package/src/sources/ChainSources.res.mjs +2 -2
- package/src/sources/EvmChain.res +3 -0
- package/src/sources/EvmChain.res.mjs +4 -2
- package/src/sources/EvmHyperSyncSource.res +2 -2
- package/src/sources/EvmHyperSyncSource.res.mjs +1 -1
- package/src/sources/EvmRpcClient.res +13 -3
- package/src/sources/EvmRpcClient.res.mjs +4 -3
- package/src/sources/EvmRpcWs.res +4 -3
- package/src/sources/EvmRpcWs.res.mjs +2 -2
- package/src/sources/HeightFeed.res +31 -10
- package/src/sources/HeightFeed.res.mjs +10 -6
- package/src/sources/HeightStream.res +32 -17
- package/src/sources/HeightStream.res.mjs +10 -10
- package/src/sources/HyperSyncSSE.res +4 -6
- package/src/sources/HyperSyncSSE.res.mjs +2 -2
- package/src/sources/RpcSource.res +10 -1
- package/src/sources/RpcSource.res.mjs +4 -3
- package/src/sources/Source.res +3 -0
- package/src/sources/SourceManager.res +85 -104
- package/src/sources/SourceManager.res.mjs +18 -37
- package/src/sources/SourceManager.resi +3 -5
- package/src/sources/StartBlockResolver.res +1 -0
- package/src/sources/StartBlockResolver.res.mjs +4 -3
- package/src/sources/SvmHyperSyncSource.res +2 -2
- package/src/sources/SvmHyperSyncSource.res.mjs +1 -1
- package/src/subgraph/graph-ts.ts +87 -28
- package/src/subgraph/runtime.ts +0 -1
- package/src/subgraph/scope.ts +0 -1
- package/svm.schema.json +3 -3
- package/src/PgWriting.res +0 -36
- package/src/PgWriting.res.mjs +0 -34
- package/src/db/IndexDefinition.res +0 -47
- package/src/db/IndexDefinition.res.mjs +0 -60
package/src/Storage.res.mjs
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
|
-
import * as Fs from "fs";
|
|
4
3
|
import * as Env from "./Env.res.mjs";
|
|
5
4
|
import * as Sql from "./db/Sql.res.mjs";
|
|
6
5
|
import * as Path from "path";
|
|
@@ -12,16 +11,16 @@ import * as Logger from "./Logger.res.mjs";
|
|
|
12
11
|
import * as Schema from "./db/Schema.res.mjs";
|
|
13
12
|
import * as ChainId from "./ChainId.res.mjs";
|
|
14
13
|
import * as Staging from "./Staging.res.mjs";
|
|
15
|
-
import * as EntityId from "./EntityId.res.mjs";
|
|
16
14
|
import * as Frontier from "./db/Frontier.res.mjs";
|
|
17
15
|
import * as Internal from "./Internal.res.mjs";
|
|
18
|
-
import * as PgWriting from "./PgWriting.res.mjs";
|
|
19
16
|
import * as ChainState from "./ChainState.res.mjs";
|
|
20
17
|
import * as ClickHouse from "./bindings/ClickHouse.res.mjs";
|
|
21
18
|
import * as LoadFilter from "./db/LoadFilter.res.mjs";
|
|
19
|
+
import * as StagedRows from "./StagedRows.res.mjs";
|
|
22
20
|
import * as AddressRows from "./AddressRows.res.mjs";
|
|
23
21
|
import * as Performance from "./bindings/Performance.res.mjs";
|
|
24
22
|
import * as Persistence from "./Persistence.res.mjs";
|
|
23
|
+
import * as Stdlib_Null from "@rescript/runtime/lib/es6/Stdlib_Null.js";
|
|
25
24
|
import * as EntityFilter from "./db/EntityFilter.res.mjs";
|
|
26
25
|
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
27
26
|
import * as Stdlib_JsExn from "@rescript/runtime/lib/es6/Stdlib_JsExn.js";
|
|
@@ -30,21 +29,12 @@ import * as HistoryPolicy from "./HistoryPolicy.res.mjs";
|
|
|
30
29
|
import * as InternalTable from "./db/InternalTable.res.mjs";
|
|
31
30
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
32
31
|
import * as StorageClient from "./bindings/StorageClient.res.mjs";
|
|
33
|
-
import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
|
|
34
32
|
import * as Stdlib_Promise from "@rescript/runtime/lib/es6/Stdlib_Promise.js";
|
|
35
33
|
import * as ContractMapping from "./ContractMapping.res.mjs";
|
|
36
|
-
import * as IndexDefinition from "./db/IndexDefinition.res.mjs";
|
|
37
34
|
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
38
35
|
import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
|
|
39
|
-
import * as CheckpointSequence from "./db/CheckpointSequence.res.mjs";
|
|
40
36
|
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
41
37
|
|
|
42
|
-
function formatSeconds(seconds) {
|
|
43
|
-
return (Math.round(seconds * 100) / 100).toString();
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
let slowOnLargeDatabaseNotice = "This can take a long time on a large database.";
|
|
47
|
-
|
|
48
38
|
function storeName(store) {
|
|
49
39
|
if (store === "Postgres") {
|
|
50
40
|
return "postgres";
|
|
@@ -55,83 +45,11 @@ function storeName(store) {
|
|
|
55
45
|
|
|
56
46
|
let postgresName = "postgres";
|
|
57
47
|
|
|
58
|
-
function
|
|
59
|
-
switch (event.kind) {
|
|
60
|
-
case "Invalid" :
|
|
61
|
-
return Logger.warn(logger, `Ignoring invalid PostgreSQL indexes in schema "` + pgSchema + `". They can't serve queries, so the indexer builds its own alongside them.`, {
|
|
62
|
-
storage: postgresName,
|
|
63
|
-
indexes: event.names
|
|
64
|
-
});
|
|
65
|
-
case "Planned" :
|
|
66
|
-
let rebuilt = event.rebuilt;
|
|
67
|
-
let missing = event.missing;
|
|
68
|
-
if (Utils.$$Array.notEmpty(rebuilt)) {
|
|
69
|
-
Logger.warn(logger, `PostgreSQL reports ` + rebuilt.length.toString() + ` of the indexer's own indexes as invalid, so they can't serve queries. Rebuilding them.`, {
|
|
70
|
-
storage: postgresName,
|
|
71
|
-
indexes: rebuilt
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
if (missing.length !== 0) {
|
|
75
|
-
return Logger.info(logger, `Creating the ` + missing.length.toString() + ` remaining schema indexes before the indexer reports ready. Writes are paused until they are committed. ` + slowOnLargeDatabaseNotice, {
|
|
76
|
-
storage: postgresName,
|
|
77
|
-
indexes: missing
|
|
78
|
-
});
|
|
79
|
-
} else {
|
|
80
|
-
return Logger.info(logger, `All ` + event.declared.toString() + ` schema indexes are already in place. Marking the indexer ready.`, {
|
|
81
|
-
storage: postgresName
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
case "Building" :
|
|
85
|
-
if (event.purpose === "Query") {
|
|
86
|
-
return Logger.info(logger, (
|
|
87
|
-
event.isRebuild ? "Rebuilding unusable index" : "Creating index"
|
|
88
|
-
) + ` "` + event.name + `" to serve a getWhere query on "` + event.tableName + `". Writes to the table are paused until it completes. ` + slowOnLargeDatabaseNotice, {
|
|
89
|
-
storage: postgresName
|
|
90
|
-
});
|
|
91
|
-
} else {
|
|
92
|
-
return Logger.info(logger, (
|
|
93
|
-
event.isRebuild ? "Rebuilding unusable index" : "Creating missing index"
|
|
94
|
-
) + ` "` + event.name + `" the schema promises but the database no longer has. Writes to the table are paused until it completes. ` + slowOnLargeDatabaseNotice, {
|
|
95
|
-
storage: postgresName
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
case "Built" :
|
|
99
|
-
let tmp;
|
|
100
|
-
tmp = event.purpose === "Query" ? " Resuming indexing." : "";
|
|
101
|
-
return Logger.info(logger, `Index "` + event.name + `" is ready after ` + formatSeconds(event.seconds) + `s.` + tmp, {
|
|
102
|
-
storage: postgresName
|
|
103
|
-
});
|
|
104
|
-
case "Failed" :
|
|
105
|
-
if (event.purpose === "Query") {
|
|
106
|
-
return Logger.warn(logger, `Failed to create an index on "` + event.tableName + `"(` + event.columns.map(column => `"` + column + `"`).join(", ") + `) for a getWhere query. The query runs without it.`, {
|
|
107
|
-
storage: postgresName,
|
|
108
|
-
err: event.error,
|
|
109
|
-
code: event.code
|
|
110
|
-
});
|
|
111
|
-
} else {
|
|
112
|
-
return Logger.warn(logger, `Failed to restore the schema index "` + event.name + `". Queries relying on it run unindexed until the next restart.`, {
|
|
113
|
-
storage: postgresName,
|
|
114
|
-
err: event.error,
|
|
115
|
-
code: event.code
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
case "ResyncFailed" :
|
|
119
|
-
return Logger.trace(logger, `Could not re-read the index "` + event.name + `" after a failed build. The next attempt reads it again.`, {
|
|
120
|
-
storage: postgresName,
|
|
121
|
-
err: event.error,
|
|
122
|
-
code: event.code
|
|
123
|
-
});
|
|
124
|
-
case "Committed" :
|
|
125
|
-
return Logger.info(logger, `Committed ` + event.count.toString() + ` schema indexes and the ready timestamp in ` + formatSeconds(event.seconds) + `s.`, {
|
|
126
|
-
storage: postgresName
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
function postgresOptions(pgSchemaOpt, isHasuraEnabledOpt, maxConnectionsOpt) {
|
|
48
|
+
function postgresOptions(pgSchemaOpt, isHasuraEnabledOpt, maxConnectionsOpt, isolatedOpt) {
|
|
132
49
|
let pgSchema = pgSchemaOpt !== undefined ? pgSchemaOpt : Env.Db.publicSchema;
|
|
133
50
|
let isHasuraEnabled = isHasuraEnabledOpt !== undefined ? isHasuraEnabledOpt : false;
|
|
134
51
|
let maxConnections = maxConnectionsOpt !== undefined ? maxConnectionsOpt : Env.Db.maxConnections;
|
|
52
|
+
let isolated = isolatedOpt !== undefined ? isolatedOpt : false;
|
|
135
53
|
return {
|
|
136
54
|
host: Env.Db.host,
|
|
137
55
|
port: Env.Db.port,
|
|
@@ -142,298 +60,23 @@ function postgresOptions(pgSchemaOpt, isHasuraEnabledOpt, maxConnectionsOpt) {
|
|
|
142
60
|
maxConnections: maxConnections,
|
|
143
61
|
applicationName: `hyperindex/` + Utils.EnvioPackage.value.version,
|
|
144
62
|
pgSchema: pgSchema,
|
|
145
|
-
isHasuraEnabled: isHasuraEnabled
|
|
63
|
+
isHasuraEnabled: isHasuraEnabled,
|
|
64
|
+
isolated: isolated
|
|
146
65
|
};
|
|
147
66
|
}
|
|
148
67
|
|
|
149
|
-
function makeClient(logger,
|
|
150
|
-
let chainIdMode = chainIdModeOpt !== undefined ? chainIdModeOpt : "int32";
|
|
68
|
+
function makeClient(logger, config, postgres, clickhouse) {
|
|
151
69
|
return StorageClient.make({
|
|
152
|
-
chainIdMode: chainIdMode,
|
|
153
70
|
postgres: postgres,
|
|
154
71
|
clickhouse: clickhouse
|
|
155
|
-
},
|
|
156
|
-
storage: "clickhouse"
|
|
157
|
-
}));
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
function partitionTableName(entityConfig, chainId) {
|
|
161
|
-
let chainIdStr = ChainId.toString(chainId);
|
|
162
|
-
return Table.fitPgTableName(entityConfig.table.tableName + `$` + chainIdStr, `$` + entityConfig.index.toString() + `$` + chainIdStr);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
function indexTableNames(entityConfig, partitionChainIds) {
|
|
166
|
-
let match = Table.getChainIdField(entityConfig.table);
|
|
167
|
-
if (match !== undefined) {
|
|
168
|
-
if (partitionChainIds !== undefined) {
|
|
169
|
-
return partitionChainIds.map(chainId => partitionTableName(entityConfig, chainId));
|
|
170
|
-
} else {
|
|
171
|
-
return [entityConfig.table.tableName];
|
|
172
|
-
}
|
|
173
|
-
} else {
|
|
174
|
-
return [entityConfig.table.tableName];
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
function getSchemaIndexes(entities, partitionChainIds) {
|
|
179
|
-
let derivedSchema = Schema.make(entities.map(e => e.table));
|
|
180
|
-
let all = [];
|
|
181
|
-
entities.forEach(param => {
|
|
182
|
-
let table = param.table;
|
|
183
|
-
Table.getSingleIndexes(table).forEach(column => {
|
|
184
|
-
all.push(IndexDefinition.single(table.tableName, column));
|
|
185
|
-
});
|
|
186
|
-
Table.getCompositeIndexes(table).forEach(indexFields => {
|
|
187
|
-
all.push(IndexDefinition.fromIndexFields(table.tableName, indexFields));
|
|
188
|
-
});
|
|
189
|
-
});
|
|
190
|
-
entities.forEach(param => {
|
|
191
|
-
Table.getDerivedFromFields(param.table).forEach(derivedFromField => {
|
|
192
|
-
let column = Utils.unwrapResultExn(Schema.getDerivedFromPgFieldName(derivedSchema, derivedFromField));
|
|
193
|
-
let isList = Stdlib_Option.mapOr(Stdlib_Option.flatMap(derivedSchema[derivedFromField.derivedFromEntity], table => Table.getFieldByName(table, derivedFromField.derivedFromField)), false, field => {
|
|
194
|
-
if (field.TAG === "Field") {
|
|
195
|
-
return field._0.isArray;
|
|
196
|
-
} else {
|
|
197
|
-
return false;
|
|
198
|
-
}
|
|
199
|
-
});
|
|
200
|
-
all.push(IndexDefinition.make(derivedFromField.derivedFromEntity, [{
|
|
201
|
-
name: column,
|
|
202
|
-
direction: "Asc"
|
|
203
|
-
}], isList ? "gin" : undefined));
|
|
204
|
-
});
|
|
205
|
-
});
|
|
206
|
-
let seen = new Set();
|
|
207
|
-
let entityByTableName = {};
|
|
208
|
-
entities.forEach(entityConfig => {
|
|
209
|
-
entityByTableName[entityConfig.table.tableName] = entityConfig;
|
|
210
|
-
});
|
|
211
|
-
return all.filter(definition => {
|
|
212
|
-
let identity = IndexDefinition.describe(definition);
|
|
213
|
-
if (seen.has(identity)) {
|
|
214
|
-
return false;
|
|
215
|
-
} else {
|
|
216
|
-
seen.add(identity);
|
|
217
|
-
return true;
|
|
218
|
-
}
|
|
219
|
-
}).flatMap(definition => indexTableNames(Stdlib_Option.getOrThrow(entityByTableName[definition.tableName], undefined), partitionChainIds).map(tableName => ({
|
|
220
|
-
tableName: tableName,
|
|
221
|
-
columns: definition.columns,
|
|
222
|
-
method: definition.method
|
|
223
|
-
})));
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
function pgColumnInput(field) {
|
|
227
|
-
let match = Table.pgFieldTypeParts(field.fieldType);
|
|
228
|
-
return {
|
|
229
|
-
name: Table.getPgDbFieldName(field),
|
|
230
|
-
fieldType: match[0],
|
|
231
|
-
isArray: field.isArray,
|
|
232
|
-
isNullable: field.isNullable,
|
|
233
|
-
isPrimaryKey: field.isPrimaryKey,
|
|
234
|
-
defaultValue: field.defaultValue,
|
|
235
|
-
precision: match[1],
|
|
236
|
-
scale: match[2],
|
|
237
|
-
enumName: match[3]
|
|
238
|
-
};
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
let rowSchemaCache = new WeakMap();
|
|
242
|
-
|
|
243
|
-
function getRowSchema(entityConfig) {
|
|
244
|
-
let cached = rowSchemaCache.get(entityConfig);
|
|
245
|
-
if (cached !== undefined) {
|
|
246
|
-
return Primitive_option.valFromOption(cached);
|
|
247
|
-
}
|
|
248
|
-
let chainIdField = Table.getChainIdField(entityConfig.table);
|
|
249
|
-
let schema = chainIdField !== undefined ? S$RescriptSchema.schema(s => {
|
|
250
|
-
let dict = {};
|
|
251
|
-
let match = entityConfig.schema.t;
|
|
252
|
-
let exit = 0;
|
|
253
|
-
if (typeof match !== "object" || match.TAG !== "object") {
|
|
254
|
-
exit = 1;
|
|
255
|
-
} else {
|
|
256
|
-
match.items.forEach(param => {
|
|
257
|
-
dict[param.location] = s.m(param.schema);
|
|
258
|
-
});
|
|
259
|
-
}
|
|
260
|
-
if (exit === 1) {
|
|
261
|
-
Stdlib_JsError.throwWithMessage(`Unexpected non-object schema for entity "` + entityConfig.name + `".`);
|
|
262
|
-
}
|
|
263
|
-
dict[chainIdField.fieldName] = s.m(ChainId.schema);
|
|
264
|
-
return dict;
|
|
265
|
-
}) : entityConfig.schema;
|
|
266
|
-
rowSchemaCache.set(entityConfig, schema);
|
|
267
|
-
return schema;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
function register(client, table, itemSchema, postgresOpt, clickhouse, appendOnlyOpt, history) {
|
|
271
|
-
let postgres = postgresOpt !== undefined ? postgresOpt : true;
|
|
272
|
-
let appendOnly = appendOnlyOpt !== undefined ? appendOnlyOpt : false;
|
|
273
|
-
let fields = Table.schemaOrderedFields(table, itemSchema);
|
|
274
|
-
let chainIdField = Table.getChainIdField(table);
|
|
275
|
-
let registered = client.registerTable({
|
|
276
|
-
name: table.tableName,
|
|
277
|
-
postgres: postgres ? ({
|
|
278
|
-
columns: Table.getFields(table).map(pgColumnInput),
|
|
279
|
-
writeColumns: fields.map(Table.getPgDbFieldName),
|
|
280
|
-
partitionByColumn: Stdlib_Option.map(chainIdField, Table.getPgDbFieldName),
|
|
281
|
-
appendOnly: appendOnly,
|
|
282
|
-
historyTable: history,
|
|
283
|
-
chainIdColumn: history !== undefined ? Stdlib_Option.map(chainIdField, Table.getPgDbFieldName) : undefined
|
|
284
|
-
}) : undefined,
|
|
285
|
-
clickhouse: clickhouse
|
|
286
|
-
});
|
|
287
|
-
return {
|
|
288
|
-
handle: registered.handle,
|
|
289
|
-
home: registered.home,
|
|
290
|
-
table: table,
|
|
291
|
-
fields: fields,
|
|
292
|
-
postgres: Stdlib_Option.map(registered.postgres, param => ({
|
|
293
|
-
staged: Stdlib_Option.map(param.kinds, kinds => PgWriting.columns(fields, kinds.map(Staging.kindOfOrdinal)))
|
|
294
|
-
})),
|
|
295
|
-
clickhouse: Stdlib_Option.map(registered.clickhouse, __x => ClickHouse.makeTable(registered.handle, Stdlib_Option.getOr(history, table.tableName), __x))
|
|
296
|
-
};
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
function registerEntity(client, entityConfig) {
|
|
300
|
-
return register(client, entityConfig.table, getRowSchema(entityConfig), entityConfig.storage.postgres, entityConfig.storage.clickhouse ? ClickHouse.entityTable(entityConfig) : undefined, undefined, EntityHistory.historyTableName(entityConfig.name, entityConfig.index));
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
function renderDocument(value, isNullable) {
|
|
304
|
-
if (value == null) {
|
|
305
|
-
if (value === null && !isNullable) {
|
|
306
|
-
return "null";
|
|
307
|
-
} else {
|
|
308
|
-
return value;
|
|
309
|
-
}
|
|
310
|
-
} else {
|
|
311
|
-
return Sql.stringifyDocument(value);
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
let arenaConverters = new WeakMap();
|
|
316
|
-
|
|
317
|
-
let cellConverters = new WeakMap();
|
|
318
|
-
|
|
319
|
-
function converterOf(registered, forArena, itemSchema) {
|
|
320
|
-
let converters = forArena ? arenaConverters : cellConverters;
|
|
321
|
-
let convert = converters.get(itemSchema);
|
|
322
|
-
if (convert !== undefined) {
|
|
323
|
-
return convert;
|
|
324
|
-
}
|
|
325
|
-
let documents = Stdlib_Array.filterMapWithIndex(registered.fields, (field, index) => {
|
|
326
|
-
if (field.fieldType === "Json") {
|
|
327
|
-
return [
|
|
328
|
-
index,
|
|
329
|
-
field
|
|
330
|
-
];
|
|
331
|
-
}
|
|
332
|
-
});
|
|
333
|
-
let schema = forArena ? Table.toDbSchema(registered.table, itemSchema) : itemSchema;
|
|
334
|
-
let convert$1 = S$RescriptSchema.compile(S$RescriptSchema.preprocess(S$RescriptSchema.unnest(schema), param => ({
|
|
335
|
-
s: columns => {
|
|
336
|
-
documents.forEach(param => {
|
|
337
|
-
let field = param[1];
|
|
338
|
-
let values = columns[param[0]];
|
|
339
|
-
for (let row = 0, row_finish = values.length; row < row_finish; ++row) {
|
|
340
|
-
let value = values[row];
|
|
341
|
-
values[row] = !(value == null) && field.isArray ? value.map(document => renderDocument(document, true)) : renderDocument(value, field.isNullable);
|
|
342
|
-
}
|
|
343
|
-
});
|
|
344
|
-
return columns;
|
|
345
|
-
}
|
|
346
|
-
})), "Output", "Input", "Sync", false);
|
|
347
|
-
converters.set(itemSchema, convert$1);
|
|
348
|
-
return convert$1;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
function refuseNonFinite(values, fields) {
|
|
352
|
-
fields.forEach((field, index) => {
|
|
353
|
-
if (field.fieldType !== "Number") {
|
|
354
|
-
return;
|
|
355
|
-
}
|
|
356
|
-
let column = Table.getPgDbFieldName(field);
|
|
357
|
-
let check = value => {
|
|
358
|
-
if (value == null) {
|
|
359
|
-
return;
|
|
360
|
-
}
|
|
361
|
-
Staging.finiteOrThrow(value, column);
|
|
362
|
-
};
|
|
363
|
-
values[index].forEach(value => {
|
|
364
|
-
if (!field.isArray) {
|
|
365
|
-
return check(value);
|
|
366
|
-
}
|
|
367
|
-
if (value == null) {
|
|
368
|
-
return;
|
|
369
|
-
}
|
|
370
|
-
value.forEach(check);
|
|
371
|
-
});
|
|
372
|
-
});
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
function stagedFor(staged, store, stage) {
|
|
376
|
-
let started = Performance.now();
|
|
377
|
-
let result = stage();
|
|
378
|
-
let name = storeName(store);
|
|
379
|
-
staged.seconds[name] = Stdlib_Option.getOr(staged.seconds[name], 0) + Performance.secondsSince(started);
|
|
380
|
-
return result;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
function rowsOrThrow(client, registered, itemSchema, items, staged) {
|
|
384
|
-
return stagedFor(staged, "Postgres", () => {
|
|
385
|
-
let rows = items.length;
|
|
386
|
-
try {
|
|
387
|
-
let match = registered.postgres;
|
|
388
|
-
if (match === undefined) {
|
|
389
|
-
return Stdlib_JsError.throwWithMessage(`Postgres doesn't keep "` + registered.table.tableName + `"`);
|
|
390
|
-
}
|
|
391
|
-
let columns = match.staged;
|
|
392
|
-
if (columns !== undefined) {
|
|
393
|
-
let values = converterOf(registered, true, itemSchema)(items);
|
|
394
|
-
let handle = PgWriting.stage(StorageClient.arena(client, "Postgres"), registered.handle, columns, values, rows);
|
|
395
|
-
staged.handles.push(handle);
|
|
396
|
-
return {
|
|
397
|
-
staged: handle,
|
|
398
|
-
rows: rows
|
|
399
|
-
};
|
|
400
|
-
}
|
|
401
|
-
let values$1 = converterOf(registered, false, itemSchema)(items);
|
|
402
|
-
refuseNonFinite(values$1, registered.fields);
|
|
403
|
-
return {
|
|
404
|
-
cells: Sql.params(values$1.flat(1)),
|
|
405
|
-
rows: rows
|
|
406
|
-
};
|
|
407
|
-
} catch (raw_exn) {
|
|
408
|
-
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
409
|
-
if (exn.RE_EXN_ID === S$RescriptSchema.Raised) {
|
|
410
|
-
throw {
|
|
411
|
-
RE_EXN_ID: Persistence.StorageError,
|
|
412
|
-
message: `Failed to convert items for table "` + registered.table.tableName + `"`,
|
|
413
|
-
reason: exn,
|
|
414
|
-
Error: new Error()
|
|
415
|
-
};
|
|
416
|
-
}
|
|
417
|
-
throw {
|
|
418
|
-
RE_EXN_ID: Persistence.StorageError,
|
|
419
|
-
message: `Failed to insert items into table "` + registered.table.tableName + `"`,
|
|
420
|
-
reason: Utils.prettifyExn(exn),
|
|
421
|
-
Error: new Error()
|
|
422
|
-
};
|
|
423
|
-
}
|
|
424
|
-
});
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
function renderIds(table, ids) {
|
|
428
|
-
return Table.encodeIdsToJson(table, ids).map(Sql.render);
|
|
72
|
+
}, Stdlib_Option.map(config, config => JSON.stringify(config.envioInfo)), logger);
|
|
429
73
|
}
|
|
430
74
|
|
|
431
75
|
function bounds(param) {
|
|
432
|
-
let
|
|
76
|
+
let byChain = param.byChain;
|
|
433
77
|
return {
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
checkpointIds: match[1]
|
|
78
|
+
chainIds: Frontier.chainIds(byChain),
|
|
79
|
+
checkpointIds: Frontier.chainIds(byChain).map(chainId => Frontier.get(byChain, chainId))
|
|
437
80
|
};
|
|
438
81
|
}
|
|
439
82
|
|
|
@@ -484,18 +127,71 @@ function storageErrorOf(exn) {
|
|
|
484
127
|
}
|
|
485
128
|
}
|
|
486
129
|
|
|
487
|
-
let rollbackRowStateSchema = Utils.$$WeakMap.memoize(table => S$RescriptSchema.object(s => [
|
|
488
|
-
s.f(Table.idFieldName, Table.getIdSchema(table)),
|
|
489
|
-
s.f(EntityHistory.changeFieldName, EntityHistory.RowAction.schema)
|
|
490
|
-
]));
|
|
491
|
-
|
|
492
130
|
let rollbackChainIdSchema = Utils.$$WeakMap.memoize(table => Stdlib_Option.map(Table.getChainIdField(table), field => S$RescriptSchema.object(s => s.f(Table.getPgDbFieldName(field), ChainId.schema))));
|
|
493
131
|
|
|
494
132
|
let rollbackRemovedIdSchema = Utils.$$WeakMap.memoize(table => S$RescriptSchema.object(s => s.f(Table.idFieldName, Table.getIdSchema(table))));
|
|
495
133
|
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
134
|
+
let changeColumns = [
|
|
135
|
+
{
|
|
136
|
+
name: EntityHistory.checkpointIdFieldName,
|
|
137
|
+
kind: 2,
|
|
138
|
+
isNullable: false
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
name: EntityHistory.changeFieldName,
|
|
142
|
+
kind: 0,
|
|
143
|
+
isNullable: false
|
|
144
|
+
}
|
|
145
|
+
];
|
|
146
|
+
|
|
147
|
+
function stageOrThrow(arena, columns, rows, fill) {
|
|
148
|
+
let stage = Staging.begin(arena, rows, columns);
|
|
149
|
+
try {
|
|
150
|
+
fill(stage);
|
|
151
|
+
return Staging.commit(stage);
|
|
152
|
+
} catch (exn) {
|
|
153
|
+
Staging.abort(stage);
|
|
154
|
+
throw exn;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function stageRowsOrThrow(arena, writers, items) {
|
|
159
|
+
return stageOrThrow(arena, StagedRows.columnsOf(writers), items.length, stage => {
|
|
160
|
+
items.forEach((item, row) => {
|
|
161
|
+
writers.forEach((param, column) => StagedRows.writeField(stage, writers, column, row, item[param.field.name]));
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function stageChangesOrThrow(arena, writers, changes) {
|
|
167
|
+
let fields = writers.length;
|
|
168
|
+
return stageOrThrow(arena, StagedRows.columnsOf(writers).concat(changeColumns), changes.length, stage => {
|
|
169
|
+
changes.forEach((change, row) => {
|
|
170
|
+
let entityId = change.entityId;
|
|
171
|
+
if (change.type === "SET") {
|
|
172
|
+
let entity = change.entity;
|
|
173
|
+
writers.forEach((param, column) => {
|
|
174
|
+
let field = param.field;
|
|
175
|
+
StagedRows.writeField(stage, writers, column, row, field.name === Table.idFieldName ? entityId : entity[field.name]);
|
|
176
|
+
});
|
|
177
|
+
} else {
|
|
178
|
+
writers.forEach((param, column) => {
|
|
179
|
+
if (param.field.name === Table.idFieldName) {
|
|
180
|
+
return StagedRows.writeField(stage, writers, column, row, entityId);
|
|
181
|
+
} else {
|
|
182
|
+
return Staging.writeDeletedValue(stage, column, row, undefined);
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
Staging.writeValue(stage, fields, row, change.checkpointId);
|
|
187
|
+
let tmp;
|
|
188
|
+
tmp = change.type === "SET" ? 0 : 1;
|
|
189
|
+
Staging.writeValue(stage, fields + 1 | 0, row, tmp);
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function make(client, cacheDir, ecosystem, onInitialize) {
|
|
499
195
|
let eagerSchemaIndexes = Env.subgraphMode.contents;
|
|
500
196
|
let keptEffectCaches = Env.subgraphMode.contents ? [
|
|
501
197
|
"envio_subgraph_eth_call",
|
|
@@ -506,142 +202,33 @@ function make(client, logger, entitiesOpt, cacheDir, ecosystem, isolatedOpt, onI
|
|
|
506
202
|
"envio_subgraph_arweave"
|
|
507
203
|
] : undefined;
|
|
508
204
|
let cacheDirPath = cacheDir !== undefined ? Primitive_option.valFromOption(cacheDir) : Path.resolve(".envio", "cache");
|
|
509
|
-
let
|
|
510
|
-
let
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
return registered$1;
|
|
514
|
-
}
|
|
515
|
-
let registered$2 = register();
|
|
516
|
-
registry[table.tableName] = registered$2;
|
|
517
|
-
return registered$2;
|
|
518
|
-
};
|
|
519
|
-
let entityTable = entityConfig => registered(entityConfig.table, () => registerEntity(client, entityConfig));
|
|
520
|
-
let ownTable = (table, itemSchema, appendOnly) => registered(table, () => register(client, table, itemSchema, undefined, undefined, appendOnly, undefined));
|
|
521
|
-
let rawEventsTable = () => ownTable(InternalTable.RawEvents.table, InternalTable.RawEvents.schema, true);
|
|
522
|
-
entities.forEach(entityConfig => {
|
|
523
|
-
entityTable(entityConfig);
|
|
205
|
+
let layouts = client.layouts();
|
|
206
|
+
let entityIndexByName = {};
|
|
207
|
+
layouts.entities.forEach((layout, index) => {
|
|
208
|
+
entityIndexByName[layout.name] = index;
|
|
524
209
|
});
|
|
525
|
-
let
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
return registered;
|
|
529
|
-
} else if (Stdlib_Option.isSome(Internal.EffectCache.fromTableName(table.tableName))) {
|
|
530
|
-
return ownTable(table, Internal.cacheItemSchema, undefined);
|
|
531
|
-
} else {
|
|
532
|
-
return Stdlib_JsError.throwWithMessage(`The storage has no table "` + table.tableName + `".`);
|
|
533
|
-
}
|
|
534
|
-
};
|
|
535
|
-
let partitions = (entities, chainIds) => entities.filter(entityConfig => {
|
|
536
|
-
if (entityConfig.storage.postgres) {
|
|
537
|
-
return Stdlib_Option.isSome(Table.getChainIdField(entityConfig.table));
|
|
538
|
-
} else {
|
|
539
|
-
return false;
|
|
540
|
-
}
|
|
541
|
-
}).flatMap(entityConfig => chainIds.map(chainId => ({
|
|
542
|
-
table: entityTable(entityConfig).handle,
|
|
543
|
-
chainId: chainId,
|
|
544
|
-
name: partitionTableName(entityConfig, chainId)
|
|
545
|
-
})));
|
|
210
|
+
let entityWriters = layouts.entities.map(layout => StagedRows.writersOf(layout.fields));
|
|
211
|
+
let rawEventWriters = StagedRows.writersOf(layouts.rawEvents);
|
|
212
|
+
let effectCacheWriters = StagedRows.writersOf(layouts.effectCache);
|
|
546
213
|
let holding = () => client.holding();
|
|
547
|
-
let scanCacheDir = async () => {
|
|
548
|
-
let topEntries;
|
|
549
|
-
try {
|
|
550
|
-
topEntries = await Fs.promises.readdir(cacheDirPath);
|
|
551
|
-
} catch (exn) {
|
|
552
|
-
topEntries = [];
|
|
553
|
-
}
|
|
554
|
-
let result = [];
|
|
555
|
-
await Promise.all(topEntries.map(async entry => {
|
|
556
|
-
let entryPath = Path.join(cacheDirPath, entry);
|
|
557
|
-
let isDir = (await Fs.promises.stat(entryPath)).isDirectory();
|
|
558
|
-
if (isDir) {
|
|
559
|
-
let subEntries = await Fs.promises.readdir(entryPath);
|
|
560
|
-
let tsvs = subEntries.filter(sub => sub.endsWith(".tsv"));
|
|
561
|
-
let chainId = Internal.EffectCache.parseChainId(entry);
|
|
562
|
-
if (chainId === undefined) {
|
|
563
|
-
if (Utils.$$Array.notEmpty(tsvs)) {
|
|
564
|
-
return Stdlib_JsError.throwWithMessage(`Invalid effect cache directory ".envio/cache/` + entry + `". Chain cache directories must be named by a numeric chain id (e.g. "1"). Found cache files: ` + tsvs.join(", ") + `.`);
|
|
565
|
-
} else {
|
|
566
|
-
return;
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
let chainId$1 = Primitive_option.valFromOption(chainId);
|
|
570
|
-
tsvs.forEach(sub => {
|
|
571
|
-
let effectName = sub.slice(0, -4);
|
|
572
|
-
let table = Internal.makeCacheTable(effectName, chainId$1);
|
|
573
|
-
result.push([
|
|
574
|
-
table,
|
|
575
|
-
Path.join(entryPath, sub)
|
|
576
|
-
]);
|
|
577
|
-
});
|
|
578
|
-
return;
|
|
579
|
-
}
|
|
580
|
-
if (!entry.endsWith(".tsv")) {
|
|
581
|
-
return;
|
|
582
|
-
}
|
|
583
|
-
let effectName = entry.slice(0, -4);
|
|
584
|
-
let table = Internal.makeCacheTable(effectName, "crossChain");
|
|
585
|
-
result.push([
|
|
586
|
-
table,
|
|
587
|
-
entryPath
|
|
588
|
-
]);
|
|
589
|
-
}));
|
|
590
|
-
return result;
|
|
591
|
-
};
|
|
592
214
|
let restoreEffectCache = async withUpload => {
|
|
593
|
-
if (withUpload) {
|
|
594
|
-
let entries = await scanCacheDir();
|
|
595
|
-
if (entries.length !== 0) {
|
|
596
|
-
try {
|
|
597
|
-
await client.uploadEffectCache(entries.map(param => ({
|
|
598
|
-
table: ownTable(param[0], Internal.cacheItemSchema, undefined).handle,
|
|
599
|
-
path: param[1]
|
|
600
|
-
})));
|
|
601
|
-
Logger.info(logger, "Successfully uploaded cache.", undefined);
|
|
602
|
-
} catch (raw_exn) {
|
|
603
|
-
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
604
|
-
Logger.errorWithExn(logger, "Failed to upload cache, continuing without it.", exn);
|
|
605
|
-
}
|
|
606
|
-
} else {
|
|
607
|
-
Logger.info(logger, "No saved effect cache to load from .envio/cache.", undefined);
|
|
608
|
-
}
|
|
609
|
-
}
|
|
610
215
|
let cache = {};
|
|
611
|
-
(await client.
|
|
216
|
+
(await client.restoreEffectCache(cacheDirPath, withUpload)).forEach(param => {
|
|
612
217
|
let tableName = param.tableName;
|
|
613
|
-
let
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
};
|
|
621
|
-
return;
|
|
622
|
-
}
|
|
218
|
+
let chainId = param.chainId;
|
|
219
|
+
cache[tableName] = {
|
|
220
|
+
effectName: param.effectName,
|
|
221
|
+
scope: chainId !== undefined ? Primitive_option.valFromOption(chainId) : "crossChain",
|
|
222
|
+
tableName: tableName,
|
|
223
|
+
count: param.rows
|
|
224
|
+
};
|
|
623
225
|
});
|
|
624
226
|
return cache;
|
|
625
227
|
};
|
|
626
|
-
let
|
|
627
|
-
if (isolated) {
|
|
628
|
-
return Primitive_option.some(chainIds);
|
|
629
|
-
}
|
|
630
|
-
};
|
|
631
|
-
let schemaIndexes = (entities, chainIds) => getSchemaIndexes(entities.filter(e => e.storage.postgres), partitionChainIds(chainIds)).map(IndexDefinition.toInput);
|
|
632
|
-
let initialize = async (chainConfigsOpt, entitiesOpt, enumsOpt, contractMapping, envioInfo) => {
|
|
228
|
+
let initialize = async (chainConfigsOpt, contractMapping, envioInfo) => {
|
|
633
229
|
let chainConfigs = chainConfigsOpt !== undefined ? chainConfigsOpt : [];
|
|
634
|
-
let entities = entitiesOpt !== undefined ? entitiesOpt : [];
|
|
635
|
-
let enums = enumsOpt !== undefined ? enumsOpt : [];
|
|
636
230
|
let rowsByChain = chainConfigs.map(chainConfig => ChainState.configStorageRows(chainConfig, ecosystem, contractMapping));
|
|
637
231
|
await client.initialize({
|
|
638
|
-
sequence: CheckpointSequence.fromEntities(entities),
|
|
639
|
-
tables: [rawEventsTable().handle].concat(entities.map(entityConfig => entityTable(entityConfig).handle)),
|
|
640
|
-
partitions: partitions(entities, chainConfigs.map(chainConfig => chainConfig.id)),
|
|
641
|
-
enums: enums.map(enumConfig => ({
|
|
642
|
-
name: enumConfig.name,
|
|
643
|
-
variants: enumConfig.variants
|
|
644
|
-
})),
|
|
645
232
|
chains: chainConfigs.map(toChainConfig),
|
|
646
233
|
envioInfo: JSON.stringify(envioInfo),
|
|
647
234
|
contractNames: ContractMapping.names(contractMapping),
|
|
@@ -649,7 +236,7 @@ function make(client, logger, entitiesOpt, cacheDir, ecosystem, isolatedOpt, onI
|
|
|
649
236
|
keptEffectCaches: keptEffectCaches
|
|
650
237
|
});
|
|
651
238
|
if (eagerSchemaIndexes) {
|
|
652
|
-
await client.ensureSchemaIndexes(
|
|
239
|
+
await client.ensureSchemaIndexes(chainConfigs.map(chainConfig => chainConfig.id));
|
|
653
240
|
}
|
|
654
241
|
let cache = await restoreEffectCache(true);
|
|
655
242
|
if (onInitialize !== undefined) {
|
|
@@ -678,9 +265,11 @@ function make(client, logger, entitiesOpt, cacheDir, ecosystem, isolatedOpt, onI
|
|
|
678
265
|
};
|
|
679
266
|
let loadOrThrow = async (filter, table) => {
|
|
680
267
|
let conditions = LoadFilter.make(filter, table, field => field.pgDbFieldName);
|
|
268
|
+
let entity = entityIndexByName[table.tableName];
|
|
269
|
+
let loading = entity !== undefined ? StorageClient.loadWhere(client, entity, conditions) : StorageClient.loadEffectCache(client, table.tableName, conditions);
|
|
681
270
|
let rows;
|
|
682
271
|
try {
|
|
683
|
-
rows = await
|
|
272
|
+
rows = await loading;
|
|
684
273
|
} catch (raw_exn) {
|
|
685
274
|
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
686
275
|
throw {
|
|
@@ -720,44 +309,17 @@ function make(client, logger, entitiesOpt, cacheDir, ecosystem, isolatedOpt, onI
|
|
|
720
309
|
}));
|
|
721
310
|
return columns;
|
|
722
311
|
};
|
|
723
|
-
let queryTableName = (entityConfig, scope) => {
|
|
724
|
-
if (scope === "crossChain") {
|
|
725
|
-
return entityConfig.table.tableName;
|
|
726
|
-
} else {
|
|
727
|
-
return indexTableNames(entityConfig, partitionChainIds([scope]))[0];
|
|
728
|
-
}
|
|
729
|
-
};
|
|
730
312
|
let ensureQueryIndexes = async (entityConfig, scope, filters) => {
|
|
731
|
-
let building = client.ensureQueryIndexes(
|
|
313
|
+
let building = client.ensureQueryIndexes(entityConfig.index, Stdlib_Null.fromOption(Internal.chainScopeChainId(scope)), filterColumns(entityConfig.table, filters));
|
|
732
314
|
if (building === null) {
|
|
733
315
|
return;
|
|
734
316
|
} else {
|
|
735
317
|
return await building;
|
|
736
318
|
}
|
|
737
319
|
};
|
|
738
|
-
let ensureSchemaIndexes =
|
|
739
|
-
let finalizeBackfill = (
|
|
740
|
-
let dumpEffectCache =
|
|
741
|
-
try {
|
|
742
|
-
let tables = (await client.effectCacheTables()).filter(param => param.rows > 0);
|
|
743
|
-
if (Utils.$$Array.notEmpty(tables)) {
|
|
744
|
-
Logger.info(logger, `Dumping cache: ` + tables.map(param => param.tableName + " (" + param.rows.toString() + " rows)").join(", "), undefined);
|
|
745
|
-
await client.dumpEffectCache(Stdlib_Array.filterMap(tables, param => {
|
|
746
|
-
let tableName = param.tableName;
|
|
747
|
-
return Stdlib_Option.map(Internal.EffectCache.fromTableName(tableName), param => ({
|
|
748
|
-
tableName: tableName,
|
|
749
|
-
path: Path.join(cacheDirPath, Internal.EffectCache.toCachePath(param[0], param[1]))
|
|
750
|
-
}));
|
|
751
|
-
}));
|
|
752
|
-
return Logger.info(logger, `Successfully dumped cache to ` + cacheDirPath, undefined);
|
|
753
|
-
} else {
|
|
754
|
-
return;
|
|
755
|
-
}
|
|
756
|
-
} catch (raw_exn) {
|
|
757
|
-
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
758
|
-
return Logger.errorWithExn(logger, `Failed to dump cache.`, exn);
|
|
759
|
-
}
|
|
760
|
-
};
|
|
320
|
+
let ensureSchemaIndexes = chainIds => client.ensureSchemaIndexes(chainIds);
|
|
321
|
+
let finalizeBackfill = (chainIds, readyAt) => client.finalizeBackfill(chainIds, readyAt.getTime());
|
|
322
|
+
let dumpEffectCache = () => client.dumpEffectCache(cacheDirPath);
|
|
761
323
|
let readStoredConfig = async () => {
|
|
762
324
|
let stored = await client.readStoredConfig();
|
|
763
325
|
let configAddresses = StorageClient.read(client, stored.configAddresses);
|
|
@@ -795,19 +357,14 @@ function make(client, logger, entitiesOpt, cacheDir, ecosystem, isolatedOpt, onI
|
|
|
795
357
|
contractMapping: ContractMapping.fromStoredNames(match$1)
|
|
796
358
|
};
|
|
797
359
|
};
|
|
798
|
-
let addChain = (chainConfig,
|
|
360
|
+
let addChain = (chainConfig, contractMapping) => client.addChain({
|
|
799
361
|
chain: toChainConfig(chainConfig),
|
|
800
|
-
partitions: partitions(entities, [chainConfig.id]),
|
|
801
362
|
addresses: addressColumns(ChainState.configStorageRows(chainConfig, ecosystem, contractMapping))
|
|
802
363
|
});
|
|
803
|
-
let resumeInitialState = async (
|
|
364
|
+
let resumeInitialState = async (chainIds, contractMapping) => {
|
|
804
365
|
let match = await Promise.all([
|
|
805
366
|
restoreEffectCache(false),
|
|
806
|
-
client.resume(
|
|
807
|
-
sequence: CheckpointSequence.fromEntities(entities),
|
|
808
|
-
tables: entities.map(entityConfig => entityTable(entityConfig).handle),
|
|
809
|
-
chainIds: chainIds
|
|
810
|
-
})
|
|
367
|
+
client.resume(chainIds)
|
|
811
368
|
]);
|
|
812
369
|
let resumed = match[1];
|
|
813
370
|
let addressRowsByChainId = AddressRows.group(StorageClient.read(client, resumed.addresses));
|
|
@@ -834,10 +391,10 @@ function make(client, logger, entitiesOpt, cacheDir, ecosystem, isolatedOpt, onI
|
|
|
834
391
|
});
|
|
835
392
|
let checkpointFrontier = Frontier.fromEntries(stored.map(param => [
|
|
836
393
|
param[0],
|
|
837
|
-
|
|
394
|
+
param[1].checkpointId
|
|
838
395
|
]));
|
|
839
396
|
let reorgCheckpoints = resumed.reorgCheckpoints.map(checkpoint => ({
|
|
840
|
-
id:
|
|
397
|
+
id: checkpoint.id,
|
|
841
398
|
chain_id: ChainId.normalizeOrThrow(checkpoint.chainId),
|
|
842
399
|
block_number: checkpoint.blockNumber,
|
|
843
400
|
block_hash: checkpoint.blockHash
|
|
@@ -864,15 +421,15 @@ function make(client, logger, entitiesOpt, cacheDir, ecosystem, isolatedOpt, onI
|
|
|
864
421
|
});
|
|
865
422
|
let setChainMeta = chainsData => client.setChainMeta(chainMeta(chainsData)).then(() => (undefined));
|
|
866
423
|
let pruneStaleCheckpoints = safeCheckpoints => client.pruneCheckpoints(bounds(safeCheckpoints));
|
|
867
|
-
let pruneStaleEntityHistory = (entityConfig, safeCheckpoints) => client.pruneHistory(
|
|
868
|
-
let getRollbackTargetCheckpoint = async (reorgChainId, lastKnownValidBlockNumber
|
|
424
|
+
let pruneStaleEntityHistory = (entityConfig, safeCheckpoints) => client.pruneHistory(entityConfig.index, bounds(safeCheckpoints));
|
|
425
|
+
let getRollbackTargetCheckpoint = async (reorgChainId, lastKnownValidBlockNumber) => Primitive_option.fromNullable(await client.rollbackTargetCheckpoint(reorgChainId, lastKnownValidBlockNumber));
|
|
869
426
|
let getRollbackProgressDiff = async floors => (await client.rollbackProgressDiff(bounds(floors.checkpointBounds))).map(diff => ({
|
|
870
427
|
chain_id: ChainId.normalizeOrThrow(diff.chainId),
|
|
871
428
|
events_processed_diff: diff.eventsProcessed,
|
|
872
429
|
new_progress_block_number: diff.progressBlock
|
|
873
430
|
}));
|
|
874
431
|
let getRollbackData = async (entityConfig, floors) => {
|
|
875
|
-
let match = await client.rollbackData(
|
|
432
|
+
let match = await client.rollbackData(entityConfig.index, bounds(floors.checkpointBounds));
|
|
876
433
|
let restored = match.restored;
|
|
877
434
|
let removedIdRows;
|
|
878
435
|
try {
|
|
@@ -890,29 +447,28 @@ function make(client, logger, entitiesOpt, cacheDir, ecosystem, isolatedOpt, onI
|
|
|
890
447
|
return "crossChain";
|
|
891
448
|
}
|
|
892
449
|
};
|
|
893
|
-
let removals = removedIdRows.map(row => ({
|
|
894
|
-
entityId: S$RescriptSchema.parseOrThrow(row, rollbackRemovedIdSchema(entityConfig.table)),
|
|
895
|
-
scope: scopeOf(row)
|
|
896
|
-
}));
|
|
897
|
-
let restoredEntitiesResult = [];
|
|
898
|
-
rollbackRows.forEach(row => {
|
|
899
|
-
let match = S$RescriptSchema.parseOrThrow(row, rollbackRowStateSchema(entityConfig.table));
|
|
900
|
-
if (match[1] === "SET") {
|
|
901
|
-
restoredEntitiesResult.push(row);
|
|
902
|
-
return;
|
|
903
|
-
}
|
|
904
|
-
removals.push({
|
|
905
|
-
entityId: match[0],
|
|
906
|
-
scope: scopeOf(row)
|
|
907
|
-
});
|
|
908
|
-
});
|
|
909
450
|
return [
|
|
910
|
-
|
|
911
|
-
|
|
451
|
+
removedIdRows.map(row => ({
|
|
452
|
+
entityId: S$RescriptSchema.parseOrThrow(row, rollbackRemovedIdSchema(entityConfig.table)),
|
|
453
|
+
scope: scopeOf(row)
|
|
454
|
+
})),
|
|
455
|
+
S$RescriptSchema.parseOrThrow(rollbackRows, Table.pgRowsSchema(entityConfig.table))
|
|
912
456
|
];
|
|
913
457
|
};
|
|
914
|
-
let
|
|
915
|
-
|
|
458
|
+
let stageRows = (table, writers, items) => stageRowsOrThrow(StorageClient.arena(client, rows => client.beginRows(table, rows)), writers, items);
|
|
459
|
+
let stageChanges = param => {
|
|
460
|
+
let entityConfig = param.entityConfig;
|
|
461
|
+
return stageChangesOrThrow(StorageClient.arena(client, rows => client.beginChanges(entityConfig.index, rows)), entityWriters[entityConfig.index], param.changes);
|
|
462
|
+
};
|
|
463
|
+
let changesErrorOf = (entityConfig, exn) => ({
|
|
464
|
+
RE_EXN_ID: Persistence.StorageError,
|
|
465
|
+
message: entityConfig.storage.postgres ? `Failed to insert items into table "` + entityConfig.table.tableName + `"` : `Failed to convert items for ClickHouse table "` + EntityHistory.historyTableName(entityConfig.name, entityConfig.index) + `"`,
|
|
466
|
+
reason: Utils.prettifyExn(exn)
|
|
467
|
+
});
|
|
468
|
+
let writeBatch = async (batch, rollback, config, updatedEffectsCache, updatedEntities, registeredAddresses, chainMetaData, onWrite) => {
|
|
469
|
+
let frontier = Persistence.writtenFrontier(batch, rollback);
|
|
470
|
+
let chainIds = Frontier.chainIds(frontier);
|
|
471
|
+
let frontierCheckpointIds = chainIds.map(chainId => Frontier.get(frontier, chainId));
|
|
916
472
|
let rawEvents;
|
|
917
473
|
if (config.enableRawEvents) {
|
|
918
474
|
let seenLogCoordinates = new Set();
|
|
@@ -931,21 +487,35 @@ function make(client, logger, entitiesOpt, cacheDir, ecosystem, isolatedOpt, onI
|
|
|
931
487
|
} else {
|
|
932
488
|
rawEvents = [];
|
|
933
489
|
}
|
|
934
|
-
let
|
|
935
|
-
let
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
490
|
+
let handles = [];
|
|
491
|
+
let staged = handle => {
|
|
492
|
+
handles.push(handle);
|
|
493
|
+
return handle;
|
|
494
|
+
};
|
|
495
|
+
let stagingStarted = Performance.now();
|
|
496
|
+
let clickHouseStagingSeconds = {
|
|
497
|
+
contents: 0
|
|
498
|
+
};
|
|
499
|
+
let clickHouseOnlyStagingSeconds = {
|
|
500
|
+
contents: 0
|
|
939
501
|
};
|
|
940
502
|
let input;
|
|
941
503
|
try {
|
|
942
504
|
let tmp;
|
|
943
505
|
if (Utils.$$Array.notEmpty(rawEvents)) {
|
|
944
|
-
let
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
506
|
+
let tmp$1;
|
|
507
|
+
try {
|
|
508
|
+
tmp$1 = staged(stageRows("RawEvents", rawEventWriters, rawEvents));
|
|
509
|
+
} catch (raw_exn) {
|
|
510
|
+
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
511
|
+
throw {
|
|
512
|
+
RE_EXN_ID: Persistence.StorageError,
|
|
513
|
+
message: `Failed to insert items into table "` + InternalTable.RawEvents.table.tableName + `"`,
|
|
514
|
+
reason: Utils.prettifyExn(exn),
|
|
515
|
+
Error: new Error()
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
tmp = tmp$1;
|
|
949
519
|
} else {
|
|
950
520
|
tmp = undefined;
|
|
951
521
|
}
|
|
@@ -954,7 +524,6 @@ function make(client, logger, entitiesOpt, cacheDir, ecosystem, isolatedOpt, onI
|
|
|
954
524
|
let rolledBackAddresses = param.rolledBackAddresses;
|
|
955
525
|
return {
|
|
956
526
|
bounds: bounds(param.floors.checkpointBounds),
|
|
957
|
-
tables: allEntities.map(entityConfig => entityTable(entityConfig).handle),
|
|
958
527
|
progress: param.progressedChains.map(progress),
|
|
959
528
|
removedAddresses: {
|
|
960
529
|
chainIds: rolledBackAddresses.map(key => key.chainId),
|
|
@@ -963,7 +532,7 @@ function make(client, logger, entitiesOpt, cacheDir, ecosystem, isolatedOpt, onI
|
|
|
963
532
|
},
|
|
964
533
|
diffCheckpoints: param.diffCheckpoints.map(diff => ({
|
|
965
534
|
chainId: diff.chainId,
|
|
966
|
-
checkpointId: diff.checkpointId
|
|
535
|
+
checkpointId: diff.checkpointId,
|
|
967
536
|
blockNumber: diff.blockNumber
|
|
968
537
|
}))
|
|
969
538
|
};
|
|
@@ -976,124 +545,41 @@ function make(client, logger, entitiesOpt, cacheDir, ecosystem, isolatedOpt, onI
|
|
|
976
545
|
totalEventsProcessed: chainAfterBatch.totalEventsProcessed
|
|
977
546
|
})),
|
|
978
547
|
rawEvents: tmp,
|
|
979
|
-
|
|
980
|
-
let
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
let
|
|
985
|
-
let
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
type: "SET",
|
|
999
|
-
entityId: change.entityId,
|
|
1000
|
-
entity: Internal.stampChainId(change.entity, field.fieldName, chainId),
|
|
1001
|
-
checkpointId: change.checkpointId
|
|
1002
|
-
};
|
|
1003
|
-
} else {
|
|
1004
|
-
return change;
|
|
1005
|
-
}
|
|
1006
|
-
});
|
|
1007
|
-
} else {
|
|
1008
|
-
stamped = changes;
|
|
1009
|
-
}
|
|
1010
|
-
let diffCheckpointId = Stdlib_Option.flatMap(rollback, r => CheckpointSequence.findForScope(config.checkpointSequence, r.diffFrontier, scope));
|
|
1011
|
-
let historySets = [];
|
|
1012
|
-
let historySetCheckpointIds = [];
|
|
1013
|
-
let historyDeleteIds = [];
|
|
1014
|
-
let historyDeleteCheckpointIds = [];
|
|
1015
|
-
let idsWithDiff = new Set();
|
|
1016
|
-
let latestChangeById = {};
|
|
1017
|
-
let orderedIds = [];
|
|
1018
|
-
stamped.forEach(change => {
|
|
1019
|
-
let entityId = change.entityId;
|
|
1020
|
-
let entityKey = EntityId.toKey(entityId);
|
|
1021
|
-
if (Stdlib_Option.isNone(latestChangeById[entityKey])) {
|
|
1022
|
-
orderedIds.push(entityId);
|
|
1023
|
-
}
|
|
1024
|
-
latestChangeById[entityKey] = change;
|
|
1025
|
-
if (!shouldSaveHistory) {
|
|
1026
|
-
return;
|
|
1027
|
-
}
|
|
1028
|
-
if (change.checkpointId === diffCheckpointId) {
|
|
1029
|
-
idsWithDiff.add(entityKey);
|
|
1030
|
-
return;
|
|
1031
|
-
}
|
|
1032
|
-
if (change.type === "SET") {
|
|
1033
|
-
historySets.push(change.entity);
|
|
1034
|
-
historySetCheckpointIds.push(change.checkpointId.toString());
|
|
1035
|
-
return;
|
|
1036
|
-
}
|
|
1037
|
-
historyDeleteIds.push(change.entityId);
|
|
1038
|
-
historyDeleteCheckpointIds.push(change.checkpointId.toString());
|
|
1039
|
-
});
|
|
1040
|
-
let sets = [];
|
|
1041
|
-
let deletes = [];
|
|
1042
|
-
let backfill = [];
|
|
1043
|
-
orderedIds.forEach(entityId => {
|
|
1044
|
-
let entityKey = EntityId.toKey(entityId);
|
|
1045
|
-
let match = latestChangeById[entityKey];
|
|
1046
|
-
if (match.type === "SET") {
|
|
1047
|
-
sets.push(match.entity);
|
|
1048
|
-
} else {
|
|
1049
|
-
deletes.push(match.entityId);
|
|
1050
|
-
}
|
|
1051
|
-
if (shouldSaveHistory && !idsWithDiff.has(entityKey)) {
|
|
1052
|
-
backfill.push(entityId);
|
|
1053
|
-
return;
|
|
1054
|
-
}
|
|
1055
|
-
});
|
|
1056
|
-
let rowsOf = entities => {
|
|
1057
|
-
if (Utils.$$Array.notEmpty(entities)) {
|
|
1058
|
-
return rowsOrThrow(client, table, getRowSchema(entityConfig), entities, staged);
|
|
1059
|
-
}
|
|
1060
|
-
};
|
|
1061
|
-
return {
|
|
1062
|
-
sets: rowsOf(sets),
|
|
1063
|
-
deletes: renderIds(entityConfig.table, deletes),
|
|
1064
|
-
history: shouldSaveHistory ? ({
|
|
1065
|
-
backfill: renderIds(entityConfig.table, backfill),
|
|
1066
|
-
sets: rowsOf(historySets),
|
|
1067
|
-
setCheckpointIds: historySetCheckpointIds,
|
|
1068
|
-
deleteIds: renderIds(entityConfig.table, historyDeleteIds),
|
|
1069
|
-
deleteCheckpointIds: historyDeleteCheckpointIds
|
|
1070
|
-
}) : undefined
|
|
1071
|
-
};
|
|
1072
|
-
};
|
|
1073
|
-
let match$1 = table.clickhouse;
|
|
1074
|
-
let tmp;
|
|
1075
|
-
if (changes.length !== 0 && match$1 !== undefined) {
|
|
1076
|
-
let handle = stagedFor(staged, "ClickHouse", () => ClickHouse.stageChangesOrThrow(StorageClient.arena(client, "ClickHouse"), match$1, entityConfig, scope, changes));
|
|
1077
|
-
staged_handles.push(handle);
|
|
1078
|
-
tmp = handle;
|
|
1079
|
-
} else {
|
|
1080
|
-
tmp = undefined;
|
|
548
|
+
changes: Stdlib_Array.filterMap(updatedEntities, update => {
|
|
549
|
+
let match = update.changes;
|
|
550
|
+
if (match.length === 0) {
|
|
551
|
+
return;
|
|
552
|
+
}
|
|
553
|
+
let started = Performance.now();
|
|
554
|
+
let handle;
|
|
555
|
+
try {
|
|
556
|
+
handle = staged(stageChanges(update));
|
|
557
|
+
} catch (raw_exn) {
|
|
558
|
+
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
559
|
+
throw changesErrorOf(update.entityConfig, exn);
|
|
560
|
+
}
|
|
561
|
+
let seconds = Performance.secondsSince(started);
|
|
562
|
+
if (update.entityConfig.storage.clickhouse) {
|
|
563
|
+
clickHouseStagingSeconds.contents = clickHouseStagingSeconds.contents + seconds;
|
|
564
|
+
}
|
|
565
|
+
if (!update.entityConfig.storage.postgres) {
|
|
566
|
+
clickHouseOnlyStagingSeconds.contents = clickHouseOnlyStagingSeconds.contents + seconds;
|
|
1081
567
|
}
|
|
1082
568
|
return {
|
|
1083
|
-
|
|
1084
|
-
chainId:
|
|
1085
|
-
|
|
1086
|
-
|
|
569
|
+
entity: update.entityConfig.index,
|
|
570
|
+
chainId: Internal.chainScopeChainId(update.scope),
|
|
571
|
+
keepsHistory: update.shouldSaveHistory,
|
|
572
|
+
changes: handle
|
|
1087
573
|
};
|
|
1088
574
|
}),
|
|
1089
575
|
chainMeta: Stdlib_Option.mapOr(chainMetaData, [], chainMeta),
|
|
1090
576
|
addresses: addressColumns(registeredAddresses.map(staged => staged.row)),
|
|
1091
577
|
frontier: {
|
|
1092
|
-
chainIds:
|
|
1093
|
-
checkpointIds:
|
|
578
|
+
chainIds: chainIds,
|
|
579
|
+
checkpointIds: frontierCheckpointIds
|
|
1094
580
|
},
|
|
1095
581
|
checkpoints: {
|
|
1096
|
-
ids: batch.checkpointIds
|
|
582
|
+
ids: batch.checkpointIds,
|
|
1097
583
|
chainIds: batch.checkpointChainIds,
|
|
1098
584
|
blockNumbers: batch.checkpointBlockNumbers,
|
|
1099
585
|
blockHashes: batch.checkpointBlockHashes,
|
|
@@ -1101,35 +587,59 @@ function make(client, logger, entitiesOpt, cacheDir, ecosystem, isolatedOpt, onI
|
|
|
1101
587
|
keepsHistory: batch.checkpointChainIds.map(chainId => HistoryPolicy.forChain(batch.history, chainId))
|
|
1102
588
|
},
|
|
1103
589
|
effectCaches: updatedEffectsCache.map(param => {
|
|
1104
|
-
let
|
|
590
|
+
let itemSchema = param.itemSchema;
|
|
591
|
+
let table = param.table;
|
|
592
|
+
let tmp;
|
|
593
|
+
try {
|
|
594
|
+
tmp = staged(stageRows("EffectCache", effectCacheWriters, param.items.map(item => S$RescriptSchema.reverseConvertOrThrow(item, itemSchema))));
|
|
595
|
+
} catch (raw_exn) {
|
|
596
|
+
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
597
|
+
if (exn.RE_EXN_ID === S$RescriptSchema.Raised) {
|
|
598
|
+
throw {
|
|
599
|
+
RE_EXN_ID: Persistence.StorageError,
|
|
600
|
+
message: `Failed to convert items for table "` + table.tableName + `"`,
|
|
601
|
+
reason: exn,
|
|
602
|
+
Error: new Error()
|
|
603
|
+
};
|
|
604
|
+
}
|
|
605
|
+
throw {
|
|
606
|
+
RE_EXN_ID: Persistence.StorageError,
|
|
607
|
+
message: `Failed to insert items into table "` + table.tableName + `"`,
|
|
608
|
+
reason: Utils.prettifyExn(exn),
|
|
609
|
+
Error: new Error()
|
|
610
|
+
};
|
|
611
|
+
}
|
|
1105
612
|
return {
|
|
1106
|
-
table:
|
|
613
|
+
table: table.tableName,
|
|
1107
614
|
create: param.shouldInitialize,
|
|
1108
|
-
rows:
|
|
615
|
+
rows: tmp
|
|
1109
616
|
};
|
|
1110
617
|
})
|
|
1111
618
|
};
|
|
1112
|
-
} catch (exn) {
|
|
1113
|
-
client.discardStaged(
|
|
1114
|
-
throw exn;
|
|
619
|
+
} catch (exn$1) {
|
|
620
|
+
client.discardStaged(handles);
|
|
621
|
+
throw exn$1;
|
|
1115
622
|
}
|
|
623
|
+
let postgresStagingSeconds = Performance.secondsSince(stagingStarted) - clickHouseOnlyStagingSeconds.contents;
|
|
1116
624
|
let timings;
|
|
1117
625
|
try {
|
|
1118
626
|
timings = await client.writeBatch(input);
|
|
1119
|
-
} catch (raw_exn) {
|
|
1120
|
-
let exn$
|
|
1121
|
-
client.discardStaged(
|
|
1122
|
-
throw storageErrorOf(exn$
|
|
627
|
+
} catch (raw_exn$1) {
|
|
628
|
+
let exn$2 = Primitive_exceptions.internalToException(raw_exn$1);
|
|
629
|
+
client.discardStaged(handles);
|
|
630
|
+
throw storageErrorOf(exn$2);
|
|
1123
631
|
}
|
|
1124
632
|
timings.forEach(param => {
|
|
1125
|
-
let
|
|
1126
|
-
|
|
633
|
+
let store = param.store;
|
|
634
|
+
let tmp;
|
|
635
|
+
tmp = store === "Postgres" ? postgresStagingSeconds : clickHouseStagingSeconds.contents;
|
|
636
|
+
onWrite(storeName(store), param.seconds + tmp);
|
|
1127
637
|
});
|
|
1128
638
|
};
|
|
1129
639
|
let close = () => client.close();
|
|
1130
640
|
return {
|
|
1131
641
|
name: postgresName,
|
|
1132
|
-
entityStoreName: entityConfig =>
|
|
642
|
+
entityStoreName: entityConfig => Stdlib_Option.mapOr(layouts.entities[entityConfig.index].home, postgresName, storeName),
|
|
1133
643
|
holding: holding,
|
|
1134
644
|
initialize: initialize,
|
|
1135
645
|
readStoredConfig: readStoredConfig,
|
|
@@ -1154,13 +664,13 @@ function make(client, logger, entitiesOpt, cacheDir, ecosystem, isolatedOpt, onI
|
|
|
1154
664
|
|
|
1155
665
|
function clientFromEnv(config, logger, pgSchemaOpt, isHasuraEnabled, maxConnections) {
|
|
1156
666
|
let pgSchema = pgSchemaOpt !== undefined ? pgSchemaOpt : Env.Db.publicSchema;
|
|
1157
|
-
return makeClient(logger, config
|
|
667
|
+
return makeClient(logger, config, postgresOptions(pgSchema, isHasuraEnabled, maxConnections, config.isolated), config.storage.clickhouse ? ClickHouse.optionsFromEnvOrThrow() : undefined);
|
|
1158
668
|
}
|
|
1159
669
|
|
|
1160
670
|
function makeStorageFromEnv(config, logger, pgSchemaOpt, isHasuraEnabledOpt, maxConnections, cacheDir) {
|
|
1161
671
|
let pgSchema = pgSchemaOpt !== undefined ? pgSchemaOpt : Env.Db.publicSchema;
|
|
1162
672
|
let isHasuraEnabled = isHasuraEnabledOpt !== undefined ? isHasuraEnabledOpt : Env.Hasura.enabled;
|
|
1163
|
-
return make(clientFromEnv(config, logger, pgSchema, isHasuraEnabled, maxConnections),
|
|
673
|
+
return make(clientFromEnv(config, logger, pgSchema, isHasuraEnabled, maxConnections), cacheDir, config.ecosystem.name, isHasuraEnabled ? () => Stdlib_Promise.$$catch(Hasura.trackDatabase(logger, Env.Hasura.graphqlEndpoint, {
|
|
1164
674
|
role: Env.Hasura.role,
|
|
1165
675
|
secret: Env.Hasura.secret
|
|
1166
676
|
}, pgSchema, Config.getPgUserEntities(config), Env.Hasura.aggregateEntities, Env.Hasura.responseLimit, Schema.make(config.userEntities.map(e => e.table))), err => Promise.resolve(Logger.errorWithExn(logger, `Error tracking tables`, err))) : undefined);
|
|
@@ -1172,36 +682,24 @@ function makePersistenceFromConfig(config, logger, storageOpt) {
|
|
|
1172
682
|
}
|
|
1173
683
|
|
|
1174
684
|
export {
|
|
1175
|
-
formatSeconds,
|
|
1176
|
-
slowOnLargeDatabaseNotice,
|
|
1177
685
|
storeName,
|
|
1178
686
|
postgresName,
|
|
1179
|
-
logIndexEvent,
|
|
1180
687
|
postgresOptions,
|
|
1181
688
|
makeClient,
|
|
1182
|
-
partitionTableName,
|
|
1183
|
-
indexTableNames,
|
|
1184
|
-
getSchemaIndexes,
|
|
1185
|
-
pgColumnInput,
|
|
1186
|
-
rowSchemaCache,
|
|
1187
|
-
getRowSchema,
|
|
1188
|
-
registerEntity,
|
|
1189
|
-
arenaConverters,
|
|
1190
|
-
cellConverters,
|
|
1191
|
-
converterOf,
|
|
1192
|
-
stagedFor,
|
|
1193
|
-
renderIds,
|
|
1194
689
|
bounds,
|
|
1195
690
|
progress,
|
|
1196
691
|
addressColumns,
|
|
1197
692
|
toChainConfig,
|
|
1198
693
|
storageErrorOf,
|
|
1199
|
-
rollbackRowStateSchema,
|
|
1200
694
|
rollbackChainIdSchema,
|
|
1201
695
|
rollbackRemovedIdSchema,
|
|
696
|
+
changeColumns,
|
|
697
|
+
stageOrThrow,
|
|
698
|
+
stageRowsOrThrow,
|
|
699
|
+
stageChangesOrThrow,
|
|
1202
700
|
make,
|
|
1203
701
|
clientFromEnv,
|
|
1204
702
|
makeStorageFromEnv,
|
|
1205
703
|
makePersistenceFromConfig,
|
|
1206
704
|
}
|
|
1207
|
-
/*
|
|
705
|
+
/* rollbackChainIdSchema Not a pure module */
|