@powersync/service-core-tests 0.14.0 → 0.15.1
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 +40 -0
- package/dist/test-utils/general-utils.d.ts +22 -3
- package/dist/test-utils/general-utils.js +56 -3
- package/dist/test-utils/general-utils.js.map +1 -1
- package/dist/test-utils/stream_utils.js +2 -2
- package/dist/test-utils/stream_utils.js.map +1 -1
- package/dist/tests/register-compacting-tests.d.ts +1 -1
- package/dist/tests/register-compacting-tests.js +360 -297
- package/dist/tests/register-compacting-tests.js.map +1 -1
- package/dist/tests/register-data-storage-checkpoint-tests.d.ts +1 -1
- package/dist/tests/register-data-storage-checkpoint-tests.js +59 -48
- package/dist/tests/register-data-storage-checkpoint-tests.js.map +1 -1
- package/dist/tests/register-data-storage-data-tests.d.ts +2 -2
- package/dist/tests/register-data-storage-data-tests.js +1112 -612
- package/dist/tests/register-data-storage-data-tests.js.map +1 -1
- package/dist/tests/register-data-storage-parameter-tests.d.ts +1 -1
- package/dist/tests/register-data-storage-parameter-tests.js +273 -254
- package/dist/tests/register-data-storage-parameter-tests.js.map +1 -1
- package/dist/tests/register-parameter-compacting-tests.d.ts +1 -1
- package/dist/tests/register-parameter-compacting-tests.js +83 -87
- package/dist/tests/register-parameter-compacting-tests.js.map +1 -1
- package/dist/tests/register-sync-tests.d.ts +2 -1
- package/dist/tests/register-sync-tests.js +479 -451
- package/dist/tests/register-sync-tests.js.map +1 -1
- package/dist/tests/util.d.ts +5 -4
- package/dist/tests/util.js +27 -12
- package/dist/tests/util.js.map +1 -1
- package/package.json +3 -3
- package/src/test-utils/general-utils.ts +81 -4
- package/src/test-utils/stream_utils.ts +2 -2
- package/src/tests/register-compacting-tests.ts +376 -322
- package/src/tests/register-data-storage-checkpoint-tests.ts +85 -53
- package/src/tests/register-data-storage-data-tests.ts +1050 -559
- package/src/tests/register-data-storage-parameter-tests.ts +330 -288
- package/src/tests/register-parameter-compacting-tests.ts +87 -90
- package/src/tests/register-sync-tests.ts +390 -380
- package/src/tests/util.ts +46 -17
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -14,14 +14,11 @@ import * as timers from 'timers/promises';
|
|
|
14
14
|
import { fileURLToPath } from 'url';
|
|
15
15
|
import { expect, test } from 'vitest';
|
|
16
16
|
import * as test_utils from '../test-utils/test-utils-index.js';
|
|
17
|
-
import { METRICS_HELPER } from '../test-utils/test-utils-index.js';
|
|
18
|
-
import { bucketRequest } from './util.js';
|
|
17
|
+
import { bucketRequest, METRICS_HELPER } from '../test-utils/test-utils-index.js';
|
|
19
18
|
|
|
20
19
|
const __filename = fileURLToPath(import.meta.url);
|
|
21
20
|
const __dirname = path.dirname(__filename);
|
|
22
21
|
|
|
23
|
-
const TEST_TABLE = test_utils.makeTestTable('test', ['id']);
|
|
24
|
-
|
|
25
22
|
const BASIC_SYNC_RULES = `
|
|
26
23
|
bucket_definitions:
|
|
27
24
|
mybucket:
|
|
@@ -39,7 +36,15 @@ export const SYNC_SNAPSHOT_PATH = path.resolve(__dirname, '../__snapshots/sync.t
|
|
|
39
36
|
* });
|
|
40
37
|
* ```
|
|
41
38
|
*/
|
|
42
|
-
export function registerSyncTests(
|
|
39
|
+
export function registerSyncTests(
|
|
40
|
+
configOrFactory: storage.TestStorageConfig | storage.TestStorageFactory,
|
|
41
|
+
options: { storageVersion?: number; tableIdStrings?: boolean } = {}
|
|
42
|
+
) {
|
|
43
|
+
const config: storage.TestStorageConfig =
|
|
44
|
+
typeof configOrFactory == 'function'
|
|
45
|
+
? { factory: configOrFactory, tableIdStrings: options.tableIdStrings ?? true }
|
|
46
|
+
: configOrFactory;
|
|
47
|
+
const factory = config.factory;
|
|
43
48
|
createCoreAPIMetrics(METRICS_HELPER.metricsEngine);
|
|
44
49
|
const tracker = new sync.RequestTracker(METRICS_HELPER.metricsEngine);
|
|
45
50
|
const syncContext = new sync.SyncContext({
|
|
@@ -65,31 +70,33 @@ export function registerSyncTests(factory: storage.TestStorageFactory, options:
|
|
|
65
70
|
});
|
|
66
71
|
|
|
67
72
|
const bucketStorage = f.getInstance(syncRules);
|
|
73
|
+
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
74
|
+
const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
68
75
|
|
|
69
|
-
|
|
70
|
-
await batch.save({
|
|
71
|
-
sourceTable: TEST_TABLE,
|
|
72
|
-
tag: storage.SaveOperationTag.INSERT,
|
|
73
|
-
after: {
|
|
74
|
-
id: 't1',
|
|
75
|
-
description: 'Test 1'
|
|
76
|
-
},
|
|
77
|
-
afterReplicaId: 't1'
|
|
78
|
-
});
|
|
76
|
+
await writer.markAllSnapshotDone('0/1');
|
|
79
77
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
78
|
+
await writer.save({
|
|
79
|
+
sourceTable,
|
|
80
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
81
|
+
after: {
|
|
82
|
+
id: 't1',
|
|
83
|
+
description: 'Test 1'
|
|
84
|
+
},
|
|
85
|
+
afterReplicaId: 't1'
|
|
86
|
+
});
|
|
89
87
|
|
|
90
|
-
|
|
88
|
+
await writer.save({
|
|
89
|
+
sourceTable,
|
|
90
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
91
|
+
after: {
|
|
92
|
+
id: 't2',
|
|
93
|
+
description: 'Test 2'
|
|
94
|
+
},
|
|
95
|
+
afterReplicaId: 't2'
|
|
91
96
|
});
|
|
92
97
|
|
|
98
|
+
await writer.commit('0/1');
|
|
99
|
+
|
|
93
100
|
const stream = sync.streamResponse({
|
|
94
101
|
syncContext,
|
|
95
102
|
bucketStorage: bucketStorage,
|
|
@@ -126,31 +133,32 @@ bucket_definitions:
|
|
|
126
133
|
});
|
|
127
134
|
|
|
128
135
|
const bucketStorage = f.getInstance(syncRules);
|
|
136
|
+
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
137
|
+
const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
138
|
+
|
|
139
|
+
await writer.markAllSnapshotDone('0/1');
|
|
140
|
+
await writer.save({
|
|
141
|
+
sourceTable: testTable,
|
|
142
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
143
|
+
after: {
|
|
144
|
+
id: 't1',
|
|
145
|
+
description: 'Test 1'
|
|
146
|
+
},
|
|
147
|
+
afterReplicaId: 't1'
|
|
148
|
+
});
|
|
129
149
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
afterReplicaId: 't1'
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
await batch.save({
|
|
142
|
-
sourceTable: TEST_TABLE,
|
|
143
|
-
tag: storage.SaveOperationTag.INSERT,
|
|
144
|
-
after: {
|
|
145
|
-
id: 'earlier',
|
|
146
|
-
description: 'Test 2'
|
|
147
|
-
},
|
|
148
|
-
afterReplicaId: 'earlier'
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
await batch.commit('0/1');
|
|
150
|
+
await writer.save({
|
|
151
|
+
sourceTable: testTable,
|
|
152
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
153
|
+
after: {
|
|
154
|
+
id: 'earlier',
|
|
155
|
+
description: 'Test 2'
|
|
156
|
+
},
|
|
157
|
+
afterReplicaId: 'earlier'
|
|
152
158
|
});
|
|
153
159
|
|
|
160
|
+
await writer.commit('0/1');
|
|
161
|
+
|
|
154
162
|
const stream = sync.streamResponse({
|
|
155
163
|
syncContext,
|
|
156
164
|
bucketStorage,
|
|
@@ -187,32 +195,33 @@ bucket_definitions:
|
|
|
187
195
|
});
|
|
188
196
|
|
|
189
197
|
const bucketStorage = f.getInstance(syncRules);
|
|
190
|
-
|
|
191
|
-
await
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
198
|
+
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
199
|
+
const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
200
|
+
|
|
201
|
+
await writer.markAllSnapshotDone('0/1');
|
|
202
|
+
// Initial data: Add one priority row and 10k low-priority rows.
|
|
203
|
+
await writer.save({
|
|
204
|
+
sourceTable: testTable,
|
|
205
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
206
|
+
after: {
|
|
207
|
+
id: 'highprio',
|
|
208
|
+
description: 'High priority row'
|
|
209
|
+
},
|
|
210
|
+
afterReplicaId: 'highprio'
|
|
211
|
+
});
|
|
212
|
+
for (let i = 0; i < 10_000; i++) {
|
|
213
|
+
await writer.save({
|
|
214
|
+
sourceTable: testTable,
|
|
195
215
|
tag: storage.SaveOperationTag.INSERT,
|
|
196
216
|
after: {
|
|
197
|
-
id:
|
|
198
|
-
description: '
|
|
217
|
+
id: `${i}`,
|
|
218
|
+
description: 'low prio'
|
|
199
219
|
},
|
|
200
|
-
afterReplicaId:
|
|
220
|
+
afterReplicaId: `${i}`
|
|
201
221
|
});
|
|
202
|
-
|
|
203
|
-
await batch.save({
|
|
204
|
-
sourceTable: TEST_TABLE,
|
|
205
|
-
tag: storage.SaveOperationTag.INSERT,
|
|
206
|
-
after: {
|
|
207
|
-
id: `${i}`,
|
|
208
|
-
description: 'low prio'
|
|
209
|
-
},
|
|
210
|
-
afterReplicaId: `${i}`
|
|
211
|
-
});
|
|
212
|
-
}
|
|
222
|
+
}
|
|
213
223
|
|
|
214
|
-
|
|
215
|
-
});
|
|
224
|
+
await writer.commit('0/1');
|
|
216
225
|
|
|
217
226
|
const stream = sync.streamResponse({
|
|
218
227
|
syncContext,
|
|
@@ -240,20 +249,18 @@ bucket_definitions:
|
|
|
240
249
|
if (sentCheckpoints == 1) {
|
|
241
250
|
// Save new data to interrupt the low-priority sync.
|
|
242
251
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
afterReplicaId: 'highprio2'
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
await batch.commit('0/2');
|
|
252
|
+
// Add another high-priority row. This should interrupt the long-running low-priority sync.
|
|
253
|
+
await writer.save({
|
|
254
|
+
sourceTable: testTable,
|
|
255
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
256
|
+
after: {
|
|
257
|
+
id: 'highprio2',
|
|
258
|
+
description: 'Another high-priority row'
|
|
259
|
+
},
|
|
260
|
+
afterReplicaId: 'highprio2'
|
|
256
261
|
});
|
|
262
|
+
|
|
263
|
+
await writer.commit('0/2');
|
|
257
264
|
} else {
|
|
258
265
|
// Low-priority sync from the first checkpoint was interrupted. This should not happen before
|
|
259
266
|
// 1000 low-priority items were synchronized.
|
|
@@ -297,32 +304,33 @@ bucket_definitions:
|
|
|
297
304
|
});
|
|
298
305
|
|
|
299
306
|
const bucketStorage = f.getInstance(syncRules);
|
|
300
|
-
|
|
301
|
-
await
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
307
|
+
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
308
|
+
const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
309
|
+
|
|
310
|
+
await writer.markAllSnapshotDone('0/1');
|
|
311
|
+
// Initial data: Add one priority row and 10k low-priority rows.
|
|
312
|
+
await writer.save({
|
|
313
|
+
sourceTable: testTable,
|
|
314
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
315
|
+
after: {
|
|
316
|
+
id: 'highprio',
|
|
317
|
+
description: 'user_one'
|
|
318
|
+
},
|
|
319
|
+
afterReplicaId: 'highprio'
|
|
320
|
+
});
|
|
321
|
+
for (let i = 0; i < 10_000; i++) {
|
|
322
|
+
await writer.save({
|
|
323
|
+
sourceTable: testTable,
|
|
305
324
|
tag: storage.SaveOperationTag.INSERT,
|
|
306
325
|
after: {
|
|
307
|
-
id:
|
|
308
|
-
description: '
|
|
326
|
+
id: `${i}`,
|
|
327
|
+
description: 'low prio'
|
|
309
328
|
},
|
|
310
|
-
afterReplicaId:
|
|
329
|
+
afterReplicaId: `${i}`
|
|
311
330
|
});
|
|
312
|
-
|
|
313
|
-
await batch.save({
|
|
314
|
-
sourceTable: TEST_TABLE,
|
|
315
|
-
tag: storage.SaveOperationTag.INSERT,
|
|
316
|
-
after: {
|
|
317
|
-
id: `${i}`,
|
|
318
|
-
description: 'low prio'
|
|
319
|
-
},
|
|
320
|
-
afterReplicaId: `${i}`
|
|
321
|
-
});
|
|
322
|
-
}
|
|
331
|
+
}
|
|
323
332
|
|
|
324
|
-
|
|
325
|
-
});
|
|
333
|
+
await writer.commit('0/1');
|
|
326
334
|
|
|
327
335
|
const stream = sync.streamResponse({
|
|
328
336
|
syncContext,
|
|
@@ -355,20 +363,18 @@ bucket_definitions:
|
|
|
355
363
|
if (typeof next === 'object' && next !== null) {
|
|
356
364
|
if ('partial_checkpoint_complete' in next) {
|
|
357
365
|
if (sentCheckpoints == 1) {
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
afterReplicaId: 'highprio2'
|
|
368
|
-
});
|
|
369
|
-
|
|
370
|
-
await batch.commit('0/2');
|
|
366
|
+
// Add a high-priority row that doesn't affect this sync stream.
|
|
367
|
+
await writer.save({
|
|
368
|
+
sourceTable: testTable,
|
|
369
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
370
|
+
after: {
|
|
371
|
+
id: 'highprio2',
|
|
372
|
+
description: 'user_two'
|
|
373
|
+
},
|
|
374
|
+
afterReplicaId: 'highprio2'
|
|
371
375
|
});
|
|
376
|
+
|
|
377
|
+
await writer.commit('0/2');
|
|
372
378
|
} else {
|
|
373
379
|
expect(sentCheckpoints).toBe(2);
|
|
374
380
|
expect(sentRows).toBe(10002);
|
|
@@ -389,20 +395,18 @@ bucket_definitions:
|
|
|
389
395
|
if (completedCheckpoints == 1) {
|
|
390
396
|
expect(sentRows).toBe(10001);
|
|
391
397
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
afterReplicaId: 'highprio3'
|
|
402
|
-
});
|
|
403
|
-
|
|
404
|
-
await batch.commit('0/3');
|
|
398
|
+
// Add a high-priority row that affects this sync stream.
|
|
399
|
+
await writer.save({
|
|
400
|
+
sourceTable: testTable,
|
|
401
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
402
|
+
after: {
|
|
403
|
+
id: 'highprio3',
|
|
404
|
+
description: 'user_one'
|
|
405
|
+
},
|
|
406
|
+
afterReplicaId: 'highprio3'
|
|
405
407
|
});
|
|
408
|
+
|
|
409
|
+
await writer.commit('0/3');
|
|
406
410
|
}
|
|
407
411
|
}
|
|
408
412
|
}
|
|
@@ -438,32 +442,33 @@ bucket_definitions:
|
|
|
438
442
|
});
|
|
439
443
|
|
|
440
444
|
const bucketStorage = f.getInstance(syncRules);
|
|
441
|
-
|
|
442
|
-
await
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
445
|
+
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
446
|
+
const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
447
|
+
|
|
448
|
+
await writer.markAllSnapshotDone('0/1');
|
|
449
|
+
// Initial data: Add one priority row and 10k low-priority rows.
|
|
450
|
+
await writer.save({
|
|
451
|
+
sourceTable: testTable,
|
|
452
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
453
|
+
after: {
|
|
454
|
+
id: 'highprio',
|
|
455
|
+
description: 'High priority row'
|
|
456
|
+
},
|
|
457
|
+
afterReplicaId: 'highprio'
|
|
458
|
+
});
|
|
459
|
+
for (let i = 0; i < 2_000; i++) {
|
|
460
|
+
await writer.save({
|
|
461
|
+
sourceTable: testTable,
|
|
446
462
|
tag: storage.SaveOperationTag.INSERT,
|
|
447
463
|
after: {
|
|
448
|
-
id:
|
|
449
|
-
description: '
|
|
464
|
+
id: `${i}`,
|
|
465
|
+
description: 'low prio'
|
|
450
466
|
},
|
|
451
|
-
afterReplicaId:
|
|
467
|
+
afterReplicaId: `${i}`
|
|
452
468
|
});
|
|
453
|
-
|
|
454
|
-
await batch.save({
|
|
455
|
-
sourceTable: TEST_TABLE,
|
|
456
|
-
tag: storage.SaveOperationTag.INSERT,
|
|
457
|
-
after: {
|
|
458
|
-
id: `${i}`,
|
|
459
|
-
description: 'low prio'
|
|
460
|
-
},
|
|
461
|
-
afterReplicaId: `${i}`
|
|
462
|
-
});
|
|
463
|
-
}
|
|
469
|
+
}
|
|
464
470
|
|
|
465
|
-
|
|
466
|
-
});
|
|
471
|
+
await writer.commit('0/1');
|
|
467
472
|
|
|
468
473
|
const stream = sync.streamResponse({
|
|
469
474
|
syncContext,
|
|
@@ -500,31 +505,29 @@ bucket_definitions:
|
|
|
500
505
|
|
|
501
506
|
if (sentRows == 1001) {
|
|
502
507
|
// Save new data to interrupt the low-priority sync.
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
afterReplicaId: '2001'
|
|
524
|
-
});
|
|
525
|
-
|
|
526
|
-
await batch.commit('0/2');
|
|
508
|
+
// Add another high-priority row. This should interrupt the long-running low-priority sync.
|
|
509
|
+
await writer.save({
|
|
510
|
+
sourceTable: testTable,
|
|
511
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
512
|
+
after: {
|
|
513
|
+
id: 'highprio2',
|
|
514
|
+
description: 'Another high-priority row'
|
|
515
|
+
},
|
|
516
|
+
afterReplicaId: 'highprio2'
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
// Also add a low-priority row
|
|
520
|
+
await writer.save({
|
|
521
|
+
sourceTable: testTable,
|
|
522
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
523
|
+
after: {
|
|
524
|
+
id: '2001',
|
|
525
|
+
description: 'Another low-priority row'
|
|
526
|
+
},
|
|
527
|
+
afterReplicaId: '2001'
|
|
527
528
|
});
|
|
529
|
+
|
|
530
|
+
await writer.commit('0/2');
|
|
528
531
|
}
|
|
529
532
|
|
|
530
533
|
if (sentRows >= 1000 && sentRows <= 2001) {
|
|
@@ -567,19 +570,20 @@ bucket_definitions:
|
|
|
567
570
|
content: BASIC_SYNC_RULES
|
|
568
571
|
});
|
|
569
572
|
const bucketStorage = f.getInstance(syncRules);
|
|
570
|
-
|
|
571
|
-
await
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
}
|
|
581
|
-
|
|
573
|
+
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
574
|
+
const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
575
|
+
|
|
576
|
+
await writer.markAllSnapshotDone('0/1');
|
|
577
|
+
await writer.save({
|
|
578
|
+
sourceTable: testTable,
|
|
579
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
580
|
+
after: {
|
|
581
|
+
id: 't1',
|
|
582
|
+
description: 'sync'
|
|
583
|
+
},
|
|
584
|
+
afterReplicaId: 't1'
|
|
582
585
|
});
|
|
586
|
+
await writer.commit('0/1');
|
|
583
587
|
|
|
584
588
|
const stream = sync.streamResponse({
|
|
585
589
|
syncContext,
|
|
@@ -610,9 +614,7 @@ bucket_definitions:
|
|
|
610
614
|
if (receivedCompletions == 1) {
|
|
611
615
|
// Trigger an empty bucket update.
|
|
612
616
|
await bucketStorage.createManagedWriteCheckpoint({ user_id: '', heads: { '1': '1/0' } });
|
|
613
|
-
await
|
|
614
|
-
await batch.commit('1/0');
|
|
615
|
-
});
|
|
617
|
+
await writer.commit('1/0');
|
|
616
618
|
} else {
|
|
617
619
|
break;
|
|
618
620
|
}
|
|
@@ -624,29 +626,30 @@ bucket_definitions:
|
|
|
624
626
|
});
|
|
625
627
|
|
|
626
628
|
test('sync legacy non-raw data', async () => {
|
|
627
|
-
|
|
629
|
+
await using f = await factory();
|
|
628
630
|
|
|
629
631
|
const syncRules = await updateSyncRules(f, {
|
|
630
632
|
content: BASIC_SYNC_RULES
|
|
631
633
|
});
|
|
632
634
|
|
|
633
635
|
const bucketStorage = await f.getInstance(syncRules);
|
|
634
|
-
|
|
635
|
-
const
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
await batch.commit('0/1');
|
|
636
|
+
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
637
|
+
const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
638
|
+
|
|
639
|
+
await writer.markAllSnapshotDone('0/1');
|
|
640
|
+
await writer.save({
|
|
641
|
+
sourceTable: testTable,
|
|
642
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
643
|
+
after: {
|
|
644
|
+
id: 't1',
|
|
645
|
+
description: 'Test\n"string"',
|
|
646
|
+
large_num: 12345678901234567890n
|
|
647
|
+
},
|
|
648
|
+
afterReplicaId: 't1'
|
|
648
649
|
});
|
|
649
650
|
|
|
651
|
+
await writer.commit('0/1');
|
|
652
|
+
|
|
650
653
|
const stream = sync.streamResponse({
|
|
651
654
|
syncContext,
|
|
652
655
|
bucketStorage,
|
|
@@ -702,10 +705,11 @@ bucket_definitions:
|
|
|
702
705
|
});
|
|
703
706
|
|
|
704
707
|
const bucketStorage = await f.getInstance(syncRules);
|
|
708
|
+
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
709
|
+
const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
705
710
|
// Activate
|
|
706
|
-
await
|
|
707
|
-
|
|
708
|
-
});
|
|
711
|
+
await writer.markAllSnapshotDone('0/0');
|
|
712
|
+
await writer.keepalive('0/0');
|
|
709
713
|
|
|
710
714
|
const stream = sync.streamResponse({
|
|
711
715
|
syncContext,
|
|
@@ -727,36 +731,32 @@ bucket_definitions:
|
|
|
727
731
|
|
|
728
732
|
expect(await getCheckpointLines(iter)).toMatchSnapshot();
|
|
729
733
|
|
|
730
|
-
await
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
afterReplicaId: 't1'
|
|
739
|
-
});
|
|
740
|
-
|
|
741
|
-
await batch.commit('0/1');
|
|
734
|
+
await writer.save({
|
|
735
|
+
sourceTable: testTable,
|
|
736
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
737
|
+
after: {
|
|
738
|
+
id: 't1',
|
|
739
|
+
description: 'Test 1'
|
|
740
|
+
},
|
|
741
|
+
afterReplicaId: 't1'
|
|
742
742
|
});
|
|
743
743
|
|
|
744
|
-
|
|
744
|
+
await writer.commit('0/1');
|
|
745
745
|
|
|
746
|
-
await
|
|
747
|
-
await batch.save({
|
|
748
|
-
sourceTable: TEST_TABLE,
|
|
749
|
-
tag: storage.SaveOperationTag.INSERT,
|
|
750
|
-
after: {
|
|
751
|
-
id: 't2',
|
|
752
|
-
description: 'Test 2'
|
|
753
|
-
},
|
|
754
|
-
afterReplicaId: 't2'
|
|
755
|
-
});
|
|
746
|
+
expect(await getCheckpointLines(iter)).toMatchSnapshot();
|
|
756
747
|
|
|
757
|
-
|
|
748
|
+
await writer.save({
|
|
749
|
+
sourceTable: testTable,
|
|
750
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
751
|
+
after: {
|
|
752
|
+
id: 't2',
|
|
753
|
+
description: 'Test 2'
|
|
754
|
+
},
|
|
755
|
+
afterReplicaId: 't2'
|
|
758
756
|
});
|
|
759
757
|
|
|
758
|
+
await writer.commit('0/2');
|
|
759
|
+
|
|
760
760
|
expect(await getCheckpointLines(iter)).toMatchSnapshot();
|
|
761
761
|
});
|
|
762
762
|
|
|
@@ -772,14 +772,13 @@ bucket_definitions:
|
|
|
772
772
|
`
|
|
773
773
|
});
|
|
774
774
|
|
|
775
|
-
const usersTable = test_utils.makeTestTable('users', ['id']);
|
|
776
|
-
const listsTable = test_utils.makeTestTable('lists', ['id']);
|
|
777
|
-
|
|
778
775
|
const bucketStorage = await f.getInstance(syncRules);
|
|
776
|
+
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
777
|
+
const usersTable = await test_utils.resolveTestTable(writer, 'users', ['id'], config, 1);
|
|
778
|
+
|
|
779
779
|
// Activate
|
|
780
|
-
await
|
|
781
|
-
|
|
782
|
-
});
|
|
780
|
+
await writer.markAllSnapshotDone('0/0');
|
|
781
|
+
await writer.keepalive('0/0');
|
|
783
782
|
|
|
784
783
|
const stream = sync.streamResponse({
|
|
785
784
|
syncContext,
|
|
@@ -805,24 +804,24 @@ bucket_definitions:
|
|
|
805
804
|
expect(checkpoint1).toMatchSnapshot();
|
|
806
805
|
|
|
807
806
|
// Add user
|
|
808
|
-
await
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
afterReplicaId: 'user1'
|
|
817
|
-
});
|
|
818
|
-
|
|
819
|
-
await batch.commit('0/1');
|
|
807
|
+
await writer.save({
|
|
808
|
+
sourceTable: usersTable,
|
|
809
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
810
|
+
after: {
|
|
811
|
+
id: 'user1',
|
|
812
|
+
name: 'User 1'
|
|
813
|
+
},
|
|
814
|
+
afterReplicaId: 'user1'
|
|
820
815
|
});
|
|
821
816
|
|
|
817
|
+
await writer.commit('0/1');
|
|
818
|
+
|
|
822
819
|
const checkpoint2 = await getCheckpointLines(iter);
|
|
820
|
+
|
|
821
|
+
const { bucket } = test_utils.bucketRequest(syncRules, 'by_user["user1"]');
|
|
823
822
|
expect(
|
|
824
823
|
(checkpoint2[0] as StreamingSyncCheckpointDiff).checkpoint_diff?.updated_buckets?.map((b) => b.bucket)
|
|
825
|
-
).toEqual([
|
|
824
|
+
).toEqual([bucket]);
|
|
826
825
|
expect(checkpoint2).toMatchSnapshot();
|
|
827
826
|
});
|
|
828
827
|
|
|
@@ -838,25 +837,24 @@ bucket_definitions:
|
|
|
838
837
|
`
|
|
839
838
|
});
|
|
840
839
|
|
|
841
|
-
const usersTable = test_utils.makeTestTable('users', ['id']);
|
|
842
|
-
const listsTable = test_utils.makeTestTable('lists', ['id']);
|
|
843
|
-
|
|
844
840
|
const bucketStorage = await f.getInstance(syncRules);
|
|
845
|
-
|
|
846
|
-
await
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
841
|
+
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
842
|
+
const usersTable = await test_utils.resolveTestTable(writer, 'users', ['id'], config, 1);
|
|
843
|
+
const listsTable = await test_utils.resolveTestTable(writer, 'lists', ['id'], config, 2);
|
|
844
|
+
|
|
845
|
+
await writer.markAllSnapshotDone('0/1');
|
|
846
|
+
await writer.save({
|
|
847
|
+
sourceTable: usersTable,
|
|
848
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
849
|
+
after: {
|
|
850
|
+
id: 'user1',
|
|
851
|
+
name: 'User 1'
|
|
852
|
+
},
|
|
853
|
+
afterReplicaId: 'user1'
|
|
858
854
|
});
|
|
859
855
|
|
|
856
|
+
await writer.commit('0/1');
|
|
857
|
+
|
|
860
858
|
const stream = sync.streamResponse({
|
|
861
859
|
syncContext,
|
|
862
860
|
bucketStorage,
|
|
@@ -875,31 +873,29 @@ bucket_definitions:
|
|
|
875
873
|
iter.return?.();
|
|
876
874
|
});
|
|
877
875
|
|
|
876
|
+
const { bucket } = bucketRequest(syncRules, 'by_user["user1"]');
|
|
878
877
|
const checkpoint1 = await getCheckpointLines(iter);
|
|
879
|
-
expect((checkpoint1[0] as StreamingSyncCheckpoint).checkpoint?.buckets?.map((b) => b.bucket)).toEqual([
|
|
880
|
-
bucketRequest(syncRules, 'by_user["user1"]')
|
|
881
|
-
]);
|
|
882
|
-
expect(checkpoint1).toMatchSnapshot();
|
|
883
878
|
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
sourceTable: listsTable,
|
|
887
|
-
tag: storage.SaveOperationTag.INSERT,
|
|
888
|
-
after: {
|
|
889
|
-
id: 'list1',
|
|
890
|
-
user_id: 'user1',
|
|
891
|
-
name: 'User 1'
|
|
892
|
-
},
|
|
893
|
-
afterReplicaId: 'list1'
|
|
894
|
-
});
|
|
879
|
+
expect((checkpoint1[0] as StreamingSyncCheckpoint).checkpoint?.buckets?.map((b) => b.bucket)).toEqual([bucket]);
|
|
880
|
+
expect(checkpoint1).toMatchSnapshot();
|
|
895
881
|
|
|
896
|
-
|
|
882
|
+
await writer.save({
|
|
883
|
+
sourceTable: listsTable,
|
|
884
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
885
|
+
after: {
|
|
886
|
+
id: 'list1',
|
|
887
|
+
user_id: 'user1',
|
|
888
|
+
name: 'User 1'
|
|
889
|
+
},
|
|
890
|
+
afterReplicaId: 'list1'
|
|
897
891
|
});
|
|
898
892
|
|
|
893
|
+
await writer.commit('0/1');
|
|
894
|
+
|
|
899
895
|
const checkpoint2 = await getCheckpointLines(iter);
|
|
900
896
|
expect(
|
|
901
897
|
(checkpoint2[0] as StreamingSyncCheckpointDiff).checkpoint_diff?.updated_buckets?.map((b) => b.bucket)
|
|
902
|
-
).toEqual([
|
|
898
|
+
).toEqual([bucket]);
|
|
903
899
|
expect(checkpoint2).toMatchSnapshot();
|
|
904
900
|
});
|
|
905
901
|
|
|
@@ -915,14 +911,13 @@ bucket_definitions:
|
|
|
915
911
|
`
|
|
916
912
|
});
|
|
917
913
|
|
|
918
|
-
const usersTable = test_utils.makeTestTable('users', ['id']);
|
|
919
|
-
const listsTable = test_utils.makeTestTable('lists', ['id']);
|
|
920
|
-
|
|
921
914
|
const bucketStorage = await f.getInstance(syncRules);
|
|
915
|
+
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
916
|
+
const usersTable = await test_utils.resolveTestTable(writer, 'users', ['id'], config, 1);
|
|
917
|
+
const listsTable = await test_utils.resolveTestTable(writer, 'lists', ['id'], config, 2);
|
|
922
918
|
// Activate
|
|
923
|
-
await
|
|
924
|
-
|
|
925
|
-
});
|
|
919
|
+
await writer.markAllSnapshotDone('0/0');
|
|
920
|
+
await writer.keepalive('0/0');
|
|
926
921
|
|
|
927
922
|
const stream = sync.streamResponse({
|
|
928
923
|
syncContext,
|
|
@@ -945,35 +940,36 @@ bucket_definitions:
|
|
|
945
940
|
// Initial empty checkpoint
|
|
946
941
|
expect(await getCheckpointLines(iter)).toMatchSnapshot();
|
|
947
942
|
|
|
948
|
-
await
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
await batch.save({
|
|
961
|
-
sourceTable: usersTable,
|
|
962
|
-
tag: storage.SaveOperationTag.INSERT,
|
|
963
|
-
after: {
|
|
964
|
-
id: 'user1',
|
|
965
|
-
name: 'User 1'
|
|
966
|
-
},
|
|
967
|
-
afterReplicaId: 'user1'
|
|
968
|
-
});
|
|
943
|
+
await writer.markAllSnapshotDone('0/1');
|
|
944
|
+
await writer.save({
|
|
945
|
+
sourceTable: listsTable,
|
|
946
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
947
|
+
after: {
|
|
948
|
+
id: 'list1',
|
|
949
|
+
user_id: 'user1',
|
|
950
|
+
name: 'User 1'
|
|
951
|
+
},
|
|
952
|
+
afterReplicaId: 'list1'
|
|
953
|
+
});
|
|
969
954
|
|
|
970
|
-
|
|
955
|
+
await writer.save({
|
|
956
|
+
sourceTable: usersTable,
|
|
957
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
958
|
+
after: {
|
|
959
|
+
id: 'user1',
|
|
960
|
+
name: 'User 1'
|
|
961
|
+
},
|
|
962
|
+
afterReplicaId: 'user1'
|
|
971
963
|
});
|
|
972
964
|
|
|
965
|
+
await writer.commit('0/1');
|
|
966
|
+
|
|
967
|
+
const { bucket } = test_utils.bucketRequest(syncRules, 'by_user["user1"]');
|
|
968
|
+
|
|
973
969
|
const checkpoint2 = await getCheckpointLines(iter);
|
|
974
970
|
expect(
|
|
975
971
|
(checkpoint2[0] as StreamingSyncCheckpointDiff).checkpoint_diff?.updated_buckets?.map((b) => b.bucket)
|
|
976
|
-
).toEqual([
|
|
972
|
+
).toEqual([bucket]);
|
|
977
973
|
expect(checkpoint2).toMatchSnapshot();
|
|
978
974
|
});
|
|
979
975
|
|
|
@@ -985,10 +981,10 @@ bucket_definitions:
|
|
|
985
981
|
});
|
|
986
982
|
|
|
987
983
|
const bucketStorage = await f.getInstance(syncRules);
|
|
984
|
+
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
988
985
|
// Activate
|
|
989
|
-
await
|
|
990
|
-
|
|
991
|
-
});
|
|
986
|
+
await writer.markAllSnapshotDone('0/0');
|
|
987
|
+
await writer.keepalive('0/0');
|
|
992
988
|
|
|
993
989
|
const exp = Date.now() / 1000 + 0.1;
|
|
994
990
|
|
|
@@ -1030,31 +1026,32 @@ bucket_definitions:
|
|
|
1030
1026
|
});
|
|
1031
1027
|
|
|
1032
1028
|
const bucketStorage = await f.getInstance(syncRules);
|
|
1029
|
+
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1030
|
+
const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
1031
|
+
|
|
1032
|
+
await writer.markAllSnapshotDone('0/1');
|
|
1033
|
+
await writer.save({
|
|
1034
|
+
sourceTable: testTable,
|
|
1035
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
1036
|
+
after: {
|
|
1037
|
+
id: 't1',
|
|
1038
|
+
description: 'Test 1'
|
|
1039
|
+
},
|
|
1040
|
+
afterReplicaId: 't1'
|
|
1041
|
+
});
|
|
1033
1042
|
|
|
1034
|
-
await
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
afterReplicaId: 't1'
|
|
1043
|
-
});
|
|
1044
|
-
|
|
1045
|
-
await batch.save({
|
|
1046
|
-
sourceTable: TEST_TABLE,
|
|
1047
|
-
tag: storage.SaveOperationTag.INSERT,
|
|
1048
|
-
after: {
|
|
1049
|
-
id: 't2',
|
|
1050
|
-
description: 'Test 2'
|
|
1051
|
-
},
|
|
1052
|
-
afterReplicaId: 't2'
|
|
1053
|
-
});
|
|
1054
|
-
|
|
1055
|
-
await batch.commit('0/1');
|
|
1043
|
+
await writer.save({
|
|
1044
|
+
sourceTable: testTable,
|
|
1045
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
1046
|
+
after: {
|
|
1047
|
+
id: 't2',
|
|
1048
|
+
description: 'Test 2'
|
|
1049
|
+
},
|
|
1050
|
+
afterReplicaId: 't2'
|
|
1056
1051
|
});
|
|
1057
1052
|
|
|
1053
|
+
await writer.commit('0/1');
|
|
1054
|
+
|
|
1058
1055
|
const stream = sync.streamResponse({
|
|
1059
1056
|
syncContext,
|
|
1060
1057
|
bucketStorage,
|
|
@@ -1086,30 +1083,29 @@ bucket_definitions:
|
|
|
1086
1083
|
// Now we save additional data AND compact before continuing.
|
|
1087
1084
|
// This invalidates the checkpoint we've received above.
|
|
1088
1085
|
|
|
1089
|
-
await
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
await batch.save({
|
|
1101
|
-
sourceTable: TEST_TABLE,
|
|
1102
|
-
tag: storage.SaveOperationTag.UPDATE,
|
|
1103
|
-
after: {
|
|
1104
|
-
id: 't2',
|
|
1105
|
-
description: 'Test 2b'
|
|
1106
|
-
},
|
|
1107
|
-
afterReplicaId: 't2'
|
|
1108
|
-
});
|
|
1086
|
+
await writer.markAllSnapshotDone('0/1');
|
|
1087
|
+
await writer.save({
|
|
1088
|
+
sourceTable: testTable,
|
|
1089
|
+
tag: storage.SaveOperationTag.UPDATE,
|
|
1090
|
+
after: {
|
|
1091
|
+
id: 't1',
|
|
1092
|
+
description: 'Test 1b'
|
|
1093
|
+
},
|
|
1094
|
+
afterReplicaId: 't1'
|
|
1095
|
+
});
|
|
1109
1096
|
|
|
1110
|
-
|
|
1097
|
+
await writer.save({
|
|
1098
|
+
sourceTable: testTable,
|
|
1099
|
+
tag: storage.SaveOperationTag.UPDATE,
|
|
1100
|
+
after: {
|
|
1101
|
+
id: 't2',
|
|
1102
|
+
description: 'Test 2b'
|
|
1103
|
+
},
|
|
1104
|
+
afterReplicaId: 't2'
|
|
1111
1105
|
});
|
|
1112
1106
|
|
|
1107
|
+
await writer.commit('0/2');
|
|
1108
|
+
|
|
1113
1109
|
await bucketStorage.compact({
|
|
1114
1110
|
minBucketChanges: 1,
|
|
1115
1111
|
minChangeRatio: 0
|
|
@@ -1173,11 +1169,11 @@ bucket_definitions:
|
|
|
1173
1169
|
});
|
|
1174
1170
|
|
|
1175
1171
|
const bucketStorage = f.getInstance(syncRules);
|
|
1172
|
+
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1176
1173
|
|
|
1177
|
-
await
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
});
|
|
1174
|
+
await writer.markAllSnapshotDone('0/1');
|
|
1175
|
+
// <= the managed write checkpoint LSN below
|
|
1176
|
+
await writer.commit('0/1');
|
|
1181
1177
|
|
|
1182
1178
|
const checkpoint = await bucketStorage.createManagedWriteCheckpoint({
|
|
1183
1179
|
user_id: 'test',
|
|
@@ -1209,10 +1205,9 @@ bucket_definitions:
|
|
|
1209
1205
|
})
|
|
1210
1206
|
});
|
|
1211
1207
|
|
|
1212
|
-
await
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
});
|
|
1208
|
+
await writer.markAllSnapshotDone('0/1');
|
|
1209
|
+
// must be >= the managed write checkpoint LSN
|
|
1210
|
+
await writer.commit('1/0');
|
|
1216
1211
|
|
|
1217
1212
|
// At this point the LSN has advanced, so the write checkpoint should be
|
|
1218
1213
|
// included in the next checkpoint message.
|
|
@@ -1226,9 +1221,12 @@ bucket_definitions:
|
|
|
1226
1221
|
});
|
|
1227
1222
|
});
|
|
1228
1223
|
|
|
1229
|
-
test('encodes sync rules id in
|
|
1224
|
+
test('encodes sync rules id in buckets for streams', async () => {
|
|
1230
1225
|
await using f = await factory();
|
|
1231
|
-
|
|
1226
|
+
// This test relies making an actual update to sync rules to test the different bucket names.
|
|
1227
|
+
// The actual naming scheme may change, as long as the two buckets have different names.
|
|
1228
|
+
const rules = [
|
|
1229
|
+
`
|
|
1232
1230
|
streams:
|
|
1233
1231
|
test:
|
|
1234
1232
|
auto_subscribe: true
|
|
@@ -1236,26 +1234,38 @@ streams:
|
|
|
1236
1234
|
|
|
1237
1235
|
config:
|
|
1238
1236
|
edition: 2
|
|
1239
|
-
|
|
1237
|
+
`,
|
|
1238
|
+
`
|
|
1239
|
+
streams:
|
|
1240
|
+
test2:
|
|
1241
|
+
auto_subscribe: true
|
|
1242
|
+
query: SELECT * FROM test WHERE 1;
|
|
1243
|
+
|
|
1244
|
+
config:
|
|
1245
|
+
edition: 2
|
|
1246
|
+
`
|
|
1247
|
+
];
|
|
1240
1248
|
|
|
1241
1249
|
for (let i = 0; i < 2; i++) {
|
|
1242
1250
|
const syncRules = await updateSyncRules(f, {
|
|
1243
|
-
content: rules
|
|
1251
|
+
content: rules[i]
|
|
1244
1252
|
});
|
|
1245
1253
|
const bucketStorage = f.getInstance(syncRules);
|
|
1254
|
+
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1255
|
+
|
|
1256
|
+
const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config, i + 1);
|
|
1246
1257
|
|
|
1247
|
-
await
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
});
|
|
1257
|
-
await batch.commit('0/1');
|
|
1258
|
+
await writer.markAllSnapshotDone('0/1');
|
|
1259
|
+
await writer.save({
|
|
1260
|
+
sourceTable: testTable,
|
|
1261
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
1262
|
+
after: {
|
|
1263
|
+
id: 't1',
|
|
1264
|
+
description: 'Test 1'
|
|
1265
|
+
},
|
|
1266
|
+
afterReplicaId: 't1'
|
|
1258
1267
|
});
|
|
1268
|
+
await writer.commit('0/1');
|
|
1259
1269
|
|
|
1260
1270
|
const stream = sync.streamResponse({
|
|
1261
1271
|
syncContext,
|