envio 2.27.6 → 2.28.0-alpha.2

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.
@@ -16,6 +16,7 @@ var Belt_Array = require("rescript/lib/js/belt_Array.js");
16
16
  var Belt_Option = require("rescript/lib/js/belt_Option.js");
17
17
  var Caml_option = require("rescript/lib/js/caml_option.js");
18
18
  var Persistence = require("./Persistence.res.js");
19
+ var InternalTable = require("./db/InternalTable.res.js");
19
20
  var Child_process = require("child_process");
20
21
  var Caml_exceptions = require("rescript/lib/js/caml_exceptions.js");
21
22
  var S$RescriptSchema = require("rescript-schema/src/S.res.js");
@@ -68,11 +69,18 @@ function makeCreateTableQuery(table, pgSchema) {
68
69
  ) + ");";
69
70
  }
70
71
 
71
- function makeInitializeTransaction(pgSchema, pgUser, generalTablesOpt, entitiesOpt, enumsOpt, isEmptyPgSchemaOpt) {
72
- var generalTables = generalTablesOpt !== undefined ? generalTablesOpt : [];
72
+ function makeInitializeTransaction(pgSchema, pgUser, chainConfigsOpt, entitiesOpt, enumsOpt, isEmptyPgSchemaOpt) {
73
+ var chainConfigs = chainConfigsOpt !== undefined ? chainConfigsOpt : [];
73
74
  var entities = entitiesOpt !== undefined ? entitiesOpt : [];
74
75
  var enums = enumsOpt !== undefined ? enumsOpt : [];
75
76
  var isEmptyPgSchema = isEmptyPgSchemaOpt !== undefined ? isEmptyPgSchemaOpt : false;
77
+ var generalTables = [
78
+ InternalTable.EventSyncState.table,
79
+ InternalTable.Chains.table,
80
+ InternalTable.PersistedState.table,
81
+ InternalTable.EndOfBlockRangeScannedData.table,
82
+ InternalTable.RawEvents.table
83
+ ];
76
84
  var allTables = $$Array.copy(generalTables);
77
85
  var allEntityTables = [];
78
86
  entities.forEach(function (entity) {
@@ -107,12 +115,18 @@ function makeInitializeTransaction(pgSchema, pgUser, generalTablesOpt, entitiesO
107
115
  contents: ""
108
116
  };
109
117
  entities.forEach(function (entity) {
110
- functionsQuery.contents = functionsQuery.contents + "\n" + entity.entityHistory.createInsertFnQuery;
118
+ functionsQuery.contents = functionsQuery.contents + "\n" + entity.entityHistory.makeInsertFnQuery(pgSchema);
111
119
  Table.getDerivedFromFields(entity.table).forEach(function (derivedFromField) {
112
120
  var indexField = Utils.unwrapResultExn(Schema.getDerivedFromFieldName(derivedSchema, derivedFromField));
113
121
  query.contents = query.contents + "\n" + makeCreateIndexQuery(derivedFromField.derivedFromEntity, [indexField], pgSchema);
114
122
  });
115
123
  });
124
+ query.contents = query.contents + "\n" + InternalTable.Views.makeMetaViewQuery(pgSchema);
125
+ query.contents = query.contents + "\n" + InternalTable.Views.makeChainMetadataViewQuery(pgSchema);
126
+ var initialChainsValuesQuery = InternalTable.Chains.makeInitialValuesQuery(pgSchema, chainConfigs);
127
+ if (initialChainsValuesQuery !== undefined) {
128
+ query.contents = query.contents + "\n" + initialChainsValuesQuery;
129
+ }
116
130
  functionsQuery.contents = functionsQuery.contents + "\n" + ("CREATE OR REPLACE FUNCTION " + getCacheRowCountFnName + "(table_name text) \nRETURNS integer AS $$\nDECLARE\n result integer;\nBEGIN\n EXECUTE format('SELECT COUNT(*) FROM \"" + pgSchema + "\".%I', table_name) INTO result;\n RETURN result;\nEND;\n$$ LANGUAGE plpgsql;");
117
131
  return [query.contents].concat(functionsQuery.contents !== "" ? [functionsQuery.contents] : []);
118
132
  }
@@ -129,6 +143,10 @@ function makeLoadByIdsQuery(pgSchema, tableName) {
129
143
  return "SELECT * FROM \"" + pgSchema + "\".\"" + tableName + "\" WHERE id = ANY($1::text[]);";
130
144
  }
131
145
 
146
+ function makeLoadAllQuery(pgSchema, tableName) {
147
+ return "SELECT * FROM \"" + pgSchema + "\".\"" + tableName + "\";";
148
+ }
149
+
132
150
  function makeInsertUnnestSetQuery(pgSchema, table, itemSchema, isRawEvents) {
133
151
  var match = Table.toSqlParams(table, itemSchema, pgSchema);
134
152
  var quotedNonPrimaryFieldNames = match.quotedNonPrimaryFieldNames;
@@ -177,13 +195,9 @@ function makeInsertValuesSetQuery(pgSchema, table, itemSchema, itemsCount) {
177
195
  ) + ";";
178
196
  }
179
197
 
180
- var rawEventsTableName = "raw_events";
181
-
182
- var eventSyncStateTableName = "event_sync_state";
183
-
184
198
  function makeTableBatchSetQuery(pgSchema, table, itemSchema) {
185
199
  var match = Table.toSqlParams(table, itemSchema, pgSchema);
186
- var isRawEvents = table.tableName === rawEventsTableName;
200
+ var isRawEvents = table.tableName === InternalTable.RawEvents.table.tableName;
187
201
  if (isRawEvents || !match.hasArrayField) {
188
202
  return {
189
203
  query: makeInsertUnnestSetQuery(pgSchema, table, itemSchema, isRawEvents),
@@ -285,13 +299,24 @@ async function setOrThrow(sql, items, table, itemSchema, pgSchema) {
285
299
 
286
300
  function setEntityHistoryOrThrow(sql, entityHistory, rows, shouldCopyCurrentEntity, shouldRemoveInvalidUtf8Opt) {
287
301
  var shouldRemoveInvalidUtf8 = shouldRemoveInvalidUtf8Opt !== undefined ? shouldRemoveInvalidUtf8Opt : false;
288
- return Promise.all(Belt_Array.map(rows, (function (historyRow) {
289
- var row = S$RescriptSchema.reverseConvertToJsonOrThrow(historyRow, entityHistory.schema);
290
- if (shouldRemoveInvalidUtf8) {
291
- removeInvalidUtf8InPlace([row]);
292
- }
293
- return entityHistory.insertFn(sql, row, shouldCopyCurrentEntity !== undefined ? shouldCopyCurrentEntity : !Belt_Option.getWithDefault(historyRow.containsRollbackDiffChange, false));
294
- })));
302
+ return Belt_Array.map(rows, (function (historyRow) {
303
+ var row = S$RescriptSchema.reverseConvertToJsonOrThrow(historyRow, entityHistory.schema);
304
+ if (shouldRemoveInvalidUtf8) {
305
+ removeInvalidUtf8InPlace([row]);
306
+ }
307
+ return $$Promise.$$catch(entityHistory.insertFn(sql, row, shouldCopyCurrentEntity !== undefined ? shouldCopyCurrentEntity : !Belt_Option.getWithDefault(historyRow.containsRollbackDiffChange, false)), (function (exn) {
308
+ var reason = Utils.prettifyExn(exn);
309
+ var detail = (reason?.detail || "");
310
+ throw {
311
+ RE_EXN_ID: Persistence.StorageError,
312
+ message: "Failed to insert history item into table \"" + entityHistory.table.tableName + "\"." + (
313
+ detail !== "" ? " Details: " + detail : ""
314
+ ),
315
+ reason: reason,
316
+ Error: new Error()
317
+ };
318
+ }));
319
+ }));
295
320
  }
296
321
 
297
322
  function makeSchemaTableNamesQuery(pgSchema) {
@@ -370,29 +395,112 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, onI
370
395
  };
371
396
  var cacheDirPath = Path.resolve("..", ".envio", "cache");
372
397
  var isInitialized = async function () {
373
- var envioTables = await sql.unsafe("SELECT table_schema FROM information_schema.tables WHERE table_schema = '" + pgSchema + "' AND table_name = '" + eventSyncStateTableName + "';");
398
+ var envioTables = await sql.unsafe("SELECT table_schema FROM information_schema.tables WHERE table_schema = '" + pgSchema + "' AND table_name = '" + InternalTable.EventSyncState.table.tableName + "' OR table_name = '" + InternalTable.Chains.table.tableName + "';");
374
399
  return Utils.$$Array.notEmpty(envioTables);
375
400
  };
376
- var initialize = async function (entitiesOpt, generalTablesOpt, enumsOpt) {
401
+ var restoreEffectCache = async function (withUpload) {
402
+ if (withUpload) {
403
+ var nothingToUploadErrorMessage = "Nothing to upload.";
404
+ var match = await Promise.all([
405
+ $$Promise.$$catch(Fs.promises.readdir(cacheDirPath).then(function (e) {
406
+ return {
407
+ TAG: "Ok",
408
+ _0: e
409
+ };
410
+ }), (function (param) {
411
+ return Promise.resolve({
412
+ TAG: "Error",
413
+ _0: nothingToUploadErrorMessage
414
+ });
415
+ })),
416
+ getConnectedPsqlExec(pgUser, pgHost, pgDatabase, pgPort)
417
+ ]);
418
+ var exit = 0;
419
+ var message;
420
+ var entries = match[0];
421
+ if (entries.TAG === "Ok") {
422
+ var psqlExec = match[1];
423
+ if (psqlExec.TAG === "Ok") {
424
+ var psqlExec$1 = psqlExec._0;
425
+ var cacheFiles = entries._0.filter(function (entry) {
426
+ return entry.endsWith(".tsv");
427
+ });
428
+ await Promise.all(cacheFiles.map(function (entry) {
429
+ var effectName = entry.slice(0, -4);
430
+ var table = Internal.makeCacheTable(effectName);
431
+ return sql.unsafe(makeCreateTableQuery(table, pgSchema)).then(function () {
432
+ var inputFile = Path.join(cacheDirPath, entry);
433
+ var command = psqlExec$1 + " -c 'COPY \"" + pgSchema + "\".\"" + table.tableName + "\" FROM STDIN WITH (FORMAT text, HEADER);' < " + inputFile;
434
+ return new Promise((function (resolve, reject) {
435
+ Child_process.exec(command, psqlExecOptions, (function (error, stdout, param) {
436
+ if (error === null) {
437
+ return resolve(stdout);
438
+ } else {
439
+ return reject(error);
440
+ }
441
+ }));
442
+ }));
443
+ });
444
+ }));
445
+ Logging.info("Successfully uploaded cache.");
446
+ } else {
447
+ message = match[1]._0;
448
+ exit = 1;
449
+ }
450
+ } else {
451
+ message = entries._0;
452
+ exit = 1;
453
+ }
454
+ if (exit === 1) {
455
+ if (message === nothingToUploadErrorMessage) {
456
+ Logging.info("No cache found to upload.");
457
+ } else {
458
+ Logging.error("Failed to upload cache, continuing without it. " + message);
459
+ }
460
+ }
461
+
462
+ }
463
+ var cacheTableInfo = await sql.unsafe(makeSchemaCacheTableInfoQuery(pgSchema));
464
+ if (withUpload && Utils.$$Array.notEmpty(cacheTableInfo) && onNewTables !== undefined) {
465
+ await onNewTables(cacheTableInfo.map(function (info) {
466
+ return info.table_name;
467
+ }));
468
+ }
469
+ var cache = {};
470
+ cacheTableInfo.forEach(function (param) {
471
+ var effectName = param.table_name.slice(cacheTablePrefixLength);
472
+ cache[effectName] = {
473
+ effectName: effectName,
474
+ count: param.count
475
+ };
476
+ });
477
+ return cache;
478
+ };
479
+ var initialize = async function (chainConfigsOpt, entitiesOpt, enumsOpt) {
480
+ var chainConfigs = chainConfigsOpt !== undefined ? chainConfigsOpt : [];
377
481
  var entities = entitiesOpt !== undefined ? entitiesOpt : [];
378
- var generalTables = generalTablesOpt !== undefined ? generalTablesOpt : [];
379
482
  var enums = enumsOpt !== undefined ? enumsOpt : [];
380
483
  var schemaTableNames = await sql.unsafe(makeSchemaTableNamesQuery(pgSchema));
381
484
  if (Utils.$$Array.notEmpty(schemaTableNames) && !schemaTableNames.some(function (table) {
382
- return table.table_name === eventSyncStateTableName;
485
+ return table.table_name === InternalTable.EventSyncState.table.tableName;
383
486
  })) {
384
487
  Js_exn.raiseError("Cannot run Envio migrations on PostgreSQL schema \"" + pgSchema + "\" because it contains non-Envio tables. Running migrations would delete all data in this schema.\n\nTo resolve this:\n1. If you want to use this schema, first backup any important data, then drop it with: \"pnpm envio local db-migrate down\"\n2. Or specify a different schema name by setting the \"ENVIO_PG_PUBLIC_SCHEMA\" environment variable\n3. Or manually drop the schema in your database if you're certain the data is not needed.");
385
488
  }
386
- var queries = makeInitializeTransaction(pgSchema, pgUser, generalTables, entities, enums, Utils.$$Array.isEmpty(schemaTableNames));
489
+ var queries = makeInitializeTransaction(pgSchema, pgUser, chainConfigs, entities, enums, Utils.$$Array.isEmpty(schemaTableNames));
387
490
  await sql.begin(function (sql) {
388
- return queries.map(function (query) {
389
- return sql.unsafe(query);
390
- });
491
+ return Promise.all(queries.map(function (query) {
492
+ return sql.unsafe(query);
493
+ }));
391
494
  });
495
+ var cache = await restoreEffectCache(true);
392
496
  if (onInitialize !== undefined) {
393
- return await onInitialize();
497
+ await onInitialize();
394
498
  }
395
-
499
+ return {
500
+ cleanRun: true,
501
+ cache: cache,
502
+ chains: chainConfigs.map(InternalTable.Chains.initialFromConfig)
503
+ };
396
504
  };
397
505
  var loadByIdsOrThrow = async function (ids, table, rowsSchema) {
398
506
  var rows;
@@ -526,90 +634,26 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, onI
526
634
  return Logging.errorWithExn(Utils.prettifyExn(exn$1), "Failed to dump cache.");
527
635
  }
528
636
  };
529
- var restoreEffectCache = async function (withUpload) {
530
- if (withUpload) {
531
- var nothingToUploadErrorMessage = "Nothing to upload.";
532
- var match = await Promise.all([
533
- $$Promise.$$catch(Fs.promises.readdir(cacheDirPath).then(function (e) {
534
- return {
535
- TAG: "Ok",
536
- _0: e
537
- };
538
- }), (function (param) {
539
- return Promise.resolve({
540
- TAG: "Error",
541
- _0: nothingToUploadErrorMessage
542
- });
543
- })),
544
- getConnectedPsqlExec(pgUser, pgHost, pgDatabase, pgPort)
545
- ]);
546
- var exit = 0;
547
- var message;
548
- var entries = match[0];
549
- if (entries.TAG === "Ok") {
550
- var psqlExec = match[1];
551
- if (psqlExec.TAG === "Ok") {
552
- var psqlExec$1 = psqlExec._0;
553
- var cacheFiles = entries._0.filter(function (entry) {
554
- return entry.endsWith(".tsv");
555
- });
556
- await Promise.all(cacheFiles.map(function (entry) {
557
- var effectName = entry.slice(0, -4);
558
- var table = Internal.makeCacheTable(effectName);
559
- return sql.unsafe(makeCreateTableQuery(table, pgSchema)).then(function () {
560
- var inputFile = Path.join(cacheDirPath, entry);
561
- var command = psqlExec$1 + " -c 'COPY \"" + pgSchema + "\".\"" + table.tableName + "\" FROM STDIN WITH (FORMAT text, HEADER);' < " + inputFile;
562
- return new Promise((function (resolve, reject) {
563
- Child_process.exec(command, psqlExecOptions, (function (error, stdout, param) {
564
- if (error === null) {
565
- return resolve(stdout);
566
- } else {
567
- return reject(error);
568
- }
569
- }));
570
- }));
571
- });
572
- }));
573
- Logging.info("Successfully uploaded cache.");
574
- } else {
575
- message = match[1]._0;
576
- exit = 1;
577
- }
578
- } else {
579
- message = entries._0;
580
- exit = 1;
581
- }
582
- if (exit === 1) {
583
- if (message === nothingToUploadErrorMessage) {
584
- Logging.info("No cache found to upload.");
585
- } else {
586
- Logging.error("Failed to upload cache, continuing without it. " + message);
587
- }
588
- }
589
-
590
- }
591
- var cacheTableInfo = await sql.unsafe(makeSchemaCacheTableInfoQuery(pgSchema));
592
- if (withUpload && Utils.$$Array.notEmpty(cacheTableInfo) && onNewTables !== undefined) {
593
- await onNewTables(cacheTableInfo.map(function (info) {
594
- return info.table_name;
595
- }));
596
- }
597
- return cacheTableInfo.map(function (info) {
598
- return {
599
- effectName: info.table_name.slice(cacheTablePrefixLength),
600
- count: info.count
601
- };
602
- });
637
+ var loadInitialState = async function () {
638
+ var match = await Promise.all([
639
+ restoreEffectCache(false),
640
+ sql.unsafe(makeLoadAllQuery(pgSchema, InternalTable.Chains.table.tableName))
641
+ ]);
642
+ return {
643
+ cleanRun: false,
644
+ cache: match[0],
645
+ chains: match[1]
646
+ };
603
647
  };
604
648
  return {
605
649
  isInitialized: isInitialized,
606
650
  initialize: initialize,
651
+ loadInitialState: loadInitialState,
607
652
  loadByIdsOrThrow: loadByIdsOrThrow,
608
653
  loadByFieldOrThrow: loadByFieldOrThrow,
609
654
  setOrThrow: setOrThrow$1,
610
655
  setEffectCacheOrThrow: setEffectCacheOrThrow,
611
- dumpEffectCache: dumpEffectCache,
612
- restoreEffectCache: restoreEffectCache
656
+ dumpEffectCache: dumpEffectCache
613
657
  };
614
658
  }
615
659
 
@@ -623,10 +667,9 @@ exports.makeInitializeTransaction = makeInitializeTransaction;
623
667
  exports.makeLoadByIdQuery = makeLoadByIdQuery;
624
668
  exports.makeLoadByFieldQuery = makeLoadByFieldQuery;
625
669
  exports.makeLoadByIdsQuery = makeLoadByIdsQuery;
670
+ exports.makeLoadAllQuery = makeLoadAllQuery;
626
671
  exports.makeInsertUnnestSetQuery = makeInsertUnnestSetQuery;
627
672
  exports.makeInsertValuesSetQuery = makeInsertValuesSetQuery;
628
- exports.rawEventsTableName = rawEventsTableName;
629
- exports.eventSyncStateTableName = eventSyncStateTableName;
630
673
  exports.maxItemsPerQuery = maxItemsPerQuery;
631
674
  exports.makeTableBatchSetQuery = makeTableBatchSetQuery;
632
675
  exports.chunkArray = chunkArray;
@@ -213,9 +213,9 @@ let incrementExecuteBatchDurationCounter = (~duration) => {
213
213
  executeBatchDurationCounter->PromClient.Counter.incMany(duration)
214
214
  }
215
215
 
216
- let setSourceChainHeight = (~blockNumber, ~chain) => {
216
+ let setSourceChainHeight = (~blockNumber, ~chainId) => {
217
217
  sourceChainHeight
218
- ->PromClient.Gauge.labels({"chainId": chain->ChainMap.Chain.toString})
218
+ ->PromClient.Gauge.labels({"chainId": chainId})
219
219
  ->PromClient.Gauge.set(blockNumber)
220
220
  }
221
221
 
@@ -4,7 +4,6 @@
4
4
  var Utils = require("./Utils.res.js");
5
5
  var Hrtime = require("./bindings/Hrtime.res.js");
6
6
  var Js_exn = require("rescript/lib/js/js_exn.js");
7
- var ChainMap = require("./ChainMap.res.js");
8
7
  var Belt_Array = require("rescript/lib/js/belt_Array.js");
9
8
  var Belt_Result = require("rescript/lib/js/belt_Result.js");
10
9
  var PromClient = require("prom-client");
@@ -315,9 +314,9 @@ function incrementExecuteBatchDurationCounter(duration) {
315
314
  executeBatchDurationCounter.inc(duration);
316
315
  }
317
316
 
318
- function setSourceChainHeight(blockNumber, chain) {
317
+ function setSourceChainHeight(blockNumber, chainId) {
319
318
  sourceChainHeight.labels({
320
- chainId: ChainMap.Chain.toString(chain)
319
+ chainId: chainId
321
320
  }).set(blockNumber);
322
321
  }
323
322
 
@@ -46,7 +46,7 @@ let createPinoMessageWithError = (message, err): pinoMessageBlobWithError => {
46
46
  // serializers type below: `type serializers = {err: Js.Json.t => Js.Json.t}`
47
47
  Utils.magic({
48
48
  "msg": message,
49
- "err": err,
49
+ "err": err->Utils.prettifyExn,
50
50
  })
51
51
  }
52
52
 
@@ -2,6 +2,7 @@
2
2
  'use strict';
3
3
 
4
4
  var Pino = require("pino");
5
+ var Utils = require("../Utils.res.js");
5
6
  var Caml_obj = require("rescript/lib/js/caml_obj.js");
6
7
  var Belt_Array = require("rescript/lib/js/belt_Array.js");
7
8
  var Belt_Option = require("rescript/lib/js/belt_Option.js");
@@ -14,7 +15,7 @@ function createPinoMessage(message) {
14
15
  function createPinoMessageWithError(message, err) {
15
16
  return {
16
17
  msg: message,
17
- err: err
18
+ err: Utils.prettifyExn(err)
18
19
  };
19
20
  }
20
21
 
@@ -89,7 +89,7 @@ type poolConfig = {
89
89
  @module
90
90
  external makeSql: (~config: poolConfig) => sql = "postgres"
91
91
 
92
- @send external beginSql: (sql, sql => array<promise<unit>>) => promise<unit> = "begin"
92
+ @send external beginSql: (sql, sql => promise<'result>) => promise<'result> = "begin"
93
93
 
94
94
  // TODO: can explore this approach (https://forum.rescript-lang.org/t/rfc-support-for-tagged-template-literals/3744)
95
95
  // @send @variadic
@@ -141,7 +141,7 @@ let makeHistoryRowSchema: S.t<'entity> => S.t<historyRow<'entity>> = entitySchem
141
141
 
142
142
  type t<'entity> = {
143
143
  table: table,
144
- createInsertFnQuery: string,
144
+ makeInsertFnQuery: (~pgSchema: string) => string,
145
145
  schema: S.t<historyRow<'entity>>,
146
146
  // Used for parsing
147
147
  schemaRows: S.t<array<historyRow<'entity>>>,
@@ -153,7 +153,7 @@ type entityInternal
153
153
  external castInternal: t<'entity> => t<entityInternal> = "%identity"
154
154
  external eval: string => 'a = "eval"
155
155
 
156
- let fromTable = (table: table, ~pgSchema, ~schema: S.t<'entity>): t<'entity> => {
156
+ let fromTable = (table: table, ~schema: S.t<'entity>): t<'entity> => {
157
157
  let entity_history_block_timestamp = "entity_history_block_timestamp"
158
158
  let entity_history_chain_id = "entity_history_chain_id"
159
159
  let entity_history_block_number = "entity_history_block_number"
@@ -227,19 +227,6 @@ let fromTable = (table: table, ~pgSchema, ~schema: S.t<'entity>): t<'entity> =>
227
227
  )
228
228
 
229
229
  let insertFnName = `"insert_${table.tableName}"`
230
- let historyRowArg = "history_row"
231
- let historyTablePath = `"${pgSchema}"."${historyTableName}"`
232
- let originTablePath = `"${pgSchema}"."${originTableName}"`
233
-
234
- let previousHistoryFieldsAreNullStr =
235
- previousChangeFieldNames
236
- ->Belt.Array.map(fieldName => `${historyRowArg}.${fieldName} IS NULL`)
237
- ->Js.Array2.joinWith(" OR ")
238
-
239
- let currentChangeFieldNamesCommaSeparated = currentChangeFieldNames->Js.Array2.joinWith(", ")
240
-
241
- let dataFieldNamesDoubleQuoted = dataFieldNames->Belt.Array.map(fieldName => `"${fieldName}"`)
242
- let dataFieldNamesCommaSeparated = dataFieldNamesDoubleQuoted->Js.Array2.joinWith(", ")
243
230
 
244
231
  let allFieldNamesDoubleQuoted =
245
232
  Belt.Array.concatMany([
@@ -249,7 +236,21 @@ let fromTable = (table: table, ~pgSchema, ~schema: S.t<'entity>): t<'entity> =>
249
236
  [actionFieldName],
250
237
  ])->Belt.Array.map(fieldName => `"${fieldName}"`)
251
238
 
252
- let createInsertFnQuery = {
239
+ let makeInsertFnQuery = (~pgSchema) => {
240
+ let historyRowArg = "history_row"
241
+ let historyTablePath = `"${pgSchema}"."${historyTableName}"`
242
+ let originTablePath = `"${pgSchema}"."${originTableName}"`
243
+
244
+ let previousHistoryFieldsAreNullStr =
245
+ previousChangeFieldNames
246
+ ->Belt.Array.map(fieldName => `${historyRowArg}.${fieldName} IS NULL`)
247
+ ->Js.Array2.joinWith(" OR ")
248
+
249
+ let currentChangeFieldNamesCommaSeparated = currentChangeFieldNames->Js.Array2.joinWith(", ")
250
+
251
+ let dataFieldNamesDoubleQuoted = dataFieldNames->Belt.Array.map(fieldName => `"${fieldName}"`)
252
+ let dataFieldNamesCommaSeparated = dataFieldNamesDoubleQuoted->Js.Array2.joinWith(", ")
253
+
253
254
  `CREATE OR REPLACE FUNCTION ${insertFnName}(${historyRowArg} ${historyTablePath}, should_copy_current_entity BOOLEAN)
254
255
  RETURNS void AS $$
255
256
  DECLARE
@@ -315,7 +316,7 @@ $$ LANGUAGE plpgsql;`
315
316
 
316
317
  let schema = makeHistoryRowSchema(schema)
317
318
 
318
- {table, createInsertFnQuery, schema, schemaRows: S.array(schema), insertFn}
319
+ {table, makeInsertFnQuery, schema, schemaRows: S.array(schema), insertFn}
319
320
  }
320
321
 
321
322
  type safeReorgBlocks = {
@@ -157,7 +157,7 @@ function makeHistoryRowSchema(entitySchema) {
157
157
  }));
158
158
  }
159
159
 
160
- function fromTable(table, pgSchema, schema) {
160
+ function fromTable(table, schema) {
161
161
  var currentChangeFieldNames = [
162
162
  "entity_history_block_timestamp",
163
163
  "entity_history_chain_id",
@@ -233,17 +233,6 @@ function fromTable(table, pgSchema, schema) {
233
233
  ]
234
234
  ]));
235
235
  var insertFnName = "\"insert_" + table$1.tableName + "\"";
236
- var historyRowArg = "history_row";
237
- var historyTablePath = "\"" + pgSchema + "\".\"" + historyTableName + "\"";
238
- var originTablePath = "\"" + pgSchema + "\".\"" + originTableName + "\"";
239
- var previousHistoryFieldsAreNullStr = Belt_Array.map(previousChangeFieldNames, (function (fieldName) {
240
- return historyRowArg + "." + fieldName + " IS NULL";
241
- })).join(" OR ");
242
- var currentChangeFieldNamesCommaSeparated = currentChangeFieldNames.join(", ");
243
- var dataFieldNamesDoubleQuoted = Belt_Array.map(dataFieldNames, (function (fieldName) {
244
- return "\"" + fieldName + "\"";
245
- }));
246
- var dataFieldNamesCommaSeparated = dataFieldNamesDoubleQuoted.join(", ");
247
236
  var allFieldNamesDoubleQuoted = Belt_Array.map(Belt_Array.concatMany([
248
237
  currentChangeFieldNames,
249
238
  previousChangeFieldNames,
@@ -252,19 +241,32 @@ function fromTable(table, pgSchema, schema) {
252
241
  ]), (function (fieldName) {
253
242
  return "\"" + fieldName + "\"";
254
243
  }));
255
- var createInsertFnQuery = "CREATE OR REPLACE FUNCTION " + insertFnName + "(" + historyRowArg + " " + historyTablePath + ", should_copy_current_entity BOOLEAN)\nRETURNS void AS $$\nDECLARE\n v_previous_record RECORD;\n v_origin_record RECORD;\nBEGIN\n -- Check if previous values are not provided\n IF " + previousHistoryFieldsAreNullStr + " THEN\n -- Find the most recent record for the same id\n SELECT " + currentChangeFieldNamesCommaSeparated + " INTO v_previous_record\n FROM " + historyTablePath + "\n WHERE " + id + " = " + historyRowArg + "." + id + "\n ORDER BY " + Belt_Array.map(currentChangeFieldNames, (function (fieldName) {
256
- return fieldName + " DESC";
257
- })).join(", ") + "\n LIMIT 1;\n\n -- If a previous record exists, use its values\n IF FOUND THEN\n " + Belt_Array.map(Belt_Array.zip(currentChangeFieldNames, previousChangeFieldNames), (function (param) {
258
- return historyRowArg + "." + param[1] + " := v_previous_record." + param[0] + ";";
259
- })).join(" ") + "\n ElSIF should_copy_current_entity THEN\n -- Check if a value for the id exists in the origin table and if so, insert a history row for it.\n SELECT " + dataFieldNamesCommaSeparated + " FROM " + originTablePath + " WHERE id = " + historyRowArg + "." + id + " INTO v_origin_record;\n IF FOUND THEN\n INSERT INTO " + historyTablePath + " (" + currentChangeFieldNamesCommaSeparated + ", " + dataFieldNamesCommaSeparated + ", \"" + actionFieldName + "\")\n -- SET the current change data fields to 0 since we don't know what they were\n -- and it doesn't matter provided they are less than any new values\n VALUES (" + Belt_Array.map(currentChangeFieldNames, (function (param) {
260
- return "0";
261
- })).join(", ") + ", " + Belt_Array.map(dataFieldNames, (function (fieldName) {
262
- return "v_origin_record.\"" + fieldName + "\"";
263
- })).join(", ") + ", 'SET');\n\n " + Belt_Array.map(previousChangeFieldNames, (function (previousFieldName) {
264
- return historyRowArg + "." + previousFieldName + " := 0;";
265
- })).join(" ") + "\n END IF;\n END IF;\n END IF;\n\n INSERT INTO " + historyTablePath + " (" + allFieldNamesDoubleQuoted.join(", ") + ")\n VALUES (" + Belt_Array.map(allFieldNamesDoubleQuoted, (function (fieldName) {
266
- return historyRowArg + "." + fieldName;
267
- })).join(", ") + ");\nEND;\n$$ LANGUAGE plpgsql;";
244
+ var makeInsertFnQuery = function (pgSchema) {
245
+ var historyRowArg = "history_row";
246
+ var historyTablePath = "\"" + pgSchema + "\".\"" + historyTableName + "\"";
247
+ var originTablePath = "\"" + pgSchema + "\".\"" + originTableName + "\"";
248
+ var previousHistoryFieldsAreNullStr = Belt_Array.map(previousChangeFieldNames, (function (fieldName) {
249
+ return historyRowArg + "." + fieldName + " IS NULL";
250
+ })).join(" OR ");
251
+ var currentChangeFieldNamesCommaSeparated = currentChangeFieldNames.join(", ");
252
+ var dataFieldNamesDoubleQuoted = Belt_Array.map(dataFieldNames, (function (fieldName) {
253
+ return "\"" + fieldName + "\"";
254
+ }));
255
+ var dataFieldNamesCommaSeparated = dataFieldNamesDoubleQuoted.join(", ");
256
+ return "CREATE OR REPLACE FUNCTION " + insertFnName + "(" + historyRowArg + " " + historyTablePath + ", should_copy_current_entity BOOLEAN)\nRETURNS void AS $$\nDECLARE\n v_previous_record RECORD;\n v_origin_record RECORD;\nBEGIN\n -- Check if previous values are not provided\n IF " + previousHistoryFieldsAreNullStr + " THEN\n -- Find the most recent record for the same id\n SELECT " + currentChangeFieldNamesCommaSeparated + " INTO v_previous_record\n FROM " + historyTablePath + "\n WHERE " + id + " = " + historyRowArg + "." + id + "\n ORDER BY " + Belt_Array.map(currentChangeFieldNames, (function (fieldName) {
257
+ return fieldName + " DESC";
258
+ })).join(", ") + "\n LIMIT 1;\n\n -- If a previous record exists, use its values\n IF FOUND THEN\n " + Belt_Array.map(Belt_Array.zip(currentChangeFieldNames, previousChangeFieldNames), (function (param) {
259
+ return historyRowArg + "." + param[1] + " := v_previous_record." + param[0] + ";";
260
+ })).join(" ") + "\n ElSIF should_copy_current_entity THEN\n -- Check if a value for the id exists in the origin table and if so, insert a history row for it.\n SELECT " + dataFieldNamesCommaSeparated + " FROM " + originTablePath + " WHERE id = " + historyRowArg + "." + id + " INTO v_origin_record;\n IF FOUND THEN\n INSERT INTO " + historyTablePath + " (" + currentChangeFieldNamesCommaSeparated + ", " + dataFieldNamesCommaSeparated + ", \"" + actionFieldName + "\")\n -- SET the current change data fields to 0 since we don't know what they were\n -- and it doesn't matter provided they are less than any new values\n VALUES (" + Belt_Array.map(currentChangeFieldNames, (function (param) {
261
+ return "0";
262
+ })).join(", ") + ", " + Belt_Array.map(dataFieldNames, (function (fieldName) {
263
+ return "v_origin_record.\"" + fieldName + "\"";
264
+ })).join(", ") + ", 'SET');\n\n " + Belt_Array.map(previousChangeFieldNames, (function (previousFieldName) {
265
+ return historyRowArg + "." + previousFieldName + " := 0;";
266
+ })).join(" ") + "\n END IF;\n END IF;\n END IF;\n\n INSERT INTO " + historyTablePath + " (" + allFieldNamesDoubleQuoted.join(", ") + ")\n VALUES (" + Belt_Array.map(allFieldNamesDoubleQuoted, (function (fieldName) {
267
+ return historyRowArg + "." + fieldName;
268
+ })).join(", ") + ");\nEND;\n$$ LANGUAGE plpgsql;";
269
+ };
268
270
  var insertFnString = "(sql, rowArgs, shouldCopyCurrentEntity) =>\n sql\`select " + insertFnName + "(ROW(" + Belt_Array.map(allFieldNamesDoubleQuoted, (function (fieldNameDoubleQuoted) {
269
271
  return "\${rowArgs[" + fieldNameDoubleQuoted + "]\}";
270
272
  })).join(", ") + ", NULL), --NULL argument for SERIAL field\n \${shouldCopyCurrentEntity});\`";
@@ -272,7 +274,7 @@ function fromTable(table, pgSchema, schema) {
272
274
  var schema$1 = makeHistoryRowSchema(schema);
273
275
  return {
274
276
  table: table$1,
275
- createInsertFnQuery: createInsertFnQuery,
277
+ makeInsertFnQuery: makeInsertFnQuery,
276
278
  schema: schema$1,
277
279
  schemaRows: S$RescriptSchema.array(schema$1),
278
280
  insertFn: insertFn
@@ -0,0 +1,43 @@
1
+ /* TypeScript file generated from InternalTable.res by genType. */
2
+
3
+ /* eslint-disable */
4
+ /* tslint:disable */
5
+
6
+ import type {Json_t as Js_Json_t} from '../../src/Js.shim';
7
+
8
+ import type {t as Address_t} from '../../src/Address.gen';
9
+
10
+ export type EventSyncState_t = {
11
+ readonly chain_id: number;
12
+ readonly block_number: number;
13
+ readonly log_index: number;
14
+ readonly block_timestamp: number
15
+ };
16
+
17
+ export type RawEvents_t = {
18
+ readonly chain_id: number;
19
+ readonly event_id: bigint;
20
+ readonly event_name: string;
21
+ readonly contract_name: string;
22
+ readonly block_number: number;
23
+ readonly log_index: number;
24
+ readonly src_address: Address_t;
25
+ readonly block_hash: string;
26
+ readonly block_timestamp: number;
27
+ readonly block_fields: Js_Json_t;
28
+ readonly transaction_fields: Js_Json_t;
29
+ readonly params: Js_Json_t
30
+ };
31
+
32
+ export type DynamicContractRegistry_t = {
33
+ readonly id: string;
34
+ readonly chain_id: number;
35
+ readonly registering_event_block_number: number;
36
+ readonly registering_event_log_index: number;
37
+ readonly registering_event_block_timestamp: number;
38
+ readonly registering_event_contract_name: string;
39
+ readonly registering_event_name: string;
40
+ readonly registering_event_src_address: Address_t;
41
+ readonly contract_address: Address_t;
42
+ readonly contract_name: string
43
+ };