@powersync/service-module-mongodb-storage 0.13.2 → 0.14.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 +30 -0
- package/dist/migrations/db/migrations/1770213298299-storage-version.d.ts +3 -0
- package/dist/migrations/db/migrations/1770213298299-storage-version.js +29 -0
- package/dist/migrations/db/migrations/1770213298299-storage-version.js.map +1 -0
- package/dist/storage/MongoBucketStorage.d.ts +7 -15
- package/dist/storage/MongoBucketStorage.js +13 -51
- package/dist/storage/MongoBucketStorage.js.map +1 -1
- package/dist/storage/implementation/MongoChecksums.d.ts +5 -2
- package/dist/storage/implementation/MongoChecksums.js +7 -4
- package/dist/storage/implementation/MongoChecksums.js.map +1 -1
- package/dist/storage/implementation/MongoCompactor.js +42 -17
- package/dist/storage/implementation/MongoCompactor.js.map +1 -1
- package/dist/storage/implementation/MongoPersistedSyncRulesContent.d.ts +2 -12
- package/dist/storage/implementation/MongoPersistedSyncRulesContent.js +24 -24
- package/dist/storage/implementation/MongoPersistedSyncRulesContent.js.map +1 -1
- package/dist/storage/implementation/MongoSyncBucketStorage.d.ts +4 -2
- package/dist/storage/implementation/MongoSyncBucketStorage.js +4 -1
- package/dist/storage/implementation/MongoSyncBucketStorage.js.map +1 -1
- package/dist/storage/implementation/models.d.ts +13 -1
- package/dist/storage/implementation/models.js +9 -1
- package/dist/storage/implementation/models.js.map +1 -1
- package/dist/storage/storage-index.d.ts +0 -1
- package/dist/storage/storage-index.js +0 -1
- package/dist/storage/storage-index.js.map +1 -1
- package/dist/utils/test-utils.d.ts +3 -4
- package/dist/utils/test-utils.js +2 -2
- package/dist/utils/test-utils.js.map +1 -1
- package/package.json +7 -7
- package/src/migrations/db/migrations/1770213298299-storage-version.ts +44 -0
- package/src/storage/MongoBucketStorage.ts +21 -59
- package/src/storage/implementation/MongoChecksums.ts +14 -6
- package/src/storage/implementation/MongoCompactor.ts +49 -19
- package/src/storage/implementation/MongoPersistedSyncRulesContent.ts +26 -32
- package/src/storage/implementation/MongoSyncBucketStorage.ts +16 -5
- package/src/storage/implementation/models.ts +25 -1
- package/src/storage/storage-index.ts +0 -1
- package/src/utils/test-utils.ts +3 -4
- package/test/src/__snapshots__/storage_sync.test.ts.snap +1116 -21
- package/test/src/storage_compacting.test.ts +28 -22
- package/test/src/storage_sync.test.ts +27 -14
- package/test/src/util.ts +3 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/storage/implementation/MongoPersistedSyncRules.d.ts +0 -10
- package/dist/storage/implementation/MongoPersistedSyncRules.js +0 -17
- package/dist/storage/implementation/MongoPersistedSyncRules.js.map +0 -1
- package/src/storage/implementation/MongoPersistedSyncRules.ts +0 -20
- package/test/src/__snapshots__/storage.test.ts.snap +0 -25
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { register, TEST_TABLE, test_utils } from '@powersync/service-core-tests';
|
|
1
|
+
import { bucketRequest, bucketRequests, register, TEST_TABLE, test_utils } from '@powersync/service-core-tests';
|
|
2
2
|
import { describe, expect, test } from 'vitest';
|
|
3
3
|
import { INITIALIZED_MONGO_STORAGE_FACTORY } from './util.js';
|
|
4
|
-
import { storage, SyncRulesBucketStorage } from '@powersync/service-core';
|
|
4
|
+
import { storage, SyncRulesBucketStorage, updateSyncRulesFromYaml } from '@powersync/service-core';
|
|
5
5
|
|
|
6
6
|
describe('Mongo Sync Bucket Storage Compact', () => {
|
|
7
7
|
register.registerCompactTests(INITIALIZED_MONGO_STORAGE_FACTORY);
|
|
@@ -38,22 +38,22 @@ describe('Mongo Sync Bucket Storage Compact', () => {
|
|
|
38
38
|
|
|
39
39
|
const setup = async () => {
|
|
40
40
|
await using factory = await INITIALIZED_MONGO_STORAGE_FACTORY();
|
|
41
|
-
const syncRules = await factory.updateSyncRules(
|
|
42
|
-
|
|
41
|
+
const syncRules = await factory.updateSyncRules(
|
|
42
|
+
updateSyncRulesFromYaml(`
|
|
43
43
|
bucket_definitions:
|
|
44
44
|
by_user:
|
|
45
45
|
parameters: select request.user_id() as user_id
|
|
46
46
|
data: [select * from test where owner_id = bucket.user_id]
|
|
47
|
-
`
|
|
48
|
-
|
|
47
|
+
`)
|
|
48
|
+
);
|
|
49
49
|
const bucketStorage = factory.getInstance(syncRules);
|
|
50
50
|
const { checkpoint } = await populate(bucketStorage);
|
|
51
51
|
|
|
52
|
-
return { bucketStorage, checkpoint, factory };
|
|
52
|
+
return { bucketStorage, checkpoint, factory, syncRules };
|
|
53
53
|
};
|
|
54
54
|
|
|
55
55
|
test('full compact', async () => {
|
|
56
|
-
const { bucketStorage, checkpoint, factory } = await setup();
|
|
56
|
+
const { bucketStorage, checkpoint, factory, syncRules } = await setup();
|
|
57
57
|
|
|
58
58
|
// Simulate bucket_state from old version not being available
|
|
59
59
|
await factory.db.bucket_state.deleteMany({});
|
|
@@ -68,14 +68,17 @@ bucket_definitions:
|
|
|
68
68
|
signal: null as any
|
|
69
69
|
});
|
|
70
70
|
|
|
71
|
-
const checksumAfter = await bucketStorage.getChecksums(
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
const checksumAfter = await bucketStorage.getChecksums(
|
|
72
|
+
checkpoint,
|
|
73
|
+
bucketRequests(syncRules, ['by_user["u1"]', 'by_user["u2"]'])
|
|
74
|
+
);
|
|
75
|
+
expect(checksumAfter.get(bucketRequest(syncRules, 'by_user["u1"]'))).toEqual({
|
|
76
|
+
bucket: bucketRequest(syncRules, 'by_user["u1"]'),
|
|
74
77
|
checksum: -659469718,
|
|
75
78
|
count: 1
|
|
76
79
|
});
|
|
77
|
-
expect(checksumAfter.get('by_user["u2"]')).toEqual({
|
|
78
|
-
bucket: 'by_user["u2"]',
|
|
80
|
+
expect(checksumAfter.get(bucketRequest(syncRules, 'by_user["u2"]'))).toEqual({
|
|
81
|
+
bucket: bucketRequest(syncRules, 'by_user["u2"]'),
|
|
79
82
|
checksum: 430217650,
|
|
80
83
|
count: 1
|
|
81
84
|
});
|
|
@@ -86,14 +89,14 @@ bucket_definitions:
|
|
|
86
89
|
const { factory } = await setup();
|
|
87
90
|
|
|
88
91
|
// Not populate another version (bucket definition name changed)
|
|
89
|
-
const syncRules = await factory.updateSyncRules(
|
|
90
|
-
|
|
92
|
+
const syncRules = await factory.updateSyncRules(
|
|
93
|
+
updateSyncRulesFromYaml(`
|
|
91
94
|
bucket_definitions:
|
|
92
95
|
by_user2:
|
|
93
96
|
parameters: select request.user_id() as user_id
|
|
94
97
|
data: [select * from test where owner_id = bucket.user_id]
|
|
95
|
-
`
|
|
96
|
-
|
|
98
|
+
`)
|
|
99
|
+
);
|
|
97
100
|
const bucketStorage = factory.getInstance(syncRules);
|
|
98
101
|
|
|
99
102
|
await populate(bucketStorage);
|
|
@@ -119,14 +122,17 @@ bucket_definitions:
|
|
|
119
122
|
});
|
|
120
123
|
expect(result2.buckets).toEqual(0);
|
|
121
124
|
|
|
122
|
-
const checksumAfter = await bucketStorage.getChecksums(
|
|
123
|
-
|
|
124
|
-
|
|
125
|
+
const checksumAfter = await bucketStorage.getChecksums(
|
|
126
|
+
checkpoint,
|
|
127
|
+
bucketRequests(syncRules, ['by_user2["u1"]', 'by_user2["u2"]'])
|
|
128
|
+
);
|
|
129
|
+
expect(checksumAfter.get(bucketRequest(syncRules, 'by_user2["u1"]'))).toEqual({
|
|
130
|
+
bucket: bucketRequest(syncRules, 'by_user2["u1"]'),
|
|
125
131
|
checksum: -659469718,
|
|
126
132
|
count: 1
|
|
127
133
|
});
|
|
128
|
-
expect(checksumAfter.get('by_user2["u2"]')).toEqual({
|
|
129
|
-
bucket: 'by_user2["u2"]',
|
|
134
|
+
expect(checksumAfter.get(bucketRequest(syncRules, 'by_user2["u2"]'))).toEqual({
|
|
135
|
+
bucket: bucketRequest(syncRules, 'by_user2["u2"]'),
|
|
130
136
|
checksum: 430217650,
|
|
131
137
|
count: 1
|
|
132
138
|
});
|
|
@@ -1,26 +1,30 @@
|
|
|
1
|
-
import { storage } from '@powersync/service-core';
|
|
2
|
-
import { register, TEST_TABLE, test_utils } from '@powersync/service-core-tests';
|
|
1
|
+
import { storage, updateSyncRulesFromYaml } from '@powersync/service-core';
|
|
2
|
+
import { bucketRequest, register, TEST_TABLE, test_utils } from '@powersync/service-core-tests';
|
|
3
3
|
import { describe, expect, test } from 'vitest';
|
|
4
|
-
import { INITIALIZED_MONGO_STORAGE_FACTORY } from './util.js';
|
|
4
|
+
import { INITIALIZED_MONGO_STORAGE_FACTORY, TEST_STORAGE_VERSIONS } from './util.js';
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
register.registerSyncTests(
|
|
6
|
+
function registerSyncStorageTests(storageFactory: storage.TestStorageFactory, storageVersion: number) {
|
|
7
|
+
register.registerSyncTests(storageFactory, { storageVersion });
|
|
8
8
|
|
|
9
9
|
// The split of returned results can vary depending on storage drivers
|
|
10
10
|
test('large batch (2)', async () => {
|
|
11
11
|
// Test syncing a batch of data that is small in count,
|
|
12
12
|
// but large enough in size to be split over multiple returned chunks.
|
|
13
13
|
// Similar to the above test, but splits over 1MB chunks.
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
await using factory = await storageFactory();
|
|
15
|
+
const syncRules = await factory.updateSyncRules(
|
|
16
|
+
updateSyncRulesFromYaml(
|
|
17
|
+
`
|
|
16
18
|
bucket_definitions:
|
|
17
19
|
global:
|
|
18
20
|
data:
|
|
19
21
|
- SELECT id, description FROM "%"
|
|
20
|
-
|
|
22
|
+
`,
|
|
23
|
+
{ storageVersion }
|
|
24
|
+
)
|
|
21
25
|
);
|
|
22
|
-
|
|
23
|
-
const
|
|
26
|
+
const bucketStorage = factory.getInstance(syncRules);
|
|
27
|
+
const globalBucket = bucketRequest(syncRules, 'global[]');
|
|
24
28
|
|
|
25
29
|
const result = await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
|
|
26
30
|
const sourceTable = TEST_TABLE;
|
|
@@ -74,7 +78,7 @@ describe('sync - mongodb', () => {
|
|
|
74
78
|
const options: storage.BucketDataBatchOptions = {};
|
|
75
79
|
|
|
76
80
|
const batch1 = await test_utils.fromAsync(
|
|
77
|
-
bucketStorage.getBucketDataBatch(checkpoint, new Map([[
|
|
81
|
+
bucketStorage.getBucketDataBatch(checkpoint, new Map([[globalBucket, 0n]]), options)
|
|
78
82
|
);
|
|
79
83
|
expect(test_utils.getBatchData(batch1)).toEqual([
|
|
80
84
|
{ op_id: '1', op: 'PUT', object_id: 'test1', checksum: 2871785649 },
|
|
@@ -89,7 +93,7 @@ describe('sync - mongodb', () => {
|
|
|
89
93
|
const batch2 = await test_utils.fromAsync(
|
|
90
94
|
bucketStorage.getBucketDataBatch(
|
|
91
95
|
checkpoint,
|
|
92
|
-
new Map([[
|
|
96
|
+
new Map([[globalBucket, BigInt(batch1[0].chunkData.next_after)]]),
|
|
93
97
|
options
|
|
94
98
|
)
|
|
95
99
|
);
|
|
@@ -105,7 +109,7 @@ describe('sync - mongodb', () => {
|
|
|
105
109
|
const batch3 = await test_utils.fromAsync(
|
|
106
110
|
bucketStorage.getBucketDataBatch(
|
|
107
111
|
checkpoint,
|
|
108
|
-
new Map([[
|
|
112
|
+
new Map([[globalBucket, BigInt(batch2[0].chunkData.next_after)]]),
|
|
109
113
|
options
|
|
110
114
|
)
|
|
111
115
|
);
|
|
@@ -120,9 +124,18 @@ describe('sync - mongodb', () => {
|
|
|
120
124
|
|
|
121
125
|
// Test that the checksum type is correct.
|
|
122
126
|
// Specifically, test that it never persisted as double.
|
|
123
|
-
const
|
|
127
|
+
const mongoFactory = factory as any;
|
|
128
|
+
const checksumTypes = await mongoFactory.db.bucket_data
|
|
124
129
|
.aggregate([{ $group: { _id: { $type: '$checksum' }, count: { $sum: 1 } } }])
|
|
125
130
|
.toArray();
|
|
126
131
|
expect(checksumTypes).toEqual([{ _id: 'long', count: 4 }]);
|
|
127
132
|
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
describe('sync - mongodb', () => {
|
|
136
|
+
for (const storageVersion of TEST_STORAGE_VERSIONS) {
|
|
137
|
+
describe(`storage v${storageVersion}`, () => {
|
|
138
|
+
registerSyncStorageTests(INITIALIZED_MONGO_STORAGE_FACTORY, storageVersion);
|
|
139
|
+
});
|
|
140
|
+
}
|
|
128
141
|
});
|
package/test/src/util.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { env } from './env.js';
|
|
2
2
|
import { mongoTestReportStorageFactoryGenerator, mongoTestStorageFactoryGenerator } from '@module/utils/test-utils.js';
|
|
3
|
+
import { CURRENT_STORAGE_VERSION, LEGACY_STORAGE_VERSION } from '@powersync/service-core';
|
|
3
4
|
|
|
4
5
|
export const INITIALIZED_MONGO_STORAGE_FACTORY = mongoTestStorageFactoryGenerator({
|
|
5
6
|
url: env.MONGO_TEST_URL,
|
|
@@ -10,3 +11,5 @@ export const INITIALIZED_MONGO_REPORT_STORAGE_FACTORY = mongoTestReportStorageFa
|
|
|
10
11
|
url: env.MONGO_TEST_URL,
|
|
11
12
|
isCI: env.CI
|
|
12
13
|
});
|
|
14
|
+
|
|
15
|
+
export const TEST_STORAGE_VERSIONS = [LEGACY_STORAGE_VERSION, CURRENT_STORAGE_VERSION];
|