@powersync/service-module-mongodb-storage 0.13.2 → 0.15.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 +51 -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 +28 -53
- package/dist/storage/MongoBucketStorage.js.map +1 -1
- package/dist/storage/implementation/MongoBucketBatch.d.ts +12 -11
- package/dist/storage/implementation/MongoBucketBatch.js +199 -127
- package/dist/storage/implementation/MongoBucketBatch.js.map +1 -1
- package/dist/storage/implementation/MongoChecksums.d.ts +8 -5
- package/dist/storage/implementation/MongoChecksums.js +8 -4
- package/dist/storage/implementation/MongoChecksums.js.map +1 -1
- package/dist/storage/implementation/MongoCompactor.d.ts +2 -2
- package/dist/storage/implementation/MongoCompactor.js +52 -26
- package/dist/storage/implementation/MongoCompactor.js.map +1 -1
- package/dist/storage/implementation/MongoParameterCompactor.d.ts +2 -2
- package/dist/storage/implementation/MongoParameterCompactor.js.map +1 -1
- package/dist/storage/implementation/MongoPersistedSyncRulesContent.d.ts +2 -12
- package/dist/storage/implementation/MongoPersistedSyncRulesContent.js +20 -25
- package/dist/storage/implementation/MongoPersistedSyncRulesContent.js.map +1 -1
- package/dist/storage/implementation/MongoSyncBucketStorage.d.ts +7 -4
- package/dist/storage/implementation/MongoSyncBucketStorage.js +11 -8
- package/dist/storage/implementation/MongoSyncBucketStorage.js.map +1 -1
- package/dist/storage/implementation/MongoSyncRulesLock.d.ts +3 -3
- package/dist/storage/implementation/MongoSyncRulesLock.js.map +1 -1
- package/dist/storage/implementation/MongoWriteCheckpointAPI.d.ts +4 -4
- package/dist/storage/implementation/MongoWriteCheckpointAPI.js.map +1 -1
- package/dist/storage/implementation/OperationBatch.js +3 -2
- package/dist/storage/implementation/OperationBatch.js.map +1 -1
- package/dist/storage/implementation/PersistedBatch.d.ts +11 -4
- package/dist/storage/implementation/PersistedBatch.js +42 -11
- package/dist/storage/implementation/PersistedBatch.js.map +1 -1
- package/dist/storage/implementation/db.d.ts +35 -1
- package/dist/storage/implementation/db.js +99 -0
- package/dist/storage/implementation/db.js.map +1 -1
- package/dist/storage/implementation/models.d.ts +25 -1
- package/dist/storage/implementation/models.js +10 -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 +7 -5
- package/dist/utils/test-utils.js +17 -14
- package/dist/utils/test-utils.js.map +1 -1
- package/dist/utils/util.d.ts +2 -1
- package/dist/utils/util.js +15 -1
- package/dist/utils/util.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 +44 -61
- package/src/storage/implementation/MongoBucketBatch.ts +253 -177
- package/src/storage/implementation/MongoChecksums.ts +19 -9
- package/src/storage/implementation/MongoCompactor.ts +62 -31
- package/src/storage/implementation/MongoParameterCompactor.ts +3 -3
- package/src/storage/implementation/MongoPersistedSyncRulesContent.ts +20 -34
- package/src/storage/implementation/MongoSyncBucketStorage.ts +32 -17
- package/src/storage/implementation/MongoSyncRulesLock.ts +3 -3
- package/src/storage/implementation/MongoWriteCheckpointAPI.ts +4 -4
- package/src/storage/implementation/OperationBatch.ts +3 -2
- package/src/storage/implementation/PersistedBatch.ts +42 -11
- package/src/storage/implementation/db.ts +129 -1
- package/src/storage/implementation/models.ts +39 -1
- package/src/storage/storage-index.ts +0 -1
- package/src/utils/test-utils.ts +18 -16
- package/src/utils/util.ts +17 -2
- package/test/src/__snapshots__/storage.test.ts.snap +198 -22
- 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/storage.test.ts +9 -7
- package/test/src/storage_compacting.test.ts +33 -24
- package/test/src/storage_sync.test.ts +31 -15
- package/test/src/util.ts +4 -1
- 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/storage.test.ts
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import { register } from '@powersync/service-core-tests';
|
|
2
2
|
import { describe } from 'vitest';
|
|
3
|
-
import { INITIALIZED_MONGO_STORAGE_FACTORY } from './util.js';
|
|
3
|
+
import { INITIALIZED_MONGO_STORAGE_FACTORY, TEST_STORAGE_VERSIONS } from './util.js';
|
|
4
4
|
import { env } from './env.js';
|
|
5
5
|
import { mongoTestStorageFactoryGenerator } from '@module/utils/test-utils.js';
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
for (let storageVersion of TEST_STORAGE_VERSIONS) {
|
|
8
|
+
describe(`Mongo Sync Bucket Storage - Parameters - v${storageVersion}`, () =>
|
|
9
|
+
register.registerDataStorageParameterTests({ ...INITIALIZED_MONGO_STORAGE_FACTORY, storageVersion }));
|
|
9
10
|
|
|
10
|
-
describe(
|
|
11
|
-
|
|
11
|
+
describe(`Mongo Sync Bucket Storage - Data - v${storageVersion}`, () =>
|
|
12
|
+
register.registerDataStorageDataTests({ ...INITIALIZED_MONGO_STORAGE_FACTORY, storageVersion }));
|
|
12
13
|
|
|
13
|
-
describe(
|
|
14
|
-
|
|
14
|
+
describe(`Mongo Sync Bucket Storage - Checkpoints - v${storageVersion}`, () =>
|
|
15
|
+
register.registerDataStorageCheckpointTests({ ...INITIALIZED_MONGO_STORAGE_FACTORY, storageVersion }));
|
|
16
|
+
}
|
|
15
17
|
|
|
16
18
|
describe('Sync Bucket Validation', register.registerBucketValidationTests);
|
|
17
19
|
|
|
@@ -1,15 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { storage, SyncRulesBucketStorage, updateSyncRulesFromYaml } from '@powersync/service-core';
|
|
2
|
+
import { bucketRequest, register, test_utils } from '@powersync/service-core-tests';
|
|
2
3
|
import { describe, expect, test } from 'vitest';
|
|
3
4
|
import { INITIALIZED_MONGO_STORAGE_FACTORY } from './util.js';
|
|
4
|
-
import { storage, SyncRulesBucketStorage } from '@powersync/service-core';
|
|
5
5
|
|
|
6
6
|
describe('Mongo Sync Bucket Storage Compact', () => {
|
|
7
7
|
register.registerCompactTests(INITIALIZED_MONGO_STORAGE_FACTORY);
|
|
8
|
+
const TEST_TABLE = test_utils.makeTestTable('test', ['id'], INITIALIZED_MONGO_STORAGE_FACTORY);
|
|
8
9
|
|
|
9
10
|
describe('with blank bucket_state', () => {
|
|
10
11
|
// This can happen when migrating from older service versions, that did not populate bucket_state yet.
|
|
11
12
|
const populate = async (bucketStorage: SyncRulesBucketStorage) => {
|
|
12
13
|
await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
|
|
14
|
+
await batch.markAllSnapshotDone('1/1');
|
|
15
|
+
|
|
13
16
|
await batch.save({
|
|
14
17
|
sourceTable: TEST_TABLE,
|
|
15
18
|
tag: storage.SaveOperationTag.INSERT,
|
|
@@ -37,23 +40,23 @@ describe('Mongo Sync Bucket Storage Compact', () => {
|
|
|
37
40
|
};
|
|
38
41
|
|
|
39
42
|
const setup = async () => {
|
|
40
|
-
await using factory = await INITIALIZED_MONGO_STORAGE_FACTORY();
|
|
41
|
-
const syncRules = await factory.updateSyncRules(
|
|
42
|
-
|
|
43
|
+
await using factory = await INITIALIZED_MONGO_STORAGE_FACTORY.factory();
|
|
44
|
+
const syncRules = await factory.updateSyncRules(
|
|
45
|
+
updateSyncRulesFromYaml(`
|
|
43
46
|
bucket_definitions:
|
|
44
47
|
by_user:
|
|
45
48
|
parameters: select request.user_id() as user_id
|
|
46
49
|
data: [select * from test where owner_id = bucket.user_id]
|
|
47
|
-
`
|
|
48
|
-
|
|
50
|
+
`)
|
|
51
|
+
);
|
|
49
52
|
const bucketStorage = factory.getInstance(syncRules);
|
|
50
53
|
const { checkpoint } = await populate(bucketStorage);
|
|
51
54
|
|
|
52
|
-
return { bucketStorage, checkpoint, factory };
|
|
55
|
+
return { bucketStorage, checkpoint, factory, syncRules };
|
|
53
56
|
};
|
|
54
57
|
|
|
55
58
|
test('full compact', async () => {
|
|
56
|
-
const { bucketStorage, checkpoint, factory } = await setup();
|
|
59
|
+
const { bucketStorage, checkpoint, factory, syncRules } = await setup();
|
|
57
60
|
|
|
58
61
|
// Simulate bucket_state from old version not being available
|
|
59
62
|
await factory.db.bucket_state.deleteMany({});
|
|
@@ -68,14 +71,17 @@ bucket_definitions:
|
|
|
68
71
|
signal: null as any
|
|
69
72
|
});
|
|
70
73
|
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
+
const users = ['u1', 'u2'];
|
|
75
|
+
const userRequests = users.map((user) => bucketRequest(syncRules, `by_user["${user}"]`));
|
|
76
|
+
const [u1Request, u2Request] = userRequests;
|
|
77
|
+
const checksumAfter = await bucketStorage.getChecksums(checkpoint, userRequests);
|
|
78
|
+
expect(checksumAfter.get(u1Request.bucket)).toEqual({
|
|
79
|
+
bucket: u1Request.bucket,
|
|
74
80
|
checksum: -659469718,
|
|
75
81
|
count: 1
|
|
76
82
|
});
|
|
77
|
-
expect(checksumAfter.get(
|
|
78
|
-
bucket:
|
|
83
|
+
expect(checksumAfter.get(u2Request.bucket)).toEqual({
|
|
84
|
+
bucket: u2Request.bucket,
|
|
79
85
|
checksum: 430217650,
|
|
80
86
|
count: 1
|
|
81
87
|
});
|
|
@@ -85,15 +91,15 @@ bucket_definitions:
|
|
|
85
91
|
// Populate old sync rules version
|
|
86
92
|
const { factory } = await setup();
|
|
87
93
|
|
|
88
|
-
//
|
|
89
|
-
const syncRules = await factory.updateSyncRules(
|
|
90
|
-
|
|
94
|
+
// Now populate another version (bucket definition name changed)
|
|
95
|
+
const syncRules = await factory.updateSyncRules(
|
|
96
|
+
updateSyncRulesFromYaml(`
|
|
91
97
|
bucket_definitions:
|
|
92
98
|
by_user2:
|
|
93
99
|
parameters: select request.user_id() as user_id
|
|
94
100
|
data: [select * from test where owner_id = bucket.user_id]
|
|
95
|
-
`
|
|
96
|
-
|
|
101
|
+
`)
|
|
102
|
+
);
|
|
97
103
|
const bucketStorage = factory.getInstance(syncRules);
|
|
98
104
|
|
|
99
105
|
await populate(bucketStorage);
|
|
@@ -119,14 +125,17 @@ bucket_definitions:
|
|
|
119
125
|
});
|
|
120
126
|
expect(result2.buckets).toEqual(0);
|
|
121
127
|
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
128
|
+
const users = ['u1', 'u2'];
|
|
129
|
+
const userRequests = users.map((user) => bucketRequest(syncRules, `by_user2["${user}"]`));
|
|
130
|
+
const [u1Request, u2Request] = userRequests;
|
|
131
|
+
const checksumAfter = await bucketStorage.getChecksums(checkpoint, userRequests);
|
|
132
|
+
expect(checksumAfter.get(u1Request.bucket)).toEqual({
|
|
133
|
+
bucket: u1Request.bucket,
|
|
125
134
|
checksum: -659469718,
|
|
126
135
|
count: 1
|
|
127
136
|
});
|
|
128
|
-
expect(checksumAfter.get(
|
|
129
|
-
bucket:
|
|
137
|
+
expect(checksumAfter.get(u2Request.bucket)).toEqual({
|
|
138
|
+
bucket: u2Request.bucket,
|
|
130
139
|
checksum: 430217650,
|
|
131
140
|
count: 1
|
|
132
141
|
});
|
|
@@ -1,26 +1,34 @@
|
|
|
1
|
-
import { storage } from '@powersync/service-core';
|
|
2
|
-
import {
|
|
1
|
+
import { storage, updateSyncRulesFromYaml } from '@powersync/service-core';
|
|
2
|
+
import { bucketRequest, register, 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(storageConfig: storage.TestStorageConfig, storageVersion: number) {
|
|
7
|
+
register.registerSyncTests(storageConfig.factory, {
|
|
8
|
+
storageVersion,
|
|
9
|
+
tableIdStrings: storageConfig.tableIdStrings
|
|
10
|
+
});
|
|
11
|
+
const TEST_TABLE = test_utils.makeTestTable('test', ['id'], storageConfig);
|
|
8
12
|
|
|
9
13
|
// The split of returned results can vary depending on storage drivers
|
|
10
14
|
test('large batch (2)', async () => {
|
|
11
15
|
// Test syncing a batch of data that is small in count,
|
|
12
16
|
// but large enough in size to be split over multiple returned chunks.
|
|
13
17
|
// Similar to the above test, but splits over 1MB chunks.
|
|
14
|
-
|
|
15
|
-
|
|
18
|
+
await using factory = await storageConfig.factory();
|
|
19
|
+
const syncRules = await factory.updateSyncRules(
|
|
20
|
+
updateSyncRulesFromYaml(
|
|
21
|
+
`
|
|
16
22
|
bucket_definitions:
|
|
17
23
|
global:
|
|
18
24
|
data:
|
|
19
25
|
- SELECT id, description FROM "%"
|
|
20
|
-
|
|
26
|
+
`,
|
|
27
|
+
{ storageVersion }
|
|
28
|
+
)
|
|
21
29
|
);
|
|
22
|
-
|
|
23
|
-
const
|
|
30
|
+
const bucketStorage = factory.getInstance(syncRules);
|
|
31
|
+
const globalBucket = bucketRequest(syncRules, 'global[]');
|
|
24
32
|
|
|
25
33
|
const result = await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
|
|
26
34
|
const sourceTable = TEST_TABLE;
|
|
@@ -72,9 +80,8 @@ describe('sync - mongodb', () => {
|
|
|
72
80
|
const checkpoint = result!.flushed_op;
|
|
73
81
|
|
|
74
82
|
const options: storage.BucketDataBatchOptions = {};
|
|
75
|
-
|
|
76
83
|
const batch1 = await test_utils.fromAsync(
|
|
77
|
-
bucketStorage.getBucketDataBatch(checkpoint,
|
|
84
|
+
bucketStorage.getBucketDataBatch(checkpoint, [bucketRequest(syncRules, 'global[]', 0n)], options)
|
|
78
85
|
);
|
|
79
86
|
expect(test_utils.getBatchData(batch1)).toEqual([
|
|
80
87
|
{ op_id: '1', op: 'PUT', object_id: 'test1', checksum: 2871785649 },
|
|
@@ -89,7 +96,7 @@ describe('sync - mongodb', () => {
|
|
|
89
96
|
const batch2 = await test_utils.fromAsync(
|
|
90
97
|
bucketStorage.getBucketDataBatch(
|
|
91
98
|
checkpoint,
|
|
92
|
-
|
|
99
|
+
[bucketRequest(syncRules, 'global[]', batch1[0].chunkData.next_after)],
|
|
93
100
|
options
|
|
94
101
|
)
|
|
95
102
|
);
|
|
@@ -105,7 +112,7 @@ describe('sync - mongodb', () => {
|
|
|
105
112
|
const batch3 = await test_utils.fromAsync(
|
|
106
113
|
bucketStorage.getBucketDataBatch(
|
|
107
114
|
checkpoint,
|
|
108
|
-
|
|
115
|
+
[bucketRequest(syncRules, 'global[]', batch2[0].chunkData.next_after)],
|
|
109
116
|
options
|
|
110
117
|
)
|
|
111
118
|
);
|
|
@@ -120,9 +127,18 @@ describe('sync - mongodb', () => {
|
|
|
120
127
|
|
|
121
128
|
// Test that the checksum type is correct.
|
|
122
129
|
// Specifically, test that it never persisted as double.
|
|
123
|
-
const
|
|
130
|
+
const mongoFactory = factory as any;
|
|
131
|
+
const checksumTypes = await mongoFactory.db.bucket_data
|
|
124
132
|
.aggregate([{ $group: { _id: { $type: '$checksum' }, count: { $sum: 1 } } }])
|
|
125
133
|
.toArray();
|
|
126
134
|
expect(checksumTypes).toEqual([{ _id: 'long', count: 4 }]);
|
|
127
135
|
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
describe('sync - mongodb', () => {
|
|
139
|
+
for (const storageVersion of TEST_STORAGE_VERSIONS) {
|
|
140
|
+
describe(`storage v${storageVersion}`, () => {
|
|
141
|
+
registerSyncStorageTests(INITIALIZED_MONGO_STORAGE_FACTORY, storageVersion);
|
|
142
|
+
});
|
|
143
|
+
}
|
|
128
144
|
});
|
package/test/src/util.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { env } from './env.js';
|
|
2
1
|
import { mongoTestReportStorageFactoryGenerator, mongoTestStorageFactoryGenerator } from '@module/utils/test-utils.js';
|
|
2
|
+
import { SUPPORTED_STORAGE_VERSIONS } from '@powersync/service-core';
|
|
3
|
+
import { env } from './env.js';
|
|
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 = SUPPORTED_STORAGE_VERSIONS;
|