@powersync/service-module-postgres-storage 0.11.2 → 0.13.0
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/CHANGELOG.md +60 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/@types/migrations/scripts/1771232439485-storage-version.d.ts +3 -0
- package/dist/@types/migrations/scripts/1771424826685-current-data-pending-deletes.d.ts +3 -0
- package/dist/@types/migrations/scripts/1771491856000-sync-plan.d.ts +3 -0
- package/dist/@types/storage/PostgresBucketStorageFactory.d.ts +6 -10
- package/dist/@types/storage/PostgresCompactor.d.ts +10 -3
- package/dist/@types/storage/PostgresSyncRulesStorage.d.ts +5 -3
- package/dist/@types/storage/batch/OperationBatch.d.ts +2 -2
- package/dist/@types/storage/batch/PostgresBucketBatch.d.ts +12 -9
- package/dist/@types/storage/batch/PostgresPersistedBatch.d.ts +17 -5
- package/dist/@types/storage/current-data-store.d.ts +85 -0
- package/dist/@types/storage/current-data-table.d.ts +9 -0
- package/dist/@types/storage/sync-rules/PostgresPersistedSyncRulesContent.d.ts +1 -10
- package/dist/@types/storage/table-id.d.ts +2 -0
- package/dist/@types/types/models/CurrentData.d.ts +18 -3
- package/dist/@types/types/models/SyncRules.d.ts +12 -2
- package/dist/@types/types/models/json.d.ts +11 -0
- package/dist/@types/types/types.d.ts +2 -0
- package/dist/@types/utils/bson.d.ts +1 -1
- package/dist/@types/utils/db.d.ts +9 -0
- package/dist/@types/utils/test-utils.d.ts +1 -1
- package/dist/migrations/scripts/1771232439485-storage-version.js +111 -0
- package/dist/migrations/scripts/1771232439485-storage-version.js.map +1 -0
- package/dist/migrations/scripts/1771424826685-current-data-pending-deletes.js +8 -0
- package/dist/migrations/scripts/1771424826685-current-data-pending-deletes.js.map +1 -0
- package/dist/migrations/scripts/1771491856000-sync-plan.js +91 -0
- package/dist/migrations/scripts/1771491856000-sync-plan.js.map +1 -0
- package/dist/storage/PostgresBucketStorageFactory.js +56 -58
- package/dist/storage/PostgresBucketStorageFactory.js.map +1 -1
- package/dist/storage/PostgresCompactor.js +55 -66
- package/dist/storage/PostgresCompactor.js.map +1 -1
- package/dist/storage/PostgresSyncRulesStorage.js +23 -15
- package/dist/storage/PostgresSyncRulesStorage.js.map +1 -1
- package/dist/storage/batch/OperationBatch.js +2 -1
- package/dist/storage/batch/OperationBatch.js.map +1 -1
- package/dist/storage/batch/PostgresBucketBatch.js +286 -213
- package/dist/storage/batch/PostgresBucketBatch.js.map +1 -1
- package/dist/storage/batch/PostgresPersistedBatch.js +86 -81
- package/dist/storage/batch/PostgresPersistedBatch.js.map +1 -1
- package/dist/storage/current-data-store.js +270 -0
- package/dist/storage/current-data-store.js.map +1 -0
- package/dist/storage/current-data-table.js +22 -0
- package/dist/storage/current-data-table.js.map +1 -0
- package/dist/storage/sync-rules/PostgresPersistedSyncRulesContent.js +14 -30
- package/dist/storage/sync-rules/PostgresPersistedSyncRulesContent.js.map +1 -1
- package/dist/storage/table-id.js +8 -0
- package/dist/storage/table-id.js.map +1 -0
- package/dist/types/models/CurrentData.js +11 -2
- package/dist/types/models/CurrentData.js.map +1 -1
- package/dist/types/models/SyncRules.js +12 -1
- package/dist/types/models/SyncRules.js.map +1 -1
- package/dist/types/models/json.js +21 -0
- package/dist/types/models/json.js.map +1 -0
- package/dist/utils/bson.js.map +1 -1
- package/dist/utils/db.js +41 -0
- package/dist/utils/db.js.map +1 -1
- package/dist/utils/test-utils.js +50 -14
- package/dist/utils/test-utils.js.map +1 -1
- package/package.json +9 -9
- package/src/migrations/scripts/1771232439485-storage-version.ts +44 -0
- package/src/migrations/scripts/1771424826685-current-data-pending-deletes.ts +10 -0
- package/src/migrations/scripts/1771491856000-sync-plan.ts +21 -0
- package/src/storage/PostgresBucketStorageFactory.ts +69 -68
- package/src/storage/PostgresCompactor.ts +63 -72
- package/src/storage/PostgresSyncRulesStorage.ts +30 -17
- package/src/storage/batch/OperationBatch.ts +4 -3
- package/src/storage/batch/PostgresBucketBatch.ts +306 -238
- package/src/storage/batch/PostgresPersistedBatch.ts +92 -84
- package/src/storage/current-data-store.ts +326 -0
- package/src/storage/current-data-table.ts +26 -0
- package/src/storage/sync-rules/PostgresPersistedSyncRulesContent.ts +13 -33
- package/src/storage/table-id.ts +9 -0
- package/src/types/models/CurrentData.ts +17 -4
- package/src/types/models/SyncRules.ts +16 -1
- package/src/types/models/json.ts +26 -0
- package/src/utils/bson.ts +1 -1
- package/src/utils/db.ts +47 -0
- package/src/utils/test-utils.ts +42 -15
- package/test/src/__snapshots__/storage.test.ts.snap +148 -6
- package/test/src/__snapshots__/storage_compacting.test.ts.snap +17 -0
- package/test/src/__snapshots__/storage_sync.test.ts.snap +2211 -21
- package/test/src/migrations.test.ts +9 -2
- package/test/src/storage.test.ts +137 -131
- package/test/src/storage_compacting.test.ts +113 -2
- package/test/src/storage_sync.test.ts +148 -4
- package/test/src/util.ts +5 -2
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import { pick } from '../utils/ts-codec.js';
|
|
2
|
+
import * as models from '../types/models/CurrentData.js';
|
|
3
|
+
const TruncateCurrentDataCodec = pick(models.V1CurrentData, ['buckets', 'lookups', 'source_key']);
|
|
4
|
+
const LookupKeyCodec = pick(models.V1CurrentData, ['source_key', 'source_table']);
|
|
5
|
+
export const V1_CURRENT_DATA_TABLE = 'current_data';
|
|
6
|
+
export const V3_CURRENT_DATA_TABLE = 'v3_current_data';
|
|
7
|
+
export class PostgresCurrentDataStore {
|
|
8
|
+
table;
|
|
9
|
+
softDeleteEnabled;
|
|
10
|
+
constructor(storageConfig) {
|
|
11
|
+
this.softDeleteEnabled = storageConfig.softDeleteCurrentData;
|
|
12
|
+
this.table = storageConfig.softDeleteCurrentData ? V3_CURRENT_DATA_TABLE : V1_CURRENT_DATA_TABLE;
|
|
13
|
+
}
|
|
14
|
+
streamTruncateRows(db, options) {
|
|
15
|
+
return db.streamRows({
|
|
16
|
+
statement: `
|
|
17
|
+
SELECT
|
|
18
|
+
buckets,
|
|
19
|
+
lookups,
|
|
20
|
+
source_key
|
|
21
|
+
FROM
|
|
22
|
+
${this.table}
|
|
23
|
+
WHERE
|
|
24
|
+
group_id = $1
|
|
25
|
+
AND source_table = $2
|
|
26
|
+
${this.wherePendingDelete({ onlyLiveRows: true })}
|
|
27
|
+
LIMIT
|
|
28
|
+
$3
|
|
29
|
+
FOR NO KEY UPDATE
|
|
30
|
+
`,
|
|
31
|
+
params: [
|
|
32
|
+
{ type: 'int4', value: options.groupId },
|
|
33
|
+
{ type: 'varchar', value: options.sourceTableId },
|
|
34
|
+
{ type: 'int4', value: options.limit }
|
|
35
|
+
]
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
decodeTruncateRow(row) {
|
|
39
|
+
return TruncateCurrentDataCodec.decode(row);
|
|
40
|
+
}
|
|
41
|
+
streamSizeRows(db, options) {
|
|
42
|
+
return db.streamRows({
|
|
43
|
+
statement: `
|
|
44
|
+
WITH
|
|
45
|
+
filter_data AS (
|
|
46
|
+
SELECT
|
|
47
|
+
decode(FILTER ->> 'source_key', 'hex') AS source_key,
|
|
48
|
+
(FILTER ->> 'source_table') AS source_table_id
|
|
49
|
+
FROM
|
|
50
|
+
jsonb_array_elements($1::jsonb) AS FILTER
|
|
51
|
+
)
|
|
52
|
+
SELECT
|
|
53
|
+
octet_length(c.data) AS data_size,
|
|
54
|
+
c.source_table,
|
|
55
|
+
c.source_key
|
|
56
|
+
FROM
|
|
57
|
+
${this.table} c
|
|
58
|
+
JOIN filter_data f ON c.source_table = f.source_table_id
|
|
59
|
+
AND c.source_key = f.source_key
|
|
60
|
+
WHERE
|
|
61
|
+
c.group_id = $2
|
|
62
|
+
FOR NO KEY UPDATE
|
|
63
|
+
`,
|
|
64
|
+
params: [
|
|
65
|
+
{ type: 'jsonb', value: options.lookups },
|
|
66
|
+
{ type: 'int4', value: options.groupId }
|
|
67
|
+
]
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
streamLookupRows(db, options) {
|
|
71
|
+
const selectColumns = options.skipExistingRows ? `c.source_table, c.source_key` : `c.*`;
|
|
72
|
+
return db.streamRows({
|
|
73
|
+
statement: `
|
|
74
|
+
SELECT
|
|
75
|
+
${selectColumns}
|
|
76
|
+
FROM
|
|
77
|
+
${this.table} c
|
|
78
|
+
JOIN (
|
|
79
|
+
SELECT
|
|
80
|
+
decode(FILTER ->> 'source_key', 'hex') AS source_key,
|
|
81
|
+
FILTER ->> 'source_table' AS source_table_id
|
|
82
|
+
FROM
|
|
83
|
+
jsonb_array_elements($1::jsonb) AS FILTER
|
|
84
|
+
) f ON c.source_table = f.source_table_id
|
|
85
|
+
AND c.source_key = f.source_key
|
|
86
|
+
WHERE
|
|
87
|
+
c.group_id = $2
|
|
88
|
+
FOR NO KEY UPDATE;
|
|
89
|
+
`,
|
|
90
|
+
params: [
|
|
91
|
+
{ type: 'jsonb', value: options.lookups },
|
|
92
|
+
{ type: 'int4', value: options.groupId }
|
|
93
|
+
]
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
decodeLookupRow(row, skipExistingRows) {
|
|
97
|
+
if (skipExistingRows) {
|
|
98
|
+
return LookupKeyCodec.decode(row);
|
|
99
|
+
}
|
|
100
|
+
return this.softDeleteEnabled ? models.V3CurrentData.decode(row) : models.V1CurrentData.decode(row);
|
|
101
|
+
}
|
|
102
|
+
async flushUpserts(db, updates) {
|
|
103
|
+
if (updates.length == 0) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (this.softDeleteEnabled) {
|
|
107
|
+
await db.sql `
|
|
108
|
+
INSERT INTO
|
|
109
|
+
v3_current_data (
|
|
110
|
+
group_id,
|
|
111
|
+
source_table,
|
|
112
|
+
source_key,
|
|
113
|
+
buckets,
|
|
114
|
+
data,
|
|
115
|
+
lookups,
|
|
116
|
+
pending_delete
|
|
117
|
+
)
|
|
118
|
+
SELECT
|
|
119
|
+
group_id,
|
|
120
|
+
source_table,
|
|
121
|
+
decode(source_key, 'hex') AS source_key,
|
|
122
|
+
buckets::jsonb AS buckets,
|
|
123
|
+
decode(data, 'hex') AS data,
|
|
124
|
+
array(
|
|
125
|
+
SELECT
|
|
126
|
+
decode(element, 'hex')
|
|
127
|
+
FROM
|
|
128
|
+
unnest(lookups) AS element
|
|
129
|
+
) AS lookups,
|
|
130
|
+
CASE
|
|
131
|
+
WHEN pending_delete IS NOT NULL THEN nextval('op_id_sequence')
|
|
132
|
+
ELSE NULL
|
|
133
|
+
END AS pending_delete
|
|
134
|
+
FROM
|
|
135
|
+
json_to_recordset(${{ type: 'json', value: updates }}::json) AS t (
|
|
136
|
+
group_id integer,
|
|
137
|
+
source_table text,
|
|
138
|
+
source_key text,
|
|
139
|
+
buckets text,
|
|
140
|
+
data text,
|
|
141
|
+
lookups TEXT[],
|
|
142
|
+
pending_delete bigint
|
|
143
|
+
)
|
|
144
|
+
ON CONFLICT (group_id, source_table, source_key) DO UPDATE
|
|
145
|
+
SET
|
|
146
|
+
buckets = EXCLUDED.buckets,
|
|
147
|
+
data = EXCLUDED.data,
|
|
148
|
+
lookups = EXCLUDED.lookups,
|
|
149
|
+
pending_delete = EXCLUDED.pending_delete;
|
|
150
|
+
`.execute();
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
await db.sql `
|
|
154
|
+
INSERT INTO
|
|
155
|
+
current_data (
|
|
156
|
+
group_id,
|
|
157
|
+
source_table,
|
|
158
|
+
source_key,
|
|
159
|
+
buckets,
|
|
160
|
+
data,
|
|
161
|
+
lookups
|
|
162
|
+
)
|
|
163
|
+
SELECT
|
|
164
|
+
group_id,
|
|
165
|
+
source_table,
|
|
166
|
+
decode(source_key, 'hex') AS source_key,
|
|
167
|
+
buckets::jsonb AS buckets,
|
|
168
|
+
decode(data, 'hex') AS data,
|
|
169
|
+
array(
|
|
170
|
+
SELECT
|
|
171
|
+
decode(element, 'hex')
|
|
172
|
+
FROM
|
|
173
|
+
unnest(lookups) AS element
|
|
174
|
+
) AS lookups
|
|
175
|
+
FROM
|
|
176
|
+
json_to_recordset(${{ type: 'json', value: updates }}::json) AS t (
|
|
177
|
+
group_id integer,
|
|
178
|
+
source_table text,
|
|
179
|
+
source_key text,
|
|
180
|
+
buckets text,
|
|
181
|
+
data text,
|
|
182
|
+
lookups TEXT[]
|
|
183
|
+
)
|
|
184
|
+
ON CONFLICT (group_id, source_table, source_key) DO UPDATE
|
|
185
|
+
SET
|
|
186
|
+
buckets = EXCLUDED.buckets,
|
|
187
|
+
data = EXCLUDED.data,
|
|
188
|
+
lookups = EXCLUDED.lookups;
|
|
189
|
+
`.execute();
|
|
190
|
+
}
|
|
191
|
+
async flushDeletes(db, options) {
|
|
192
|
+
if (options.deletes.length == 0) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
if (this.softDeleteEnabled) {
|
|
196
|
+
await db.sql `
|
|
197
|
+
WITH
|
|
198
|
+
conditions AS (
|
|
199
|
+
SELECT
|
|
200
|
+
source_table,
|
|
201
|
+
decode(source_key_hex, 'hex') AS source_key
|
|
202
|
+
FROM
|
|
203
|
+
jsonb_to_recordset(${{
|
|
204
|
+
type: 'jsonb',
|
|
205
|
+
value: options.deletes
|
|
206
|
+
}}::jsonb) AS t (source_table text, source_key_hex text)
|
|
207
|
+
)
|
|
208
|
+
DELETE FROM v3_current_data USING conditions
|
|
209
|
+
WHERE
|
|
210
|
+
v3_current_data.group_id = ${{ type: 'int4', value: options.groupId }}
|
|
211
|
+
AND v3_current_data.source_table = conditions.source_table
|
|
212
|
+
AND v3_current_data.source_key = conditions.source_key;
|
|
213
|
+
`.execute();
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
await db.sql `
|
|
217
|
+
WITH
|
|
218
|
+
conditions AS (
|
|
219
|
+
SELECT
|
|
220
|
+
source_table,
|
|
221
|
+
decode(source_key_hex, 'hex') AS source_key
|
|
222
|
+
FROM
|
|
223
|
+
jsonb_to_recordset(${{
|
|
224
|
+
type: 'jsonb',
|
|
225
|
+
value: options.deletes
|
|
226
|
+
}}::jsonb) AS t (source_table text, source_key_hex text)
|
|
227
|
+
)
|
|
228
|
+
DELETE FROM current_data USING conditions
|
|
229
|
+
WHERE
|
|
230
|
+
current_data.group_id = ${{ type: 'int4', value: options.groupId }}
|
|
231
|
+
AND current_data.source_table = conditions.source_table
|
|
232
|
+
AND current_data.source_key = conditions.source_key;
|
|
233
|
+
`.execute();
|
|
234
|
+
}
|
|
235
|
+
async cleanupPendingDeletes(db, options) {
|
|
236
|
+
if (!this.softDeleteEnabled) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
await db.sql `
|
|
240
|
+
DELETE FROM v3_current_data
|
|
241
|
+
WHERE
|
|
242
|
+
group_id = ${{ type: 'int4', value: options.groupId }}
|
|
243
|
+
AND pending_delete IS NOT NULL
|
|
244
|
+
AND pending_delete <= ${{ type: 'int8', value: options.lastCheckpoint }}
|
|
245
|
+
`.execute();
|
|
246
|
+
}
|
|
247
|
+
async deleteGroupRows(db, options) {
|
|
248
|
+
if (this.softDeleteEnabled) {
|
|
249
|
+
await db.sql `
|
|
250
|
+
DELETE FROM v3_current_data
|
|
251
|
+
WHERE
|
|
252
|
+
group_id = ${{ type: 'int4', value: options.groupId }}
|
|
253
|
+
`.execute();
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
await db.sql `
|
|
257
|
+
DELETE FROM current_data
|
|
258
|
+
WHERE
|
|
259
|
+
group_id = ${{ type: 'int4', value: options.groupId }}
|
|
260
|
+
`.execute();
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
wherePendingDelete(options) {
|
|
264
|
+
if (this.softDeleteEnabled && options.onlyLiveRows) {
|
|
265
|
+
return `AND pending_delete IS NULL`;
|
|
266
|
+
}
|
|
267
|
+
return ``;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
//# sourceMappingURL=current-data-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"current-data-store.js","sourceRoot":"","sources":["../../src/storage/current-data-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ServiceAssertionError } from '@powersync/lib-services-framework';
|
|
2
|
+
export const V1_CURRENT_DATA_TABLE = 'current_data';
|
|
3
|
+
export const V3_CURRENT_DATA_TABLE = 'v3_current_data';
|
|
4
|
+
/**
|
|
5
|
+
* The table used by a specific storage version for general current_data access.
|
|
6
|
+
*/
|
|
7
|
+
export function getCommonCurrentDataTable(storageConfig) {
|
|
8
|
+
return storageConfig.softDeleteCurrentData ? V3_CURRENT_DATA_TABLE : V1_CURRENT_DATA_TABLE;
|
|
9
|
+
}
|
|
10
|
+
export function getV1CurrentDataTable(storageConfig) {
|
|
11
|
+
if (storageConfig.softDeleteCurrentData) {
|
|
12
|
+
throw new ServiceAssertionError('current_data table cannot be used when softDeleteCurrentData is enabled');
|
|
13
|
+
}
|
|
14
|
+
return V1_CURRENT_DATA_TABLE;
|
|
15
|
+
}
|
|
16
|
+
export function getV3CurrentDataTable(storageConfig) {
|
|
17
|
+
if (!storageConfig.softDeleteCurrentData) {
|
|
18
|
+
throw new ServiceAssertionError('v3_current_data table cannot be used when softDeleteCurrentData is disabled');
|
|
19
|
+
}
|
|
20
|
+
return V3_CURRENT_DATA_TABLE;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=current-data-table.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"current-data-table.js","sourceRoot":"","sources":["../../src/storage/current-data-table.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAG1E,MAAM,CAAC,MAAM,qBAAqB,GAAG,cAAc,CAAC;AACpD,MAAM,CAAC,MAAM,qBAAqB,GAAG,iBAAiB,CAAC;AAEvD;;GAEG;AACH,MAAM,UAAU,yBAAyB,CAAC,aAA2C;IACnF,OAAO,aAAa,CAAC,qBAAqB,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,qBAAqB,CAAC;AAC7F,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,aAA2C;IAC/E,IAAI,aAAa,CAAC,qBAAqB,EAAE,CAAC;QACxC,MAAM,IAAI,qBAAqB,CAAC,yEAAyE,CAAC,CAAC;IAC7G,CAAC;IACD,OAAO,qBAAqB,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,aAA2C;IAC/E,IAAI,CAAC,aAAa,CAAC,qBAAqB,EAAE,CAAC;QACzC,MAAM,IAAI,qBAAqB,CAAC,6EAA6E,CAAC,CAAC;IACjH,CAAC;IACD,OAAO,qBAAqB,CAAC;AAC/B,CAAC"}
|
|
@@ -1,39 +1,23 @@
|
|
|
1
1
|
import * as lib_postgres from '@powersync/lib-service-postgres';
|
|
2
2
|
import { ErrorCode, logger, ServiceError } from '@powersync/lib-services-framework';
|
|
3
|
-
import {
|
|
4
|
-
export class PostgresPersistedSyncRulesContent {
|
|
3
|
+
import { storage } from '@powersync/service-core';
|
|
4
|
+
export class PostgresPersistedSyncRulesContent extends storage.PersistedSyncRulesContent {
|
|
5
5
|
db;
|
|
6
|
-
slot_name;
|
|
7
|
-
id;
|
|
8
|
-
sync_rules_content;
|
|
9
|
-
last_checkpoint_lsn;
|
|
10
|
-
last_fatal_error;
|
|
11
|
-
last_keepalive_ts;
|
|
12
|
-
last_checkpoint_ts;
|
|
13
|
-
active;
|
|
14
6
|
current_lock = null;
|
|
15
7
|
constructor(db, row) {
|
|
8
|
+
super({
|
|
9
|
+
id: Number(row.id),
|
|
10
|
+
sync_rules_content: row.content,
|
|
11
|
+
compiled_plan: row.sync_plan,
|
|
12
|
+
last_checkpoint_lsn: row.last_checkpoint_lsn,
|
|
13
|
+
slot_name: row.slot_name,
|
|
14
|
+
last_fatal_error: row.last_fatal_error,
|
|
15
|
+
last_checkpoint_ts: row.last_checkpoint_ts ? new Date(row.last_checkpoint_ts) : null,
|
|
16
|
+
last_keepalive_ts: row.last_keepalive_ts ? new Date(row.last_keepalive_ts) : null,
|
|
17
|
+
active: row.state == 'ACTIVE',
|
|
18
|
+
storageVersion: row.storage_version ?? storage.LEGACY_STORAGE_VERSION
|
|
19
|
+
});
|
|
16
20
|
this.db = db;
|
|
17
|
-
this.id = Number(row.id);
|
|
18
|
-
this.sync_rules_content = row.content;
|
|
19
|
-
this.last_checkpoint_lsn = row.last_checkpoint_lsn;
|
|
20
|
-
this.slot_name = row.slot_name;
|
|
21
|
-
this.last_fatal_error = row.last_fatal_error;
|
|
22
|
-
this.last_checkpoint_ts = row.last_checkpoint_ts ? new Date(row.last_checkpoint_ts) : null;
|
|
23
|
-
this.last_keepalive_ts = row.last_keepalive_ts ? new Date(row.last_keepalive_ts) : null;
|
|
24
|
-
this.active = row.state == 'ACTIVE';
|
|
25
|
-
}
|
|
26
|
-
parsed(options) {
|
|
27
|
-
return {
|
|
28
|
-
id: this.id,
|
|
29
|
-
slot_name: this.slot_name,
|
|
30
|
-
sync_rules: SqlSyncRules.fromYaml(this.sync_rules_content, options),
|
|
31
|
-
hydratedSyncRules() {
|
|
32
|
-
return this.sync_rules.config.hydrate({
|
|
33
|
-
hydrationState: versionedHydrationState(this.id)
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
21
|
}
|
|
38
22
|
async lock() {
|
|
39
23
|
const manager = new lib_postgres.PostgresLockManager({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PostgresPersistedSyncRulesContent.js","sourceRoot":"","sources":["../../../src/storage/sync-rules/PostgresPersistedSyncRulesContent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,YAAY,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"PostgresPersistedSyncRulesContent.js","sourceRoot":"","sources":["../../../src/storage/sync-rules/PostgresPersistedSyncRulesContent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,YAAY,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACpF,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAGlD,MAAM,OAAO,iCAAkC,SAAQ,OAAO,CAAC,yBAAyB;IAI5E;IAHV,YAAY,GAAmC,IAAI,CAAC;IAEpD,YACU,EAA+B,EACvC,GAA4B;QAE5B,KAAK,CAAC;YACJ,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YAClB,kBAAkB,EAAE,GAAG,CAAC,OAAO;YAC/B,aAAa,EAAE,GAAG,CAAC,SAAS;YAC5B,mBAAmB,EAAE,GAAG,CAAC,mBAAmB;YAC5C,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,gBAAgB,EAAE,GAAG,CAAC,gBAAgB;YACtC,kBAAkB,EAAE,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,IAAI;YACpF,iBAAiB,EAAE,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,IAAI;YACjF,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,QAAQ;YAC7B,cAAc,EAAE,GAAG,CAAC,eAAe,IAAI,OAAO,CAAC,sBAAsB;SACtE,CAAC,CAAC;QAdK,OAAE,GAAF,EAAE,CAA6B;IAezC,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC,mBAAmB,CAAC;YACnD,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,IAAI,EAAE,cAAc,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,SAAS,EAAE;SAChD,CAAC,CAAC;QACH,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;QAC3C,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,YAAY,CACpB,SAAS,CAAC,WAAW,EACrB,eAAe,IAAI,CAAC,EAAE,uDAAuD,CAC9E,CAAC;QACJ,CAAC;QAED,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;YACtC,IAAI,CAAC;gBACH,MAAM,UAAU,CAAC,OAAO,EAAE,CAAC;YAC7B,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,MAAM,CAAC,KAAK,CAAC,wBAAwB,EAAE,CAAC,CAAC,CAAC;gBAC1C,aAAa,CAAC,QAAQ,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC,EAAE,MAAM,CAAC,CAAC;QAEX,OAAO,CAAC,IAAI,CAAC,YAAY,GAAG;YAC1B,aAAa,EAAE,IAAI,CAAC,EAAE;YACtB,OAAO,EAAE,KAAK,IAAI,EAAE;gBAClB,aAAa,CAAC,QAAQ,CAAC,CAAC;gBACxB,OAAO,UAAU,CAAC,OAAO,EAAE,CAAC;YAC9B,CAAC;SACF,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ServiceAssertionError } from '@powersync/lib-services-framework';
|
|
2
|
+
export function postgresTableId(id) {
|
|
3
|
+
if (typeof id == 'string') {
|
|
4
|
+
return id;
|
|
5
|
+
}
|
|
6
|
+
throw new ServiceAssertionError(`Expected string table id, got ObjectId`);
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=table-id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table-id.js","sourceRoot":"","sources":["../../src/storage/table-id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAG1E,MAAM,UAAU,eAAe,CAAC,EAAyB;IACvD,IAAI,OAAO,EAAE,IAAI,QAAQ,EAAE,CAAC;QAC1B,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,IAAI,qBAAqB,CAAC,wCAAwC,CAAC,CAAC;AAC5E,CAAC"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import * as t from 'ts-codec';
|
|
2
|
-
import { hexBuffer, jsonb, pgwire_number } from '../codecs.js';
|
|
2
|
+
import { bigint, hexBuffer, jsonb, pgwire_number } from '../codecs.js';
|
|
3
3
|
export const CurrentBucket = t.object({
|
|
4
4
|
bucket: t.string,
|
|
5
5
|
table: t.string,
|
|
6
6
|
id: t.string
|
|
7
7
|
});
|
|
8
|
-
export const
|
|
8
|
+
export const V1CurrentData = t.object({
|
|
9
9
|
buckets: jsonb(t.array(CurrentBucket)),
|
|
10
10
|
data: hexBuffer,
|
|
11
11
|
group_id: pgwire_number,
|
|
@@ -13,4 +13,13 @@ export const CurrentData = t.object({
|
|
|
13
13
|
source_key: hexBuffer,
|
|
14
14
|
source_table: t.string
|
|
15
15
|
});
|
|
16
|
+
export const V3CurrentData = t.object({
|
|
17
|
+
buckets: jsonb(t.array(CurrentBucket)),
|
|
18
|
+
data: hexBuffer,
|
|
19
|
+
group_id: pgwire_number,
|
|
20
|
+
lookups: t.array(hexBuffer),
|
|
21
|
+
source_key: hexBuffer,
|
|
22
|
+
source_table: t.string,
|
|
23
|
+
pending_delete: t.Null.or(bigint)
|
|
24
|
+
});
|
|
16
25
|
//# sourceMappingURL=CurrentData.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CurrentData.js","sourceRoot":"","sources":["../../../src/types/models/CurrentData.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,UAAU,CAAC;AAC9B,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"CurrentData.js","sourceRoot":"","sources":["../../../src/types/models/CurrentData.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,UAAU,CAAC;AAC9B,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAEvE,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,MAAM,EAAE,CAAC,CAAC,MAAM;IAChB,KAAK,EAAE,CAAC,CAAC,MAAM;IACf,EAAE,EAAE,CAAC,CAAC,MAAM;CACb,CAAC,CAAC;AAKH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IACtC,IAAI,EAAE,SAAS;IACf,QAAQ,EAAE,aAAa;IACvB,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC;IAC3B,UAAU,EAAE,SAAS;IACrB,YAAY,EAAE,CAAC,CAAC,MAAM;CACvB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IACtC,IAAI,EAAE,SAAS;IACf,QAAQ,EAAE,aAAa;IACvB,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC;IAC3B,UAAU,EAAE,SAAS;IACrB,YAAY,EAAE,CAAC,CAAC,MAAM;IACtB,cAAc,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC;CAClC,CAAC,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { framework, storage } from '@powersync/service-core';
|
|
2
2
|
import * as t from 'ts-codec';
|
|
3
3
|
import { bigint, pgwire_number } from '../codecs.js';
|
|
4
|
+
import { jsonContainerObject } from './json.js';
|
|
4
5
|
export const SyncRules = t.object({
|
|
5
6
|
id: pgwire_number,
|
|
6
7
|
state: t.Enum(storage.SyncRuleState),
|
|
@@ -46,6 +47,16 @@ export const SyncRules = t.object({
|
|
|
46
47
|
*/
|
|
47
48
|
last_fatal_error: t.Null.or(t.string),
|
|
48
49
|
keepalive_op: t.Null.or(bigint),
|
|
49
|
-
|
|
50
|
+
storage_version: t.Null.or(pgwire_number).optional(),
|
|
51
|
+
content: t.string,
|
|
52
|
+
sync_plan: t.Null.or(jsonContainerObject(t.object({
|
|
53
|
+
plan: t.any,
|
|
54
|
+
compatibility: t.object({
|
|
55
|
+
edition: t.number,
|
|
56
|
+
overrides: t.record(t.boolean),
|
|
57
|
+
maxTimeValuePrecision: t.number.optional()
|
|
58
|
+
}),
|
|
59
|
+
eventDescriptors: t.record(t.array(t.string))
|
|
60
|
+
})))
|
|
50
61
|
});
|
|
51
62
|
//# sourceMappingURL=SyncRules.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SyncRules.js","sourceRoot":"","sources":["../../../src/types/models/SyncRules.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,CAAC,MAAM,UAAU,CAAC;AAC9B,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"SyncRules.js","sourceRoot":"","sources":["../../../src/types/models/SyncRules.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,CAAC,MAAM,UAAU,CAAC;AAC9B,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAEhD,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC;IAChC,EAAE,EAAE,aAAa;IACjB,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC;IACpC;;;;OAIG;IACH,aAAa,EAAE,CAAC,CAAC,OAAO;IACxB;;OAEG;IACH,YAAY,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;IACjC;;;;OAIG;IACH,eAAe,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC;IAClC;;OAEG;IACH,mBAAmB,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;IACxC;;OAEG;IACH,oBAAoB,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;IACzC,SAAS,EAAE,CAAC,CAAC,MAAM;IACnB;;;;OAIG;IACH,kBAAkB,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC;IACpD;;;;OAIG;IACH,iBAAiB,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC;IACnD;;OAEG;IACH,gBAAgB,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;IACrC,YAAY,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC;IAC/B,eAAe,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,QAAQ,EAAE;IACpD,OAAO,EAAE,CAAC,CAAC,MAAM;IACjB,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAClB,mBAAmB,CACjB,CAAC,CAAC,MAAM,CAAC;QACP,IAAI,EAAE,CAAC,CAAC,GAAG;QACX,aAAa,EAAE,CAAC,CAAC,MAAM,CAAC;YACtB,OAAO,EAAE,CAAC,CAAC,MAAM;YACjB,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;YAC9B,qBAAqB,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE;SAC3C,CAAC;QACF,gBAAgB,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;KAC9C,CAAC,CACH,CACF;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { JsonContainer } from '@powersync/service-jsonbig';
|
|
2
|
+
import { codec } from 'ts-codec';
|
|
3
|
+
/**
|
|
4
|
+
* Wraps a codec to support {@link JsonContainer} values.
|
|
5
|
+
*
|
|
6
|
+
* Because our postgres client implementation wraps JSON objects in a {@link JsonContainer}, this intermediate layer is
|
|
7
|
+
* required to use JSON columns from Postgres in `ts-codec` models.
|
|
8
|
+
*
|
|
9
|
+
* Note that this serializes and deserializes values using {@link JSON}, so bigints are not supported.
|
|
10
|
+
*/
|
|
11
|
+
export function jsonContainerObject(inner) {
|
|
12
|
+
return codec(inner._tag, (input) => {
|
|
13
|
+
return new JsonContainer(JSON.stringify(inner.encode(input)));
|
|
14
|
+
}, (json) => {
|
|
15
|
+
if (!(json instanceof JsonContainer)) {
|
|
16
|
+
throw new Error('Expected JsonContainer');
|
|
17
|
+
}
|
|
18
|
+
return inner.decode(JSON.parse(json.data));
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=json.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.js","sourceRoot":"","sources":["../../../src/types/models/json.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAS,KAAK,EAAE,MAAM,UAAU,CAAC;AAExC;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CAAO,KAAkB;IAC1D,OAAO,KAAK,CACV,KAAK,CAAC,IAAI,EACV,CAAC,KAAK,EAAE,EAAE;QACR,OAAO,IAAI,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAChE,CAAC,EACD,CAAC,IAAI,EAAE,EAAE;QACP,IAAI,CAAC,CAAC,IAAI,YAAY,aAAa,CAAC,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAC5C,CAAC;QAED,OAAO,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC7C,CAAC,CACF,CAAC;AACJ,CAAC"}
|
package/dist/utils/bson.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bson.js","sourceRoot":"","sources":["../../src/utils/bson.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B;;;GAGG;AAEH,MAAM,UAAU,iBAAiB,CAAC,
|
|
1
|
+
{"version":3,"file":"bson.js","sourceRoot":"","sources":["../../src/utils/bson.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B;;;GAGG;AAEH,MAAM,UAAU,iBAAiB,CAAC,OAA8B,EAAE,EAAqB;IACrF,oCAAoC;IACpC,IAAI,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;QACvB,mDAAmD;QACnD,OAAO,GAAG,OAAO,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;IAC1C,CAAC;IACD,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;IAC3D,OAAO,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;AAC3C,CAAC"}
|
package/dist/utils/db.js
CHANGED
|
@@ -5,6 +5,9 @@ export const NOTIFICATION_CHANNEL = 'powersynccheckpoints';
|
|
|
5
5
|
* Re export for prettier to detect the tag better
|
|
6
6
|
*/
|
|
7
7
|
export const sql = lib_postgres.sql;
|
|
8
|
+
/**
|
|
9
|
+
* Drop all Postgres storage tables used by the service, including migrations.
|
|
10
|
+
*/
|
|
8
11
|
export const dropTables = async (client) => {
|
|
9
12
|
// Lock a connection for automatic schema search paths
|
|
10
13
|
await client.lockConnection(async (db) => {
|
|
@@ -14,11 +17,49 @@ export const dropTables = async (client) => {
|
|
|
14
17
|
await db.sql `DROP TABLE IF EXISTS instance`.execute();
|
|
15
18
|
await db.sql `DROP TABLE IF EXISTS bucket_data`.execute();
|
|
16
19
|
await db.sql `DROP TABLE IF EXISTS current_data`.execute();
|
|
20
|
+
await db.sql `DROP TABLE IF EXISTS v3_current_data`.execute();
|
|
17
21
|
await db.sql `DROP TABLE IF EXISTS source_tables`.execute();
|
|
18
22
|
await db.sql `DROP TABLE IF EXISTS write_checkpoints`.execute();
|
|
19
23
|
await db.sql `DROP TABLE IF EXISTS custom_write_checkpoints`.execute();
|
|
20
24
|
await db.sql `DROP SEQUENCE IF EXISTS op_id_sequence`.execute();
|
|
21
25
|
await db.sql `DROP SEQUENCE IF EXISTS sync_rules_id_sequence`.execute();
|
|
26
|
+
await db.sql `DROP TABLE IF EXISTS migrations`.execute();
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Clear all Postgres storage tables and reset sequences.
|
|
31
|
+
*
|
|
32
|
+
* Does not clear migration state.
|
|
33
|
+
*/
|
|
34
|
+
export const truncateTables = async (db) => {
|
|
35
|
+
// Lock a connection for automatic schema search paths
|
|
36
|
+
await db.query({
|
|
37
|
+
statement: `TRUNCATE TABLE bucket_data,
|
|
38
|
+
bucket_parameters,
|
|
39
|
+
sync_rules,
|
|
40
|
+
instance,
|
|
41
|
+
current_data,
|
|
42
|
+
source_tables,
|
|
43
|
+
write_checkpoints,
|
|
44
|
+
custom_write_checkpoints,
|
|
45
|
+
connection_report_events RESTART IDENTITY CASCADE
|
|
46
|
+
`
|
|
47
|
+
}, {
|
|
48
|
+
// TRUNCATE if v3_current_data exists
|
|
49
|
+
statement: `DO $$
|
|
50
|
+
BEGIN
|
|
51
|
+
IF to_regclass('v3_current_data') IS NOT NULL THEN
|
|
52
|
+
EXECUTE 'TRUNCATE TABLE v3_current_data RESTART IDENTITY CASCADE';
|
|
53
|
+
END IF;
|
|
54
|
+
END $$;`
|
|
55
|
+
}, {
|
|
56
|
+
statement: `ALTER SEQUENCE IF EXISTS op_id_sequence RESTART
|
|
57
|
+
WITH
|
|
58
|
+
1`
|
|
59
|
+
}, {
|
|
60
|
+
statement: `ALTER SEQUENCE IF EXISTS sync_rules_id_sequence RESTART
|
|
61
|
+
WITH
|
|
62
|
+
1`
|
|
22
63
|
});
|
|
23
64
|
};
|
|
24
65
|
//# sourceMappingURL=db.js.map
|
package/dist/utils/db.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/utils/db.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,YAAY,MAAM,iCAAiC,CAAC;AAEhE,MAAM,CAAC,MAAM,mBAAmB,GAAG,WAAW,CAAC;AAE/C,MAAM,CAAC,MAAM,oBAAoB,GAAG,sBAAsB,CAAC;AAE3D;;GAEG;AACH,MAAM,CAAC,MAAM,GAAG,GAAG,YAAY,CAAC,GAAG,CAAC;AAEpC,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,EAAE,MAAmC,EAAE,EAAE;IACtE,sDAAsD;IACtD,MAAM,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;QACvC,MAAM,EAAE,CAAC,GAAG,CAAA,kCAAkC,CAAC,OAAO,EAAE,CAAC;QACzD,MAAM,EAAE,CAAC,GAAG,CAAA,wCAAwC,CAAC,OAAO,EAAE,CAAC;QAC/D,MAAM,EAAE,CAAC,GAAG,CAAA,iCAAiC,CAAC,OAAO,EAAE,CAAC;QACxD,MAAM,EAAE,CAAC,GAAG,CAAA,+BAA+B,CAAC,OAAO,EAAE,CAAC;QACtD,MAAM,EAAE,CAAC,GAAG,CAAA,kCAAkC,CAAC,OAAO,EAAE,CAAC;QACzD,MAAM,EAAE,CAAC,GAAG,CAAA,mCAAmC,CAAC,OAAO,EAAE,CAAC;QAC1D,MAAM,EAAE,CAAC,GAAG,CAAA,oCAAoC,CAAC,OAAO,EAAE,CAAC;QAC3D,MAAM,EAAE,CAAC,GAAG,CAAA,wCAAwC,CAAC,OAAO,EAAE,CAAC;QAC/D,MAAM,EAAE,CAAC,GAAG,CAAA,+CAA+C,CAAC,OAAO,EAAE,CAAC;QACtE,MAAM,EAAE,CAAC,GAAG,CAAA,wCAAwC,CAAC,OAAO,EAAE,CAAC;QAC/D,MAAM,EAAE,CAAC,GAAG,CAAA,gDAAgD,CAAC,OAAO,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/utils/db.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,YAAY,MAAM,iCAAiC,CAAC;AAEhE,MAAM,CAAC,MAAM,mBAAmB,GAAG,WAAW,CAAC;AAE/C,MAAM,CAAC,MAAM,oBAAoB,GAAG,sBAAsB,CAAC;AAE3D;;GAEG;AACH,MAAM,CAAC,MAAM,GAAG,GAAG,YAAY,CAAC,GAAG,CAAC;AAEpC;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,EAAE,MAAmC,EAAE,EAAE;IACtE,sDAAsD;IACtD,MAAM,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;QACvC,MAAM,EAAE,CAAC,GAAG,CAAA,kCAAkC,CAAC,OAAO,EAAE,CAAC;QACzD,MAAM,EAAE,CAAC,GAAG,CAAA,wCAAwC,CAAC,OAAO,EAAE,CAAC;QAC/D,MAAM,EAAE,CAAC,GAAG,CAAA,iCAAiC,CAAC,OAAO,EAAE,CAAC;QACxD,MAAM,EAAE,CAAC,GAAG,CAAA,+BAA+B,CAAC,OAAO,EAAE,CAAC;QACtD,MAAM,EAAE,CAAC,GAAG,CAAA,kCAAkC,CAAC,OAAO,EAAE,CAAC;QACzD,MAAM,EAAE,CAAC,GAAG,CAAA,mCAAmC,CAAC,OAAO,EAAE,CAAC;QAC1D,MAAM,EAAE,CAAC,GAAG,CAAA,sCAAsC,CAAC,OAAO,EAAE,CAAC;QAC7D,MAAM,EAAE,CAAC,GAAG,CAAA,oCAAoC,CAAC,OAAO,EAAE,CAAC;QAC3D,MAAM,EAAE,CAAC,GAAG,CAAA,wCAAwC,CAAC,OAAO,EAAE,CAAC;QAC/D,MAAM,EAAE,CAAC,GAAG,CAAA,+CAA+C,CAAC,OAAO,EAAE,CAAC;QACtE,MAAM,EAAE,CAAC,GAAG,CAAA,wCAAwC,CAAC,OAAO,EAAE,CAAC;QAC/D,MAAM,EAAE,CAAC,GAAG,CAAA,gDAAgD,CAAC,OAAO,EAAE,CAAC;QACvE,MAAM,EAAE,CAAC,GAAG,CAAA,iCAAiC,CAAC,OAAO,EAAE,CAAC;IAC1D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EAAE,EAA+B,EAAE,EAAE;IACtE,sDAAsD;IACtD,MAAM,EAAE,CAAC,KAAK,CACZ;QACE,SAAS,EAAE;;;;;;;;;KASZ;KACA,EACD;QACE,qCAAqC;QACrC,SAAS,EAAE;;;;;gBAKD;KACX,EACD;QACE,SAAS,EAAE;;UAEP;KACL,EACD;QACE,SAAS,EAAE;;UAEP;KACL,CACF,CAAC;AACJ,CAAC,CAAC"}
|