envio 3.15.0 → 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 +11 -2
- package/fuel.schema.json +10 -1
- package/index.d.ts +6 -0
- package/licenses/README.md +1 -1
- package/package.json +10 -9
- package/src/Batch.res.mjs +5 -5
- package/src/BatchProcessing.res +1 -0
- package/src/BatchProcessing.res.mjs +1 -0
- package/src/Bin.res +7 -0
- package/src/Bin.res.mjs +8 -0
- package/src/ChainFetching.res +450 -16
- package/src/ChainFetching.res.mjs +403 -32
- package/src/ChainState.res +124 -7
- package/src/ChainState.res.mjs +128 -67
- package/src/ChainState.resi +26 -0
- package/src/Clock.res +57 -0
- package/src/Clock.res.mjs +72 -0
- package/src/Config.res +31 -3
- package/src/Config.res.mjs +15 -4
- package/src/ContractRegisterContext.res +3 -6
- package/src/ContractRegisterContext.res.mjs +4 -2
- package/src/Core.res +95 -36
- package/src/Core.res.mjs +90 -1
- package/src/CrossChainState.res +12 -2
- package/src/CrossChainState.res.mjs +3 -3
- package/src/Ecosystem.res +7 -4
- package/src/Ecosystem.res.mjs +8 -8
- package/src/EffectCacheLookup.res +98 -0
- package/src/EffectCacheLookup.res.mjs +116 -0
- 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 +20 -0
- package/src/Env.res.mjs +16 -0
- package/src/EventProcessing.res +38 -1
- package/src/EventProcessing.res.mjs +28 -1
- package/src/FetchState.res +408 -73
- package/src/FetchState.res.mjs +361 -91
- package/src/FinalizeBackfill.res +2 -4
- package/src/FinalizeBackfill.res.mjs +3 -4
- package/src/HandlerLoader.res +39 -15
- package/src/HandlerLoader.res.mjs +27 -8
- package/src/HandlerRegister.res +4 -0
- package/src/HandlerRegister.res.mjs +5 -2
- package/src/HandlerRegister.resi +2 -0
- 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 +61 -49
- package/src/Internal.res.mjs +36 -80
- package/src/LoadLayer.res +54 -15
- package/src/LoadLayer.res.mjs +75 -45
- package/src/LoadLayer.resi +26 -0
- package/src/Main.res +14 -1
- package/src/Main.res.mjs +4 -3
- package/src/Persistence.res +3 -23
- package/src/Persistence.res.mjs +3 -3
- package/src/PreloadLookahead.res +202 -0
- package/src/PreloadLookahead.res.mjs +218 -0
- package/src/Rollback.res +0 -1
- package/src/Rollback.res.mjs +1 -1
- package/src/RunScope.res +3 -0
- package/src/SafeCheckpointTracking.res +4 -4
- package/src/SafeCheckpointTracking.res.mjs +1 -1
- package/src/SimulateItems.res +42 -26
- package/src/SimulateItems.res.mjs +40 -16
- 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 +303 -948
- package/src/Storage.res.mjs +229 -708
- package/src/SubgraphLog.res +19 -0
- package/src/SubgraphLog.res.mjs +26 -0
- package/src/Supervisor.res +75 -56
- package/src/Supervisor.res.mjs +55 -26
- package/src/SyncWrites.res +107 -0
- package/src/SyncWrites.res.mjs +98 -0
- 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 +419 -46
- package/src/UserContext.res.mjs +318 -30
- package/src/Utils.res +17 -6
- package/src/Utils.res.mjs +12 -6
- 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 +108 -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/AddressSet.res +2 -0
- package/src/sources/AddressStore.res +3 -0
- package/src/sources/CallSource.res +274 -0
- package/src/sources/CallSource.res.mjs +196 -0
- package/src/sources/ChainSources.res +2 -0
- package/src/sources/ChainSources.res.mjs +2 -2
- package/src/sources/EvmChain.res +10 -1
- package/src/sources/EvmChain.res.mjs +6 -3
- 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/HyperSync.res +2 -1
- package/src/sources/HyperSync.res.mjs +2 -1
- 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 +84 -77
- package/src/sources/SourceManager.res.mjs +17 -20
- package/src/sources/SourceManager.resi +3 -4
- package/src/sources/StartBlockResolver.res +1 -0
- package/src/sources/StartBlockResolver.res.mjs +3 -2
- package/src/sources/SvmHyperSyncSource.res +2 -2
- package/src/sources/SvmHyperSyncSource.res.mjs +1 -1
- package/src/subgraph/abi-types.ts +84 -0
- package/src/subgraph/aggregations.ts +745 -0
- package/src/subgraph/as-package.ts +143 -0
- package/src/subgraph/assemblyscript-regex.ts +67 -0
- package/src/subgraph/assemblyscript.ts +731 -0
- package/src/subgraph/blocks.ts +398 -0
- package/src/subgraph/calls-source.ts +702 -0
- package/src/subgraph/calls.ts +258 -0
- package/src/subgraph/conformance.ts +106 -0
- package/src/subgraph/errors.ts +85 -0
- package/src/subgraph/graft.ts +73 -0
- package/src/subgraph/graph-cli-worker.mjs +35 -0
- package/src/subgraph/graph-cli.ts +900 -0
- package/src/subgraph/graph-node-decimal.ts +199 -0
- package/src/subgraph/graph-ts-enums.ts +28 -0
- package/src/subgraph/graph-ts-types/VERSION +2 -0
- package/src/subgraph/graph-ts-types/chain/arweave.d.ts +70 -0
- package/src/subgraph/graph-ts-types/chain/cosmos.d.ts +327 -0
- package/src/subgraph/graph-ts-types/chain/ethereum.d.ts +233 -0
- package/src/subgraph/graph-ts-types/chain/near.d.ts +253 -0
- package/src/subgraph/graph-ts-types/chain/starknet.d.ts +32 -0
- package/src/subgraph/graph-ts-types/common/collections.d.ts +136 -0
- package/src/subgraph/graph-ts-types/common/conversion.d.ts +11 -0
- package/src/subgraph/graph-ts-types/common/datasource.d.ts +30 -0
- package/src/subgraph/graph-ts-types/common/eager-offset.d.ts +0 -0
- package/src/subgraph/graph-ts-types/common/json.d.ts +17 -0
- package/src/subgraph/graph-ts-types/common/numbers.d.ts +120 -0
- package/src/subgraph/graph-ts-types/common/value.d.ts +120 -0
- package/src/subgraph/graph-ts-types/common/yaml.d.ts +90 -0
- package/src/subgraph/graph-ts-types/global/global.d.ts +194 -0
- package/src/subgraph/graph-ts-types/helper-functions.d.ts +22 -0
- package/src/subgraph/graph-ts-types/index.d.ts +102 -0
- package/src/subgraph/graph-ts.ts +4339 -0
- package/src/subgraph/hosts.ts +554 -0
- package/src/subgraph/log.ts +28 -0
- package/src/subgraph/receipts.ts +184 -0
- package/src/subgraph/register-slots.ts +93 -0
- package/src/subgraph/rollup.ts +109 -0
- package/src/subgraph/rpc.ts +337 -0
- package/src/subgraph/runtime.ts +2059 -0
- package/src/subgraph/scope.ts +176 -0
- package/src/subgraph/stats.ts +42 -0
- package/src/subgraph/template-instances.ts +66 -0
- package/src/subgraph/toolchain.ts +327 -0
- package/src/subgraph/transient.ts +176 -0
- package/svm.schema.json +11 -2
- 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 -67
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,288 +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
|
-
all.push(IndexDefinition.single(derivedFromField.derivedFromEntity, column));
|
|
194
|
-
});
|
|
195
|
-
});
|
|
196
|
-
let seen = new Set();
|
|
197
|
-
let entityByTableName = {};
|
|
198
|
-
entities.forEach(entityConfig => {
|
|
199
|
-
entityByTableName[entityConfig.table.tableName] = entityConfig;
|
|
200
|
-
});
|
|
201
|
-
return all.filter(definition => {
|
|
202
|
-
let identity = IndexDefinition.describe(definition);
|
|
203
|
-
if (seen.has(identity)) {
|
|
204
|
-
return false;
|
|
205
|
-
} else {
|
|
206
|
-
seen.add(identity);
|
|
207
|
-
return true;
|
|
208
|
-
}
|
|
209
|
-
}).flatMap(definition => indexTableNames(Stdlib_Option.getOrThrow(entityByTableName[definition.tableName], undefined), partitionChainIds).map(tableName => ({
|
|
210
|
-
tableName: tableName,
|
|
211
|
-
columns: definition.columns,
|
|
212
|
-
method: definition.method
|
|
213
|
-
})));
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
function pgColumnInput(field) {
|
|
217
|
-
let match = Table.pgFieldTypeParts(field.fieldType);
|
|
218
|
-
return {
|
|
219
|
-
name: Table.getPgDbFieldName(field),
|
|
220
|
-
fieldType: match[0],
|
|
221
|
-
isArray: field.isArray,
|
|
222
|
-
isNullable: field.isNullable,
|
|
223
|
-
isPrimaryKey: field.isPrimaryKey,
|
|
224
|
-
defaultValue: field.defaultValue,
|
|
225
|
-
precision: match[1],
|
|
226
|
-
scale: match[2],
|
|
227
|
-
enumName: match[3]
|
|
228
|
-
};
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
let rowSchemaCache = new WeakMap();
|
|
232
|
-
|
|
233
|
-
function getRowSchema(entityConfig) {
|
|
234
|
-
let cached = rowSchemaCache.get(entityConfig);
|
|
235
|
-
if (cached !== undefined) {
|
|
236
|
-
return Primitive_option.valFromOption(cached);
|
|
237
|
-
}
|
|
238
|
-
let chainIdField = Table.getChainIdField(entityConfig.table);
|
|
239
|
-
let schema = chainIdField !== undefined ? S$RescriptSchema.schema(s => {
|
|
240
|
-
let dict = {};
|
|
241
|
-
let match = entityConfig.schema.t;
|
|
242
|
-
let exit = 0;
|
|
243
|
-
if (typeof match !== "object" || match.TAG !== "object") {
|
|
244
|
-
exit = 1;
|
|
245
|
-
} else {
|
|
246
|
-
match.items.forEach(param => {
|
|
247
|
-
dict[param.location] = s.m(param.schema);
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
|
-
if (exit === 1) {
|
|
251
|
-
Stdlib_JsError.throwWithMessage(`Unexpected non-object schema for entity "` + entityConfig.name + `".`);
|
|
252
|
-
}
|
|
253
|
-
dict[chainIdField.fieldName] = s.m(ChainId.schema);
|
|
254
|
-
return dict;
|
|
255
|
-
}) : entityConfig.schema;
|
|
256
|
-
rowSchemaCache.set(entityConfig, schema);
|
|
257
|
-
return schema;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
function register(client, table, itemSchema, postgresOpt, clickhouse, appendOnlyOpt, history) {
|
|
261
|
-
let postgres = postgresOpt !== undefined ? postgresOpt : true;
|
|
262
|
-
let appendOnly = appendOnlyOpt !== undefined ? appendOnlyOpt : false;
|
|
263
|
-
let fields = Table.schemaOrderedFields(table, itemSchema);
|
|
264
|
-
let chainIdField = Table.getChainIdField(table);
|
|
265
|
-
let registered = client.registerTable({
|
|
266
|
-
name: table.tableName,
|
|
267
|
-
postgres: postgres ? ({
|
|
268
|
-
columns: Table.getFields(table).map(pgColumnInput),
|
|
269
|
-
writeColumns: fields.map(Table.getPgDbFieldName),
|
|
270
|
-
partitionByColumn: Stdlib_Option.map(chainIdField, Table.getPgDbFieldName),
|
|
271
|
-
appendOnly: appendOnly,
|
|
272
|
-
historyTable: history,
|
|
273
|
-
chainIdColumn: history !== undefined ? Stdlib_Option.map(chainIdField, Table.getPgDbFieldName) : undefined
|
|
274
|
-
}) : undefined,
|
|
275
|
-
clickhouse: clickhouse
|
|
276
|
-
});
|
|
277
|
-
return {
|
|
278
|
-
handle: registered.handle,
|
|
279
|
-
home: registered.home,
|
|
280
|
-
table: table,
|
|
281
|
-
fields: fields,
|
|
282
|
-
postgres: Stdlib_Option.map(registered.postgres, param => ({
|
|
283
|
-
staged: Stdlib_Option.map(param.kinds, kinds => PgWriting.columns(fields, kinds.map(Staging.kindOfOrdinal)))
|
|
284
|
-
})),
|
|
285
|
-
clickhouse: Stdlib_Option.map(registered.clickhouse, __x => ClickHouse.makeTable(registered.handle, Stdlib_Option.getOr(history, table.tableName), __x))
|
|
286
|
-
};
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
function registerEntity(client, entityConfig) {
|
|
290
|
-
return register(client, entityConfig.table, getRowSchema(entityConfig), entityConfig.storage.postgres, entityConfig.storage.clickhouse ? ClickHouse.entityTable(entityConfig) : undefined, undefined, EntityHistory.historyTableName(entityConfig.name, entityConfig.index));
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
function renderDocument(value, isNullable) {
|
|
294
|
-
if (value == null) {
|
|
295
|
-
if (value === null && !isNullable) {
|
|
296
|
-
return "null";
|
|
297
|
-
} else {
|
|
298
|
-
return value;
|
|
299
|
-
}
|
|
300
|
-
} else {
|
|
301
|
-
return Sql.stringifyDocument(value);
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
let arenaConverters = new WeakMap();
|
|
306
|
-
|
|
307
|
-
let cellConverters = new WeakMap();
|
|
308
|
-
|
|
309
|
-
function converterOf(registered, forArena, itemSchema) {
|
|
310
|
-
let converters = forArena ? arenaConverters : cellConverters;
|
|
311
|
-
let convert = converters.get(itemSchema);
|
|
312
|
-
if (convert !== undefined) {
|
|
313
|
-
return convert;
|
|
314
|
-
}
|
|
315
|
-
let documents = Stdlib_Array.filterMapWithIndex(registered.fields, (field, index) => {
|
|
316
|
-
if (field.fieldType === "Json") {
|
|
317
|
-
return [
|
|
318
|
-
index,
|
|
319
|
-
field
|
|
320
|
-
];
|
|
321
|
-
}
|
|
322
|
-
});
|
|
323
|
-
let schema = forArena ? Table.toDbSchema(registered.table, itemSchema) : itemSchema;
|
|
324
|
-
let convert$1 = S$RescriptSchema.compile(S$RescriptSchema.preprocess(S$RescriptSchema.unnest(schema), param => ({
|
|
325
|
-
s: columns => {
|
|
326
|
-
documents.forEach(param => {
|
|
327
|
-
let field = param[1];
|
|
328
|
-
let values = columns[param[0]];
|
|
329
|
-
for (let row = 0, row_finish = values.length; row < row_finish; ++row) {
|
|
330
|
-
let value = values[row];
|
|
331
|
-
values[row] = !(value == null) && field.isArray ? value.map(document => renderDocument(document, true)) : renderDocument(value, field.isNullable);
|
|
332
|
-
}
|
|
333
|
-
});
|
|
334
|
-
return columns;
|
|
335
|
-
}
|
|
336
|
-
})), "Output", "Input", "Sync", false);
|
|
337
|
-
converters.set(itemSchema, convert$1);
|
|
338
|
-
return convert$1;
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
function refuseNonFinite(values, fields) {
|
|
342
|
-
fields.forEach((field, index) => {
|
|
343
|
-
if (field.fieldType !== "Number") {
|
|
344
|
-
return;
|
|
345
|
-
}
|
|
346
|
-
let column = Table.getPgDbFieldName(field);
|
|
347
|
-
let check = value => {
|
|
348
|
-
if (value == null) {
|
|
349
|
-
return;
|
|
350
|
-
}
|
|
351
|
-
Staging.finiteOrThrow(value, column);
|
|
352
|
-
};
|
|
353
|
-
values[index].forEach(value => {
|
|
354
|
-
if (!field.isArray) {
|
|
355
|
-
return check(value);
|
|
356
|
-
}
|
|
357
|
-
if (value == null) {
|
|
358
|
-
return;
|
|
359
|
-
}
|
|
360
|
-
value.forEach(check);
|
|
361
|
-
});
|
|
362
|
-
});
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
function stagedFor(staged, store, stage) {
|
|
366
|
-
let started = Performance.now();
|
|
367
|
-
let result = stage();
|
|
368
|
-
let name = storeName(store);
|
|
369
|
-
staged.seconds[name] = Stdlib_Option.getOr(staged.seconds[name], 0) + Performance.secondsSince(started);
|
|
370
|
-
return result;
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
function rowsOrThrow(client, registered, itemSchema, items, staged) {
|
|
374
|
-
return stagedFor(staged, "Postgres", () => {
|
|
375
|
-
let rows = items.length;
|
|
376
|
-
try {
|
|
377
|
-
let match = registered.postgres;
|
|
378
|
-
if (match === undefined) {
|
|
379
|
-
return Stdlib_JsError.throwWithMessage(`Postgres doesn't keep "` + registered.table.tableName + `"`);
|
|
380
|
-
}
|
|
381
|
-
let columns = match.staged;
|
|
382
|
-
if (columns !== undefined) {
|
|
383
|
-
let values = converterOf(registered, true, itemSchema)(items);
|
|
384
|
-
let handle = PgWriting.stage(StorageClient.arena(client, "Postgres"), registered.handle, columns, values, rows);
|
|
385
|
-
staged.handles.push(handle);
|
|
386
|
-
return {
|
|
387
|
-
staged: handle,
|
|
388
|
-
rows: rows
|
|
389
|
-
};
|
|
390
|
-
}
|
|
391
|
-
let values$1 = converterOf(registered, false, itemSchema)(items);
|
|
392
|
-
refuseNonFinite(values$1, registered.fields);
|
|
393
|
-
return {
|
|
394
|
-
cells: Sql.params(values$1.flat(1)),
|
|
395
|
-
rows: rows
|
|
396
|
-
};
|
|
397
|
-
} catch (raw_exn) {
|
|
398
|
-
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
399
|
-
if (exn.RE_EXN_ID === S$RescriptSchema.Raised) {
|
|
400
|
-
throw {
|
|
401
|
-
RE_EXN_ID: Persistence.StorageError,
|
|
402
|
-
message: `Failed to convert items for table "` + registered.table.tableName + `"`,
|
|
403
|
-
reason: exn,
|
|
404
|
-
Error: new Error()
|
|
405
|
-
};
|
|
406
|
-
}
|
|
407
|
-
throw {
|
|
408
|
-
RE_EXN_ID: Persistence.StorageError,
|
|
409
|
-
message: `Failed to insert items into table "` + registered.table.tableName + `"`,
|
|
410
|
-
reason: Utils.prettifyExn(exn),
|
|
411
|
-
Error: new Error()
|
|
412
|
-
};
|
|
413
|
-
}
|
|
414
|
-
});
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
function renderIds(table, ids) {
|
|
418
|
-
return Table.encodeIdsToJson(table, ids).map(Sql.render);
|
|
72
|
+
}, Stdlib_Option.map(config, config => JSON.stringify(config.envioInfo)), logger);
|
|
419
73
|
}
|
|
420
74
|
|
|
421
75
|
function bounds(param) {
|
|
422
|
-
let
|
|
76
|
+
let byChain = param.byChain;
|
|
423
77
|
return {
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
checkpointIds: match[1]
|
|
78
|
+
chainIds: Frontier.chainIds(byChain),
|
|
79
|
+
checkpointIds: Frontier.chainIds(byChain).map(chainId => Frontier.get(byChain, chainId))
|
|
427
80
|
};
|
|
428
81
|
}
|
|
429
82
|
|
|
@@ -474,154 +127,117 @@ function storageErrorOf(exn) {
|
|
|
474
127
|
}
|
|
475
128
|
}
|
|
476
129
|
|
|
477
|
-
let rollbackRowStateSchema = Utils.$$WeakMap.memoize(table => S$RescriptSchema.object(s => [
|
|
478
|
-
s.f(Table.idFieldName, Table.getIdSchema(table)),
|
|
479
|
-
s.f(EntityHistory.changeFieldName, EntityHistory.RowAction.schema)
|
|
480
|
-
]));
|
|
481
|
-
|
|
482
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))));
|
|
483
131
|
|
|
484
132
|
let rollbackRemovedIdSchema = Utils.$$WeakMap.memoize(table => S$RescriptSchema.object(s => s.f(Table.idFieldName, Table.getIdSchema(table))));
|
|
485
133
|
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
let
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
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
|
+
});
|
|
505
163
|
});
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
table: entityTable(entityConfig).handle,
|
|
524
|
-
chainId: chainId,
|
|
525
|
-
name: partitionTableName(entityConfig, chainId)
|
|
526
|
-
})));
|
|
527
|
-
let holding = () => client.holding();
|
|
528
|
-
let scanCacheDir = async () => {
|
|
529
|
-
let topEntries;
|
|
530
|
-
try {
|
|
531
|
-
topEntries = await Fs.promises.readdir(cacheDirPath);
|
|
532
|
-
} catch (exn) {
|
|
533
|
-
topEntries = [];
|
|
534
|
-
}
|
|
535
|
-
let result = [];
|
|
536
|
-
await Promise.all(topEntries.map(async entry => {
|
|
537
|
-
let entryPath = Path.join(cacheDirPath, entry);
|
|
538
|
-
let isDir = (await Fs.promises.stat(entryPath)).isDirectory();
|
|
539
|
-
if (isDir) {
|
|
540
|
-
let subEntries = await Fs.promises.readdir(entryPath);
|
|
541
|
-
let tsvs = subEntries.filter(sub => sub.endsWith(".tsv"));
|
|
542
|
-
let chainId = Internal.EffectCache.parseChainId(entry);
|
|
543
|
-
if (chainId === undefined) {
|
|
544
|
-
if (Utils.$$Array.notEmpty(tsvs)) {
|
|
545
|
-
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(", ") + `.`);
|
|
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);
|
|
546
181
|
} else {
|
|
547
|
-
return;
|
|
182
|
+
return Staging.writeDeletedValue(stage, column, row, undefined);
|
|
548
183
|
}
|
|
549
|
-
}
|
|
550
|
-
let chainId$1 = Primitive_option.valFromOption(chainId);
|
|
551
|
-
tsvs.forEach(sub => {
|
|
552
|
-
let effectName = sub.slice(0, -4);
|
|
553
|
-
let table = Internal.makeCacheTable(effectName, chainId$1);
|
|
554
|
-
result.push([
|
|
555
|
-
table,
|
|
556
|
-
Path.join(entryPath, sub)
|
|
557
|
-
]);
|
|
558
184
|
});
|
|
559
|
-
return;
|
|
560
|
-
}
|
|
561
|
-
if (!entry.endsWith(".tsv")) {
|
|
562
|
-
return;
|
|
563
185
|
}
|
|
564
|
-
|
|
565
|
-
let
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
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) {
|
|
195
|
+
let eagerSchemaIndexes = Env.subgraphMode.contents;
|
|
196
|
+
let keptEffectCaches = Env.subgraphMode.contents ? [
|
|
197
|
+
"envio_subgraph_eth_call",
|
|
198
|
+
"envio_subgraph_eth_balance",
|
|
199
|
+
"envio_subgraph_has_code",
|
|
200
|
+
"envio_subgraph_file",
|
|
201
|
+
"envio_subgraph_ipfs_cat",
|
|
202
|
+
"envio_subgraph_arweave"
|
|
203
|
+
] : undefined;
|
|
204
|
+
let cacheDirPath = cacheDir !== undefined ? Primitive_option.valFromOption(cacheDir) : Path.resolve(".envio", "cache");
|
|
205
|
+
let layouts = client.layouts();
|
|
206
|
+
let entityIndexByName = {};
|
|
207
|
+
layouts.entities.forEach((layout, index) => {
|
|
208
|
+
entityIndexByName[layout.name] = index;
|
|
209
|
+
});
|
|
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);
|
|
213
|
+
let holding = () => client.holding();
|
|
573
214
|
let restoreEffectCache = async withUpload => {
|
|
574
|
-
if (withUpload) {
|
|
575
|
-
let entries = await scanCacheDir();
|
|
576
|
-
if (entries.length !== 0) {
|
|
577
|
-
try {
|
|
578
|
-
await client.uploadEffectCache(entries.map(param => ({
|
|
579
|
-
table: ownTable(param[0], Internal.cacheItemSchema, undefined).handle,
|
|
580
|
-
path: param[1]
|
|
581
|
-
})));
|
|
582
|
-
Logger.info(logger, "Successfully uploaded cache.", undefined);
|
|
583
|
-
} catch (raw_exn) {
|
|
584
|
-
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
585
|
-
Logger.errorWithExn(logger, "Failed to upload cache, continuing without it.", exn);
|
|
586
|
-
}
|
|
587
|
-
} else {
|
|
588
|
-
Logger.info(logger, "No saved effect cache to load from .envio/cache.", undefined);
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
215
|
let cache = {};
|
|
592
|
-
(await client.
|
|
216
|
+
(await client.restoreEffectCache(cacheDirPath, withUpload)).forEach(param => {
|
|
593
217
|
let tableName = param.tableName;
|
|
594
|
-
let
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
};
|
|
602
|
-
return;
|
|
603
|
-
}
|
|
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
|
+
};
|
|
604
225
|
});
|
|
605
226
|
return cache;
|
|
606
227
|
};
|
|
607
|
-
let initialize = async (chainConfigsOpt,
|
|
228
|
+
let initialize = async (chainConfigsOpt, contractMapping, envioInfo) => {
|
|
608
229
|
let chainConfigs = chainConfigsOpt !== undefined ? chainConfigsOpt : [];
|
|
609
|
-
let entities = entitiesOpt !== undefined ? entitiesOpt : [];
|
|
610
|
-
let enums = enumsOpt !== undefined ? enumsOpt : [];
|
|
611
230
|
let rowsByChain = chainConfigs.map(chainConfig => ChainState.configStorageRows(chainConfig, ecosystem, contractMapping));
|
|
612
231
|
await client.initialize({
|
|
613
|
-
sequence: CheckpointSequence.fromEntities(entities),
|
|
614
|
-
tables: [rawEventsTable().handle].concat(entities.map(entityConfig => entityTable(entityConfig).handle)),
|
|
615
|
-
partitions: partitions(entities, chainConfigs.map(chainConfig => chainConfig.id)),
|
|
616
|
-
enums: enums.map(enumConfig => ({
|
|
617
|
-
name: enumConfig.name,
|
|
618
|
-
variants: enumConfig.variants
|
|
619
|
-
})),
|
|
620
232
|
chains: chainConfigs.map(toChainConfig),
|
|
621
233
|
envioInfo: JSON.stringify(envioInfo),
|
|
622
234
|
contractNames: ContractMapping.names(contractMapping),
|
|
623
|
-
addresses: addressColumns(rowsByChain.flat())
|
|
235
|
+
addresses: addressColumns(rowsByChain.flat()),
|
|
236
|
+
keptEffectCaches: keptEffectCaches
|
|
624
237
|
});
|
|
238
|
+
if (eagerSchemaIndexes) {
|
|
239
|
+
await client.ensureSchemaIndexes(chainConfigs.map(chainConfig => chainConfig.id));
|
|
240
|
+
}
|
|
625
241
|
let cache = await restoreEffectCache(true);
|
|
626
242
|
if (onInitialize !== undefined) {
|
|
627
243
|
await onInitialize();
|
|
@@ -649,9 +265,11 @@ function make(client, logger, entitiesOpt, cacheDir, ecosystem, isolatedOpt, onI
|
|
|
649
265
|
};
|
|
650
266
|
let loadOrThrow = async (filter, table) => {
|
|
651
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);
|
|
652
270
|
let rows;
|
|
653
271
|
try {
|
|
654
|
-
rows = await
|
|
272
|
+
rows = await loading;
|
|
655
273
|
} catch (raw_exn) {
|
|
656
274
|
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
657
275
|
throw {
|
|
@@ -691,50 +309,17 @@ function make(client, logger, entitiesOpt, cacheDir, ecosystem, isolatedOpt, onI
|
|
|
691
309
|
}));
|
|
692
310
|
return columns;
|
|
693
311
|
};
|
|
694
|
-
let partitionChainIds = chainIds => {
|
|
695
|
-
if (isolated) {
|
|
696
|
-
return Primitive_option.some(chainIds);
|
|
697
|
-
}
|
|
698
|
-
};
|
|
699
|
-
let queryTableName = (entityConfig, scope) => {
|
|
700
|
-
if (scope === "crossChain") {
|
|
701
|
-
return entityConfig.table.tableName;
|
|
702
|
-
} else {
|
|
703
|
-
return indexTableNames(entityConfig, partitionChainIds([scope]))[0];
|
|
704
|
-
}
|
|
705
|
-
};
|
|
706
312
|
let ensureQueryIndexes = async (entityConfig, scope, filters) => {
|
|
707
|
-
let building = client.ensureQueryIndexes(
|
|
313
|
+
let building = client.ensureQueryIndexes(entityConfig.index, Stdlib_Null.fromOption(Internal.chainScopeChainId(scope)), filterColumns(entityConfig.table, filters));
|
|
708
314
|
if (building === null) {
|
|
709
315
|
return;
|
|
710
316
|
} else {
|
|
711
317
|
return await building;
|
|
712
318
|
}
|
|
713
319
|
};
|
|
714
|
-
let
|
|
715
|
-
let
|
|
716
|
-
let
|
|
717
|
-
let dumpEffectCache = async () => {
|
|
718
|
-
try {
|
|
719
|
-
let tables = (await client.effectCacheTables()).filter(param => param.rows > 0);
|
|
720
|
-
if (Utils.$$Array.notEmpty(tables)) {
|
|
721
|
-
Logger.info(logger, `Dumping cache: ` + tables.map(param => param.tableName + " (" + param.rows.toString() + " rows)").join(", "), undefined);
|
|
722
|
-
await client.dumpEffectCache(Stdlib_Array.filterMap(tables, param => {
|
|
723
|
-
let tableName = param.tableName;
|
|
724
|
-
return Stdlib_Option.map(Internal.EffectCache.fromTableName(tableName), param => ({
|
|
725
|
-
tableName: tableName,
|
|
726
|
-
path: Path.join(cacheDirPath, Internal.EffectCache.toCachePath(param[0], param[1]))
|
|
727
|
-
}));
|
|
728
|
-
}));
|
|
729
|
-
return Logger.info(logger, `Successfully dumped cache to ` + cacheDirPath, undefined);
|
|
730
|
-
} else {
|
|
731
|
-
return;
|
|
732
|
-
}
|
|
733
|
-
} catch (raw_exn) {
|
|
734
|
-
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
735
|
-
return Logger.errorWithExn(logger, `Failed to dump cache.`, exn);
|
|
736
|
-
}
|
|
737
|
-
};
|
|
320
|
+
let ensureSchemaIndexes = chainIds => client.ensureSchemaIndexes(chainIds);
|
|
321
|
+
let finalizeBackfill = (chainIds, readyAt) => client.finalizeBackfill(chainIds, readyAt.getTime());
|
|
322
|
+
let dumpEffectCache = () => client.dumpEffectCache(cacheDirPath);
|
|
738
323
|
let readStoredConfig = async () => {
|
|
739
324
|
let stored = await client.readStoredConfig();
|
|
740
325
|
let configAddresses = StorageClient.read(client, stored.configAddresses);
|
|
@@ -772,19 +357,14 @@ function make(client, logger, entitiesOpt, cacheDir, ecosystem, isolatedOpt, onI
|
|
|
772
357
|
contractMapping: ContractMapping.fromStoredNames(match$1)
|
|
773
358
|
};
|
|
774
359
|
};
|
|
775
|
-
let addChain = (chainConfig,
|
|
360
|
+
let addChain = (chainConfig, contractMapping) => client.addChain({
|
|
776
361
|
chain: toChainConfig(chainConfig),
|
|
777
|
-
partitions: partitions(entities, [chainConfig.id]),
|
|
778
362
|
addresses: addressColumns(ChainState.configStorageRows(chainConfig, ecosystem, contractMapping))
|
|
779
363
|
});
|
|
780
|
-
let resumeInitialState = async (
|
|
364
|
+
let resumeInitialState = async (chainIds, contractMapping) => {
|
|
781
365
|
let match = await Promise.all([
|
|
782
366
|
restoreEffectCache(false),
|
|
783
|
-
client.resume(
|
|
784
|
-
sequence: CheckpointSequence.fromEntities(entities),
|
|
785
|
-
tables: entities.map(entityConfig => entityTable(entityConfig).handle),
|
|
786
|
-
chainIds: chainIds
|
|
787
|
-
})
|
|
367
|
+
client.resume(chainIds)
|
|
788
368
|
]);
|
|
789
369
|
let resumed = match[1];
|
|
790
370
|
let addressRowsByChainId = AddressRows.group(StorageClient.read(client, resumed.addresses));
|
|
@@ -811,10 +391,10 @@ function make(client, logger, entitiesOpt, cacheDir, ecosystem, isolatedOpt, onI
|
|
|
811
391
|
});
|
|
812
392
|
let checkpointFrontier = Frontier.fromEntries(stored.map(param => [
|
|
813
393
|
param[0],
|
|
814
|
-
|
|
394
|
+
param[1].checkpointId
|
|
815
395
|
]));
|
|
816
396
|
let reorgCheckpoints = resumed.reorgCheckpoints.map(checkpoint => ({
|
|
817
|
-
id:
|
|
397
|
+
id: checkpoint.id,
|
|
818
398
|
chain_id: ChainId.normalizeOrThrow(checkpoint.chainId),
|
|
819
399
|
block_number: checkpoint.blockNumber,
|
|
820
400
|
block_hash: checkpoint.blockHash
|
|
@@ -841,15 +421,15 @@ function make(client, logger, entitiesOpt, cacheDir, ecosystem, isolatedOpt, onI
|
|
|
841
421
|
});
|
|
842
422
|
let setChainMeta = chainsData => client.setChainMeta(chainMeta(chainsData)).then(() => (undefined));
|
|
843
423
|
let pruneStaleCheckpoints = safeCheckpoints => client.pruneCheckpoints(bounds(safeCheckpoints));
|
|
844
|
-
let pruneStaleEntityHistory = (entityConfig, safeCheckpoints) => client.pruneHistory(
|
|
845
|
-
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));
|
|
846
426
|
let getRollbackProgressDiff = async floors => (await client.rollbackProgressDiff(bounds(floors.checkpointBounds))).map(diff => ({
|
|
847
427
|
chain_id: ChainId.normalizeOrThrow(diff.chainId),
|
|
848
428
|
events_processed_diff: diff.eventsProcessed,
|
|
849
429
|
new_progress_block_number: diff.progressBlock
|
|
850
430
|
}));
|
|
851
431
|
let getRollbackData = async (entityConfig, floors) => {
|
|
852
|
-
let match = await client.rollbackData(
|
|
432
|
+
let match = await client.rollbackData(entityConfig.index, bounds(floors.checkpointBounds));
|
|
853
433
|
let restored = match.restored;
|
|
854
434
|
let removedIdRows;
|
|
855
435
|
try {
|
|
@@ -867,29 +447,28 @@ function make(client, logger, entitiesOpt, cacheDir, ecosystem, isolatedOpt, onI
|
|
|
867
447
|
return "crossChain";
|
|
868
448
|
}
|
|
869
449
|
};
|
|
870
|
-
let removals = removedIdRows.map(row => ({
|
|
871
|
-
entityId: S$RescriptSchema.parseOrThrow(row, rollbackRemovedIdSchema(entityConfig.table)),
|
|
872
|
-
scope: scopeOf(row)
|
|
873
|
-
}));
|
|
874
|
-
let restoredEntitiesResult = [];
|
|
875
|
-
rollbackRows.forEach(row => {
|
|
876
|
-
let match = S$RescriptSchema.parseOrThrow(row, rollbackRowStateSchema(entityConfig.table));
|
|
877
|
-
if (match[1] === "SET") {
|
|
878
|
-
restoredEntitiesResult.push(row);
|
|
879
|
-
return;
|
|
880
|
-
}
|
|
881
|
-
removals.push({
|
|
882
|
-
entityId: match[0],
|
|
883
|
-
scope: scopeOf(row)
|
|
884
|
-
});
|
|
885
|
-
});
|
|
886
450
|
return [
|
|
887
|
-
|
|
888
|
-
|
|
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))
|
|
889
456
|
];
|
|
890
457
|
};
|
|
891
|
-
let
|
|
892
|
-
|
|
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));
|
|
893
472
|
let rawEvents;
|
|
894
473
|
if (config.enableRawEvents) {
|
|
895
474
|
let seenLogCoordinates = new Set();
|
|
@@ -908,21 +487,35 @@ function make(client, logger, entitiesOpt, cacheDir, ecosystem, isolatedOpt, onI
|
|
|
908
487
|
} else {
|
|
909
488
|
rawEvents = [];
|
|
910
489
|
}
|
|
911
|
-
let
|
|
912
|
-
let
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
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
|
|
916
501
|
};
|
|
917
502
|
let input;
|
|
918
503
|
try {
|
|
919
504
|
let tmp;
|
|
920
505
|
if (Utils.$$Array.notEmpty(rawEvents)) {
|
|
921
|
-
let
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
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;
|
|
926
519
|
} else {
|
|
927
520
|
tmp = undefined;
|
|
928
521
|
}
|
|
@@ -931,7 +524,6 @@ function make(client, logger, entitiesOpt, cacheDir, ecosystem, isolatedOpt, onI
|
|
|
931
524
|
let rolledBackAddresses = param.rolledBackAddresses;
|
|
932
525
|
return {
|
|
933
526
|
bounds: bounds(param.floors.checkpointBounds),
|
|
934
|
-
tables: allEntities.map(entityConfig => entityTable(entityConfig).handle),
|
|
935
527
|
progress: param.progressedChains.map(progress),
|
|
936
528
|
removedAddresses: {
|
|
937
529
|
chainIds: rolledBackAddresses.map(key => key.chainId),
|
|
@@ -940,7 +532,7 @@ function make(client, logger, entitiesOpt, cacheDir, ecosystem, isolatedOpt, onI
|
|
|
940
532
|
},
|
|
941
533
|
diffCheckpoints: param.diffCheckpoints.map(diff => ({
|
|
942
534
|
chainId: diff.chainId,
|
|
943
|
-
checkpointId: diff.checkpointId
|
|
535
|
+
checkpointId: diff.checkpointId,
|
|
944
536
|
blockNumber: diff.blockNumber
|
|
945
537
|
}))
|
|
946
538
|
};
|
|
@@ -953,124 +545,41 @@ function make(client, logger, entitiesOpt, cacheDir, ecosystem, isolatedOpt, onI
|
|
|
953
545
|
totalEventsProcessed: chainAfterBatch.totalEventsProcessed
|
|
954
546
|
})),
|
|
955
547
|
rawEvents: tmp,
|
|
956
|
-
|
|
957
|
-
let
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
let
|
|
962
|
-
let
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
type: "SET",
|
|
976
|
-
entityId: change.entityId,
|
|
977
|
-
entity: Internal.stampChainId(change.entity, field.fieldName, chainId),
|
|
978
|
-
checkpointId: change.checkpointId
|
|
979
|
-
};
|
|
980
|
-
} else {
|
|
981
|
-
return change;
|
|
982
|
-
}
|
|
983
|
-
});
|
|
984
|
-
} else {
|
|
985
|
-
stamped = changes;
|
|
986
|
-
}
|
|
987
|
-
let diffCheckpointId = Stdlib_Option.flatMap(rollback, r => CheckpointSequence.findForScope(config.checkpointSequence, r.diffFrontier, scope));
|
|
988
|
-
let historySets = [];
|
|
989
|
-
let historySetCheckpointIds = [];
|
|
990
|
-
let historyDeleteIds = [];
|
|
991
|
-
let historyDeleteCheckpointIds = [];
|
|
992
|
-
let idsWithDiff = new Set();
|
|
993
|
-
let latestChangeById = {};
|
|
994
|
-
let orderedIds = [];
|
|
995
|
-
stamped.forEach(change => {
|
|
996
|
-
let entityId = change.entityId;
|
|
997
|
-
let entityKey = EntityId.toKey(entityId);
|
|
998
|
-
if (Stdlib_Option.isNone(latestChangeById[entityKey])) {
|
|
999
|
-
orderedIds.push(entityId);
|
|
1000
|
-
}
|
|
1001
|
-
latestChangeById[entityKey] = change;
|
|
1002
|
-
if (!shouldSaveHistory) {
|
|
1003
|
-
return;
|
|
1004
|
-
}
|
|
1005
|
-
if (change.checkpointId === diffCheckpointId) {
|
|
1006
|
-
idsWithDiff.add(entityKey);
|
|
1007
|
-
return;
|
|
1008
|
-
}
|
|
1009
|
-
if (change.type === "SET") {
|
|
1010
|
-
historySets.push(change.entity);
|
|
1011
|
-
historySetCheckpointIds.push(change.checkpointId.toString());
|
|
1012
|
-
return;
|
|
1013
|
-
}
|
|
1014
|
-
historyDeleteIds.push(change.entityId);
|
|
1015
|
-
historyDeleteCheckpointIds.push(change.checkpointId.toString());
|
|
1016
|
-
});
|
|
1017
|
-
let sets = [];
|
|
1018
|
-
let deletes = [];
|
|
1019
|
-
let backfill = [];
|
|
1020
|
-
orderedIds.forEach(entityId => {
|
|
1021
|
-
let entityKey = EntityId.toKey(entityId);
|
|
1022
|
-
let match = latestChangeById[entityKey];
|
|
1023
|
-
if (match.type === "SET") {
|
|
1024
|
-
sets.push(match.entity);
|
|
1025
|
-
} else {
|
|
1026
|
-
deletes.push(match.entityId);
|
|
1027
|
-
}
|
|
1028
|
-
if (shouldSaveHistory && !idsWithDiff.has(entityKey)) {
|
|
1029
|
-
backfill.push(entityId);
|
|
1030
|
-
return;
|
|
1031
|
-
}
|
|
1032
|
-
});
|
|
1033
|
-
let rowsOf = entities => {
|
|
1034
|
-
if (Utils.$$Array.notEmpty(entities)) {
|
|
1035
|
-
return rowsOrThrow(client, table, getRowSchema(entityConfig), entities, staged);
|
|
1036
|
-
}
|
|
1037
|
-
};
|
|
1038
|
-
return {
|
|
1039
|
-
sets: rowsOf(sets),
|
|
1040
|
-
deletes: renderIds(entityConfig.table, deletes),
|
|
1041
|
-
history: shouldSaveHistory ? ({
|
|
1042
|
-
backfill: renderIds(entityConfig.table, backfill),
|
|
1043
|
-
sets: rowsOf(historySets),
|
|
1044
|
-
setCheckpointIds: historySetCheckpointIds,
|
|
1045
|
-
deleteIds: renderIds(entityConfig.table, historyDeleteIds),
|
|
1046
|
-
deleteCheckpointIds: historyDeleteCheckpointIds
|
|
1047
|
-
}) : undefined
|
|
1048
|
-
};
|
|
1049
|
-
};
|
|
1050
|
-
let match$1 = table.clickhouse;
|
|
1051
|
-
let tmp;
|
|
1052
|
-
if (changes.length !== 0 && match$1 !== undefined) {
|
|
1053
|
-
let handle = stagedFor(staged, "ClickHouse", () => ClickHouse.stageChangesOrThrow(StorageClient.arena(client, "ClickHouse"), match$1, entityConfig, scope, changes));
|
|
1054
|
-
staged_handles.push(handle);
|
|
1055
|
-
tmp = handle;
|
|
1056
|
-
} else {
|
|
1057
|
-
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;
|
|
1058
567
|
}
|
|
1059
568
|
return {
|
|
1060
|
-
|
|
1061
|
-
chainId:
|
|
1062
|
-
|
|
1063
|
-
|
|
569
|
+
entity: update.entityConfig.index,
|
|
570
|
+
chainId: Internal.chainScopeChainId(update.scope),
|
|
571
|
+
keepsHistory: update.shouldSaveHistory,
|
|
572
|
+
changes: handle
|
|
1064
573
|
};
|
|
1065
574
|
}),
|
|
1066
575
|
chainMeta: Stdlib_Option.mapOr(chainMetaData, [], chainMeta),
|
|
1067
576
|
addresses: addressColumns(registeredAddresses.map(staged => staged.row)),
|
|
1068
577
|
frontier: {
|
|
1069
|
-
chainIds:
|
|
1070
|
-
checkpointIds:
|
|
578
|
+
chainIds: chainIds,
|
|
579
|
+
checkpointIds: frontierCheckpointIds
|
|
1071
580
|
},
|
|
1072
581
|
checkpoints: {
|
|
1073
|
-
ids: batch.checkpointIds
|
|
582
|
+
ids: batch.checkpointIds,
|
|
1074
583
|
chainIds: batch.checkpointChainIds,
|
|
1075
584
|
blockNumbers: batch.checkpointBlockNumbers,
|
|
1076
585
|
blockHashes: batch.checkpointBlockHashes,
|
|
@@ -1078,35 +587,59 @@ function make(client, logger, entitiesOpt, cacheDir, ecosystem, isolatedOpt, onI
|
|
|
1078
587
|
keepsHistory: batch.checkpointChainIds.map(chainId => HistoryPolicy.forChain(batch.history, chainId))
|
|
1079
588
|
},
|
|
1080
589
|
effectCaches: updatedEffectsCache.map(param => {
|
|
1081
|
-
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
|
+
}
|
|
1082
612
|
return {
|
|
1083
|
-
table:
|
|
613
|
+
table: table.tableName,
|
|
1084
614
|
create: param.shouldInitialize,
|
|
1085
|
-
rows:
|
|
615
|
+
rows: tmp
|
|
1086
616
|
};
|
|
1087
617
|
})
|
|
1088
618
|
};
|
|
1089
|
-
} catch (exn) {
|
|
1090
|
-
client.discardStaged(
|
|
1091
|
-
throw exn;
|
|
619
|
+
} catch (exn$1) {
|
|
620
|
+
client.discardStaged(handles);
|
|
621
|
+
throw exn$1;
|
|
1092
622
|
}
|
|
623
|
+
let postgresStagingSeconds = Performance.secondsSince(stagingStarted) - clickHouseOnlyStagingSeconds.contents;
|
|
1093
624
|
let timings;
|
|
1094
625
|
try {
|
|
1095
626
|
timings = await client.writeBatch(input);
|
|
1096
|
-
} catch (raw_exn) {
|
|
1097
|
-
let exn$
|
|
1098
|
-
client.discardStaged(
|
|
1099
|
-
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);
|
|
1100
631
|
}
|
|
1101
632
|
timings.forEach(param => {
|
|
1102
|
-
let
|
|
1103
|
-
|
|
633
|
+
let store = param.store;
|
|
634
|
+
let tmp;
|
|
635
|
+
tmp = store === "Postgres" ? postgresStagingSeconds : clickHouseStagingSeconds.contents;
|
|
636
|
+
onWrite(storeName(store), param.seconds + tmp);
|
|
1104
637
|
});
|
|
1105
638
|
};
|
|
1106
639
|
let close = () => client.close();
|
|
1107
640
|
return {
|
|
1108
641
|
name: postgresName,
|
|
1109
|
-
entityStoreName: entityConfig =>
|
|
642
|
+
entityStoreName: entityConfig => Stdlib_Option.mapOr(layouts.entities[entityConfig.index].home, postgresName, storeName),
|
|
1110
643
|
holding: holding,
|
|
1111
644
|
initialize: initialize,
|
|
1112
645
|
readStoredConfig: readStoredConfig,
|
|
@@ -1131,13 +664,13 @@ function make(client, logger, entitiesOpt, cacheDir, ecosystem, isolatedOpt, onI
|
|
|
1131
664
|
|
|
1132
665
|
function clientFromEnv(config, logger, pgSchemaOpt, isHasuraEnabled, maxConnections) {
|
|
1133
666
|
let pgSchema = pgSchemaOpt !== undefined ? pgSchemaOpt : Env.Db.publicSchema;
|
|
1134
|
-
return makeClient(logger, config
|
|
667
|
+
return makeClient(logger, config, postgresOptions(pgSchema, isHasuraEnabled, maxConnections, config.isolated), config.storage.clickhouse ? ClickHouse.optionsFromEnvOrThrow() : undefined);
|
|
1135
668
|
}
|
|
1136
669
|
|
|
1137
670
|
function makeStorageFromEnv(config, logger, pgSchemaOpt, isHasuraEnabledOpt, maxConnections, cacheDir) {
|
|
1138
671
|
let pgSchema = pgSchemaOpt !== undefined ? pgSchemaOpt : Env.Db.publicSchema;
|
|
1139
672
|
let isHasuraEnabled = isHasuraEnabledOpt !== undefined ? isHasuraEnabledOpt : Env.Hasura.enabled;
|
|
1140
|
-
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, {
|
|
1141
674
|
role: Env.Hasura.role,
|
|
1142
675
|
secret: Env.Hasura.secret
|
|
1143
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);
|
|
@@ -1149,36 +682,24 @@ function makePersistenceFromConfig(config, logger, storageOpt) {
|
|
|
1149
682
|
}
|
|
1150
683
|
|
|
1151
684
|
export {
|
|
1152
|
-
formatSeconds,
|
|
1153
|
-
slowOnLargeDatabaseNotice,
|
|
1154
685
|
storeName,
|
|
1155
686
|
postgresName,
|
|
1156
|
-
logIndexEvent,
|
|
1157
687
|
postgresOptions,
|
|
1158
688
|
makeClient,
|
|
1159
|
-
partitionTableName,
|
|
1160
|
-
indexTableNames,
|
|
1161
|
-
getSchemaIndexes,
|
|
1162
|
-
pgColumnInput,
|
|
1163
|
-
rowSchemaCache,
|
|
1164
|
-
getRowSchema,
|
|
1165
|
-
registerEntity,
|
|
1166
|
-
arenaConverters,
|
|
1167
|
-
cellConverters,
|
|
1168
|
-
converterOf,
|
|
1169
|
-
stagedFor,
|
|
1170
|
-
renderIds,
|
|
1171
689
|
bounds,
|
|
1172
690
|
progress,
|
|
1173
691
|
addressColumns,
|
|
1174
692
|
toChainConfig,
|
|
1175
693
|
storageErrorOf,
|
|
1176
|
-
rollbackRowStateSchema,
|
|
1177
694
|
rollbackChainIdSchema,
|
|
1178
695
|
rollbackRemovedIdSchema,
|
|
696
|
+
changeColumns,
|
|
697
|
+
stageOrThrow,
|
|
698
|
+
stageRowsOrThrow,
|
|
699
|
+
stageChangesOrThrow,
|
|
1179
700
|
make,
|
|
1180
701
|
clientFromEnv,
|
|
1181
702
|
makeStorageFromEnv,
|
|
1182
703
|
makePersistenceFromConfig,
|
|
1183
704
|
}
|
|
1184
|
-
/*
|
|
705
|
+
/* rollbackChainIdSchema Not a pure module */
|