envio 2.32.2 → 3.0.0-alpha-main-clickhouse-sink
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +1 -0
- package/package.json +6 -5
- package/src/Batch.res +4 -4
- package/src/Change.res +9 -0
- package/src/Change.res.js +2 -0
- package/src/Config.res +5 -5
- package/src/Config.res.js +3 -1
- package/src/Envio.gen.ts +3 -3
- package/src/Envio.res +14 -3
- package/src/EventRegister.res +3 -11
- package/src/EventRegister.res.js +4 -8
- package/src/EventRegister.resi +1 -1
- package/src/InMemoryStore.res +7 -15
- package/src/InMemoryStore.res.js +2 -4
- package/src/InMemoryTable.res +50 -35
- package/src/InMemoryTable.res.js +52 -84
- package/src/Internal.gen.ts +0 -2
- package/src/Internal.res +20 -38
- package/src/Internal.res.js +2 -16
- package/src/Persistence.res +190 -38
- package/src/Persistence.res.js +92 -39
- package/src/PgStorage.res +700 -14
- package/src/PgStorage.res.js +431 -19
- package/src/Platform.res +141 -0
- package/src/Platform.res.js +170 -0
- package/src/Prometheus.res +41 -0
- package/src/Prometheus.res.js +45 -0
- package/src/SafeCheckpointTracking.res +5 -4
- package/src/Sink.res +47 -0
- package/src/Sink.res.js +36 -0
- package/src/Utils.res +2 -0
- package/src/Utils.res.js +3 -0
- package/src/bindings/ClickHouse.res +387 -0
- package/src/bindings/ClickHouse.res.js +274 -0
- package/src/bindings/Postgres.res +15 -0
- package/src/db/EntityHistory.res +33 -156
- package/src/db/EntityHistory.res.js +40 -115
- package/src/db/InternalTable.res +56 -55
- package/src/db/InternalTable.res.js +49 -52
- package/src/db/Table.res +86 -22
- package/src/db/Table.res.js +77 -10
package/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "envio",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "v3.0.0-alpha-main-clickhouse-sink",
|
|
4
4
|
"description": "A latency and sync speed optimized, developer friendly blockchain data indexer.",
|
|
5
5
|
"bin": "./bin.js",
|
|
6
6
|
"main": "./index.js",
|
|
@@ -25,12 +25,13 @@
|
|
|
25
25
|
},
|
|
26
26
|
"homepage": "https://envio.dev",
|
|
27
27
|
"optionalDependencies": {
|
|
28
|
-
"envio-linux-x64": "
|
|
29
|
-
"envio-linux-arm64": "
|
|
30
|
-
"envio-darwin-x64": "
|
|
31
|
-
"envio-darwin-arm64": "
|
|
28
|
+
"envio-linux-x64": "v3.0.0-alpha-main-clickhouse-sink",
|
|
29
|
+
"envio-linux-arm64": "v3.0.0-alpha-main-clickhouse-sink",
|
|
30
|
+
"envio-darwin-x64": "v3.0.0-alpha-main-clickhouse-sink",
|
|
31
|
+
"envio-darwin-arm64": "v3.0.0-alpha-main-clickhouse-sink"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
+
"@clickhouse/client": "1.12.1",
|
|
34
35
|
"@envio-dev/hypersync-client": "0.6.6",
|
|
35
36
|
"@envio-dev/hyperfuel-client": "1.2.2",
|
|
36
37
|
"rescript": "11.1.3",
|
package/src/Batch.res
CHANGED
|
@@ -24,7 +24,7 @@ type t = {
|
|
|
24
24
|
items: array<Internal.item>,
|
|
25
25
|
progressedChainsById: dict<chainAfterBatch>,
|
|
26
26
|
// Unnest-like checkpoint fields:
|
|
27
|
-
checkpointIds: array<
|
|
27
|
+
checkpointIds: array<float>,
|
|
28
28
|
checkpointChainIds: array<int>,
|
|
29
29
|
checkpointBlockNumbers: array<int>,
|
|
30
30
|
checkpointBlockHashes: array<Js.Null.t<string>>,
|
|
@@ -196,7 +196,7 @@ let addReorgCheckpoints = (
|
|
|
196
196
|
for blockNumber in fromBlockExclusive + 1 to toBlockExclusive - 1 {
|
|
197
197
|
switch reorgDetection->ReorgDetection.getHashByBlockNumber(~blockNumber) {
|
|
198
198
|
| Js.Null.Value(hash) =>
|
|
199
|
-
let checkpointId = prevCheckpointId.contents
|
|
199
|
+
let checkpointId = prevCheckpointId.contents +. 1.
|
|
200
200
|
prevCheckpointId := checkpointId
|
|
201
201
|
|
|
202
202
|
mutCheckpointIds->Js.Array2.push(checkpointId)->ignore
|
|
@@ -277,7 +277,7 @@ let prepareOrderedBatch = (
|
|
|
277
277
|
~mutCheckpointEventsProcessed=checkpointEventsProcessed,
|
|
278
278
|
)
|
|
279
279
|
|
|
280
|
-
let checkpointId = prevCheckpointId.contents
|
|
280
|
+
let checkpointId = prevCheckpointId.contents +. 1.
|
|
281
281
|
|
|
282
282
|
items
|
|
283
283
|
->Js.Array2.push(item0)
|
|
@@ -421,7 +421,7 @@ let prepareUnorderedBatch = (
|
|
|
421
421
|
~mutCheckpointEventsProcessed=checkpointEventsProcessed,
|
|
422
422
|
)
|
|
423
423
|
|
|
424
|
-
let checkpointId = prevCheckpointId.contents
|
|
424
|
+
let checkpointId = prevCheckpointId.contents +. 1.
|
|
425
425
|
|
|
426
426
|
checkpointIds->Js.Array2.push(checkpointId)->ignore
|
|
427
427
|
checkpointChainIds->Js.Array2.push(fetchState.chainId)->ignore
|
package/src/Change.res
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
@tag("type")
|
|
2
|
+
type t<'entity> =
|
|
3
|
+
| @as("SET") Set({entityId: string, entity: 'entity, checkpointId: float})
|
|
4
|
+
| @as("DELETE") Delete({entityId: string, checkpointId: float})
|
|
5
|
+
|
|
6
|
+
@get
|
|
7
|
+
external getEntityId: t<'entity> => string = "entityId"
|
|
8
|
+
@get
|
|
9
|
+
external getCheckpointId: t<'entity> => float = "checkpointId"
|
package/src/Config.res
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
open Belt
|
|
2
2
|
|
|
3
|
-
type ecosystem = | @as("evm") Evm | @as("fuel") Fuel
|
|
4
|
-
|
|
5
3
|
type sourceSyncOptions = {
|
|
6
4
|
initialBlockInterval?: int,
|
|
7
5
|
backoffMultiplicative?: float,
|
|
@@ -47,7 +45,7 @@ type t = {
|
|
|
47
45
|
multichain: multichain,
|
|
48
46
|
chainMap: ChainMap.t<chain>,
|
|
49
47
|
defaultChain: option<chain>,
|
|
50
|
-
|
|
48
|
+
platform: Platform.t,
|
|
51
49
|
enableRawEvents: bool,
|
|
52
50
|
preloadHandlers: bool,
|
|
53
51
|
maxAddrInPartition: int,
|
|
@@ -62,7 +60,7 @@ let make = (
|
|
|
62
60
|
~chains: array<chain>=[],
|
|
63
61
|
~enableRawEvents=false,
|
|
64
62
|
~preloadHandlers=false,
|
|
65
|
-
~ecosystem=Evm,
|
|
63
|
+
~ecosystem: Platform.name=Platform.Evm,
|
|
66
64
|
~batchSize=5000,
|
|
67
65
|
~lowercaseAddresses=false,
|
|
68
66
|
~multichain=Unordered,
|
|
@@ -92,6 +90,8 @@ let make = (
|
|
|
92
90
|
})
|
|
93
91
|
})
|
|
94
92
|
|
|
93
|
+
let platform = Platform.fromName(ecosystem)
|
|
94
|
+
|
|
95
95
|
{
|
|
96
96
|
shouldRollbackOnReorg,
|
|
97
97
|
shouldSaveFullHistory,
|
|
@@ -99,7 +99,7 @@ let make = (
|
|
|
99
99
|
chainMap,
|
|
100
100
|
defaultChain: chains->Array.get(0),
|
|
101
101
|
enableRawEvents,
|
|
102
|
-
|
|
102
|
+
platform,
|
|
103
103
|
maxAddrInPartition,
|
|
104
104
|
preloadHandlers,
|
|
105
105
|
batchSize,
|
package/src/Config.res.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
var Utils = require("./Utils.res.js");
|
|
5
5
|
var Js_exn = require("rescript/lib/js/js_exn.js");
|
|
6
6
|
var ChainMap = require("./ChainMap.res.js");
|
|
7
|
+
var Platform = require("./Platform.res.js");
|
|
7
8
|
var Belt_Array = require("rescript/lib/js/belt_Array.js");
|
|
8
9
|
|
|
9
10
|
function make(shouldRollbackOnReorgOpt, shouldSaveFullHistoryOpt, chainsOpt, enableRawEventsOpt, preloadHandlersOpt, ecosystemOpt, batchSizeOpt, lowercaseAddressesOpt, multichainOpt, shouldUseHypersyncClientDecoderOpt, maxAddrInPartitionOpt) {
|
|
@@ -34,13 +35,14 @@ function make(shouldRollbackOnReorgOpt, shouldSaveFullHistoryOpt, chainsOpt, ena
|
|
|
34
35
|
addContractNameToContractNameMapping[addKey] = contract.name;
|
|
35
36
|
}));
|
|
36
37
|
}));
|
|
38
|
+
var platform = Platform.fromName(ecosystem);
|
|
37
39
|
return {
|
|
38
40
|
shouldRollbackOnReorg: shouldRollbackOnReorg,
|
|
39
41
|
shouldSaveFullHistory: shouldSaveFullHistory,
|
|
40
42
|
multichain: multichain,
|
|
41
43
|
chainMap: chainMap,
|
|
42
44
|
defaultChain: Belt_Array.get(chains, 0),
|
|
43
|
-
|
|
45
|
+
platform: platform,
|
|
44
46
|
enableRawEvents: enableRawEvents,
|
|
45
47
|
preloadHandlers: preloadHandlers,
|
|
46
48
|
maxAddrInPartition: maxAddrInPartition,
|
package/src/Envio.gen.ts
CHANGED
|
@@ -11,11 +11,11 @@ import type {Logger as $$logger} from './Types.ts';
|
|
|
11
11
|
|
|
12
12
|
import type {S_t as RescriptSchema_S_t} from 'rescript-schema/RescriptSchema.gen';
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
export type blockEvent = { readonly number: number; readonly chainId: number };
|
|
15
15
|
|
|
16
|
-
export type
|
|
16
|
+
export type fuelBlockEvent = { readonly height: number; readonly chainId: number };
|
|
17
17
|
|
|
18
|
-
export type onBlockArgs<context> = { readonly block:
|
|
18
|
+
export type onBlockArgs<block,context> = { readonly block: block; readonly context: context };
|
|
19
19
|
|
|
20
20
|
export type onBlockOptions<chain> = {
|
|
21
21
|
readonly name: string;
|
package/src/Envio.res
CHANGED
|
@@ -2,12 +2,23 @@
|
|
|
2
2
|
// Should be an entry point after we get rid of the generated project.
|
|
3
3
|
// Don't forget to keep index.d.ts in sync with this file.
|
|
4
4
|
|
|
5
|
+
// EVM block event with 'number' field for backward compatibility
|
|
5
6
|
@genType
|
|
6
|
-
type blockEvent =
|
|
7
|
+
type blockEvent = {
|
|
8
|
+
number: int,
|
|
9
|
+
chainId: int,
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// Fuel block event with 'height' field
|
|
13
|
+
@genType
|
|
14
|
+
type fuelBlockEvent = {
|
|
15
|
+
height: int,
|
|
16
|
+
chainId: int,
|
|
17
|
+
}
|
|
7
18
|
|
|
8
19
|
@genType
|
|
9
|
-
type onBlockArgs<'context> = {
|
|
10
|
-
block:
|
|
20
|
+
type onBlockArgs<'block, 'context> = {
|
|
21
|
+
block: 'block,
|
|
11
22
|
context: 'context,
|
|
12
23
|
}
|
|
13
24
|
|
package/src/EventRegister.res
CHANGED
|
@@ -4,7 +4,7 @@ type registrations = {
|
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
type activeRegistration = {
|
|
7
|
-
|
|
7
|
+
platform: Platform.t,
|
|
8
8
|
multichain: Config.multichain,
|
|
9
9
|
preloadHandlers: bool,
|
|
10
10
|
registrations: registrations,
|
|
@@ -36,9 +36,9 @@ let withRegistration = (fn: activeRegistration => unit) => {
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
let startRegistration = (~
|
|
39
|
+
let startRegistration = (~platform, ~multichain, ~preloadHandlers) => {
|
|
40
40
|
let r = {
|
|
41
|
-
|
|
41
|
+
platform,
|
|
42
42
|
multichain,
|
|
43
43
|
preloadHandlers,
|
|
44
44
|
registrations: {
|
|
@@ -80,14 +80,6 @@ let onBlockOptionsSchema = S.schema(s =>
|
|
|
80
80
|
|
|
81
81
|
let onBlock = (rawOptions: unknown, handler: Internal.onBlockArgs => promise<unit>) => {
|
|
82
82
|
withRegistration(registration => {
|
|
83
|
-
// There's no big reason for this. It's just more work
|
|
84
|
-
switch registration.ecosystem {
|
|
85
|
-
| Evm => ()
|
|
86
|
-
| Fuel =>
|
|
87
|
-
Js.Exn.raiseError(
|
|
88
|
-
"Block Handlers are not supported for non-EVM ecosystems. Please reach out to the Envio team if you need this feature.",
|
|
89
|
-
)
|
|
90
|
-
}
|
|
91
83
|
// We need to get timestamp for ordered multichain mode
|
|
92
84
|
switch registration.multichain {
|
|
93
85
|
| Unordered => ()
|
package/src/EventRegister.res.js
CHANGED
|
@@ -28,9 +28,9 @@ function withRegistration(fn) {
|
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
function startRegistration(
|
|
31
|
+
function startRegistration(platform, multichain, preloadHandlers) {
|
|
32
32
|
var r = {
|
|
33
|
-
|
|
33
|
+
platform: platform,
|
|
34
34
|
multichain: multichain,
|
|
35
35
|
preloadHandlers: preloadHandlers,
|
|
36
36
|
registrations: {
|
|
@@ -71,12 +71,8 @@ var onBlockOptionsSchema = S$RescriptSchema.schema(function (s) {
|
|
|
71
71
|
|
|
72
72
|
function onBlock(rawOptions, handler) {
|
|
73
73
|
withRegistration(function (registration) {
|
|
74
|
-
var match = registration.
|
|
75
|
-
if (match
|
|
76
|
-
Js_exn.raiseError("Block Handlers are not supported for non-EVM ecosystems. Please reach out to the Envio team if you need this feature.");
|
|
77
|
-
}
|
|
78
|
-
var match$1 = registration.multichain;
|
|
79
|
-
if (match$1 === "ordered") {
|
|
74
|
+
var match = registration.multichain;
|
|
75
|
+
if (match === "ordered") {
|
|
80
76
|
Js_exn.raiseError("Block Handlers are not supported for ordered multichain mode. Please reach out to the Envio team if you need this feature or enable unordered multichain mode with `unordered_multichain_mode: true` in your config.");
|
|
81
77
|
}
|
|
82
78
|
if (registration.preloadHandlers) {
|
package/src/EventRegister.resi
CHANGED
package/src/InMemoryStore.res
CHANGED
|
@@ -22,9 +22,7 @@ module EntityTables = {
|
|
|
22
22
|
switch self->Utils.Dict.dangerouslyGetNonOption(entityName) {
|
|
23
23
|
| Some(table) =>
|
|
24
24
|
table->(
|
|
25
|
-
Utils.magic: InMemoryTable.Entity.t<Internal.entity> => InMemoryTable.Entity.t<
|
|
26
|
-
entity,
|
|
27
|
-
>
|
|
25
|
+
Utils.magic: InMemoryTable.Entity.t<Internal.entity> => InMemoryTable.Entity.t<entity>
|
|
28
26
|
)
|
|
29
27
|
|
|
30
28
|
| None =>
|
|
@@ -53,13 +51,10 @@ type t = {
|
|
|
53
51
|
rawEvents: InMemoryTable.t<rawEventsKey, InternalTable.RawEvents.t>,
|
|
54
52
|
entities: dict<InMemoryTable.Entity.t<Internal.entity>>,
|
|
55
53
|
effects: dict<effectCacheInMemTable>,
|
|
56
|
-
rollbackTargetCheckpointId: option<
|
|
54
|
+
rollbackTargetCheckpointId: option<Internal.checkpointId>,
|
|
57
55
|
}
|
|
58
56
|
|
|
59
|
-
let make = (
|
|
60
|
-
~entities: array<Internal.entityConfig>,
|
|
61
|
-
~rollbackTargetCheckpointId=?,
|
|
62
|
-
): t => {
|
|
57
|
+
let make = (~entities: array<Internal.entityConfig>, ~rollbackTargetCheckpointId=?): t => {
|
|
63
58
|
rawEvents: InMemoryTable.make(~hash=hashRawEventsKey),
|
|
64
59
|
entities: EntityTables.make(entities),
|
|
65
60
|
effects: Js.Dict.empty(),
|
|
@@ -105,9 +100,7 @@ let isRollingBack = (inMemoryStore: t) => inMemoryStore.rollbackTargetCheckpoint
|
|
|
105
100
|
|
|
106
101
|
let setBatchDcs = (inMemoryStore: t, ~batch: Batch.t, ~shouldSaveHistory) => {
|
|
107
102
|
let inMemTable =
|
|
108
|
-
inMemoryStore->getInMemTable(
|
|
109
|
-
~entityConfig=InternalTable.DynamicContractRegistry.config,
|
|
110
|
-
)
|
|
103
|
+
inMemoryStore->getInMemTable(~entityConfig=InternalTable.DynamicContractRegistry.config)
|
|
111
104
|
|
|
112
105
|
let itemIdx = ref(0)
|
|
113
106
|
|
|
@@ -140,11 +133,11 @@ let setBatchDcs = (inMemoryStore: t, ~batch: Batch.t, ~shouldSaveHistory) => {
|
|
|
140
133
|
}
|
|
141
134
|
|
|
142
135
|
inMemTable->InMemoryTable.Entity.set(
|
|
143
|
-
{
|
|
136
|
+
Set({
|
|
144
137
|
entityId: entity.id,
|
|
145
138
|
checkpointId,
|
|
146
|
-
|
|
147
|
-
},
|
|
139
|
+
entity: entity->InternalTable.DynamicContractRegistry.castToInternal,
|
|
140
|
+
}),
|
|
148
141
|
~shouldSaveHistory,
|
|
149
142
|
)
|
|
150
143
|
}
|
|
@@ -154,4 +147,3 @@ let setBatchDcs = (inMemoryStore: t, ~batch: Batch.t, ~shouldSaveHistory) => {
|
|
|
154
147
|
itemIdx := itemIdx.contents + checkpointEventsProcessed
|
|
155
148
|
}
|
|
156
149
|
}
|
|
157
|
-
|
package/src/InMemoryStore.res.js
CHANGED
|
@@ -137,11 +137,9 @@ function setBatchDcs(inMemoryStore, batch, shouldSaveHistory) {
|
|
|
137
137
|
contract_name: entity_contract_name
|
|
138
138
|
};
|
|
139
139
|
InMemoryTable.Entity.set(inMemTable, {
|
|
140
|
+
type: "SET",
|
|
140
141
|
entityId: entity_id,
|
|
141
|
-
|
|
142
|
-
TAG: "Set",
|
|
143
|
-
_0: entity
|
|
144
|
-
},
|
|
142
|
+
entity: entity,
|
|
145
143
|
checkpointId: checkpointId
|
|
146
144
|
}, shouldSaveHistory, undefined);
|
|
147
145
|
}
|
package/src/InMemoryTable.res
CHANGED
|
@@ -39,7 +39,8 @@ module Entity = {
|
|
|
39
39
|
type indexFieldNameToIndices = t<TableIndices.Index.t, indicesSerializedToValue>
|
|
40
40
|
|
|
41
41
|
type entityWithIndices<'entity> = {
|
|
42
|
-
|
|
42
|
+
latest: option<'entity>,
|
|
43
|
+
status: Internal.inMemoryStoreEntityStatus<'entity>,
|
|
43
44
|
entityIndices: Utils.Set.t<TableIndices.Index.t>,
|
|
44
45
|
}
|
|
45
46
|
type t<'entity> = {
|
|
@@ -147,18 +148,20 @@ module Entity = {
|
|
|
147
148
|
//or if allowOverWriteEntity is true (used for mockDb in test helpers)
|
|
148
149
|
if shouldWriteEntity {
|
|
149
150
|
let entityIndices = Utils.Set.make()
|
|
150
|
-
|
|
151
|
+
switch entity {
|
|
151
152
|
| Some(entity) =>
|
|
152
153
|
//update table indices in the case where there
|
|
153
154
|
//is an already set entity
|
|
154
155
|
inMemTable->updateIndices(~entity, ~entityIndices)
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
| None => InitialReadFromDb(NotSet)
|
|
156
|
+
| None => ()
|
|
158
157
|
}
|
|
159
158
|
inMemTable.table.dict->Js.Dict.set(
|
|
160
159
|
key->inMemTable.table.hash,
|
|
161
|
-
{
|
|
160
|
+
{
|
|
161
|
+
latest: entity,
|
|
162
|
+
status: Loaded,
|
|
163
|
+
entityIndices,
|
|
164
|
+
},
|
|
162
165
|
)
|
|
163
166
|
}
|
|
164
167
|
}
|
|
@@ -166,56 +169,64 @@ module Entity = {
|
|
|
166
169
|
let setRow = set
|
|
167
170
|
let set = (
|
|
168
171
|
inMemTable: t<'entity>,
|
|
169
|
-
|
|
172
|
+
change: Change.t<'entity>,
|
|
170
173
|
~shouldSaveHistory,
|
|
171
174
|
~containsRollbackDiffChange=false,
|
|
172
175
|
) => {
|
|
173
176
|
//New entity row with only the latest update
|
|
174
177
|
@inline
|
|
175
|
-
let
|
|
176
|
-
|
|
177
|
-
history: shouldSaveHistory
|
|
178
|
+
let newStatus = () => Internal.Updated({
|
|
179
|
+
latestChange: change,
|
|
180
|
+
history: shouldSaveHistory
|
|
181
|
+
? [change]
|
|
182
|
+
: Utils.Array.immutableEmpty->(Utils.magic: array<unknown> => array<Change.t<'entity>>),
|
|
178
183
|
containsRollbackDiffChange,
|
|
179
184
|
})
|
|
185
|
+
let latest = switch change {
|
|
186
|
+
| Set({entity}) => Some(entity)
|
|
187
|
+
| Delete(_) => None
|
|
188
|
+
}
|
|
180
189
|
|
|
181
|
-
let
|
|
182
|
-
| None => {
|
|
183
|
-
| Some({
|
|
184
|
-
|
|
190
|
+
let updatedEntityRecord = switch inMemTable.table->get(change->Change.getEntityId) {
|
|
191
|
+
| None => {latest, status: newStatus(), entityIndices: Utils.Set.make()}
|
|
192
|
+
| Some({status: Loaded, entityIndices}) => {
|
|
193
|
+
latest,
|
|
194
|
+
status: newStatus(),
|
|
185
195
|
entityIndices,
|
|
186
196
|
}
|
|
187
|
-
| Some({
|
|
188
|
-
let
|
|
189
|
-
|
|
197
|
+
| Some({status: Updated(previous_values), entityIndices}) =>
|
|
198
|
+
let newStatus = Internal.Updated({
|
|
199
|
+
latestChange: change,
|
|
190
200
|
history: switch shouldSaveHistory {
|
|
191
201
|
// This prevents two db actions in the same event on the same entity from being recorded to the history table.
|
|
192
|
-
| true
|
|
202
|
+
| true
|
|
203
|
+
if previous_values.latestChange->Change.getCheckpointId ===
|
|
204
|
+
change->Change.getCheckpointId =>
|
|
193
205
|
previous_values.history->Utils.Array.setIndexImmutable(
|
|
194
206
|
previous_values.history->Array.length - 1,
|
|
195
|
-
|
|
207
|
+
change,
|
|
196
208
|
)
|
|
197
|
-
| true => [...previous_values.history,
|
|
209
|
+
| true => [...previous_values.history, change]
|
|
198
210
|
| false => previous_values.history
|
|
199
211
|
},
|
|
200
212
|
containsRollbackDiffChange: previous_values.containsRollbackDiffChange,
|
|
201
213
|
})
|
|
202
|
-
{
|
|
214
|
+
{latest, status: newStatus, entityIndices}
|
|
203
215
|
}
|
|
204
216
|
|
|
205
|
-
switch
|
|
206
|
-
| Set(entity) =>
|
|
207
|
-
|
|
217
|
+
switch change {
|
|
218
|
+
| Set({entity}) =>
|
|
219
|
+
inMemTable->updateIndices(~entity, ~entityIndices=updatedEntityRecord.entityIndices)
|
|
220
|
+
| Delete({entityId}) =>
|
|
221
|
+
inMemTable->deleteEntityFromIndices(
|
|
222
|
+
~entityId,
|
|
223
|
+
~entityIndices=updatedEntityRecord.entityIndices,
|
|
224
|
+
)
|
|
208
225
|
}
|
|
209
|
-
inMemTable.table->setRow(
|
|
226
|
+
inMemTable.table->setRow(change->Change.getEntityId, updatedEntityRecord)
|
|
210
227
|
}
|
|
211
228
|
|
|
212
|
-
let rowToEntity = row =>
|
|
213
|
-
switch row.entityRow {
|
|
214
|
-
| Internal.Updated({latest: {entityUpdateAction: Set(entity)}}) => Some(entity)
|
|
215
|
-
| Updated({latest: {entityUpdateAction: Delete}}) => None
|
|
216
|
-
| InitialReadFromDb(AlreadySet(entity)) => Some(entity)
|
|
217
|
-
| InitialReadFromDb(NotSet) => None
|
|
218
|
-
}
|
|
229
|
+
let rowToEntity = row => row.latest
|
|
219
230
|
|
|
220
231
|
let getRow = get
|
|
221
232
|
|
|
@@ -330,10 +341,15 @@ module Entity = {
|
|
|
330
341
|
}
|
|
331
342
|
}
|
|
332
343
|
|
|
333
|
-
let
|
|
344
|
+
let updates = (inMemTable: t<'entity>) => {
|
|
334
345
|
inMemTable.table
|
|
335
346
|
->values
|
|
336
|
-
->Array.
|
|
347
|
+
->Array.keepMapU(v =>
|
|
348
|
+
switch v.status {
|
|
349
|
+
| Updated(update) => Some(update)
|
|
350
|
+
| Loaded => None
|
|
351
|
+
}
|
|
352
|
+
)
|
|
337
353
|
}
|
|
338
354
|
|
|
339
355
|
let values = (inMemTable: t<'entity>) => {
|
|
@@ -353,4 +369,3 @@ module Entity = {
|
|
|
353
369
|
},
|
|
354
370
|
}
|
|
355
371
|
}
|
|
356
|
-
|