@powersync/service-module-postgres-storage 0.16.3 → 0.17.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 +33 -0
- package/dist/migrations/scripts/1782950400000-checkpoint-requested-at.d.ts +3 -0
- package/dist/migrations/scripts/1782950400000-checkpoint-requested-at.js +42 -0
- package/dist/migrations/scripts/1782950400000-checkpoint-requested-at.js.map +1 -0
- package/dist/storage/PostgresBucketStorageFactory.js +0 -2
- package/dist/storage/PostgresBucketStorageFactory.js.map +1 -1
- package/dist/storage/PostgresCompactor.d.ts +2 -0
- package/dist/storage/PostgresCompactor.js +20 -0
- package/dist/storage/PostgresCompactor.js.map +1 -1
- package/dist/storage/PostgresSyncRulesStorage.d.ts +16 -1
- package/dist/storage/PostgresSyncRulesStorage.js +200 -131
- package/dist/storage/PostgresSyncRulesStorage.js.map +1 -1
- package/dist/storage/batch/PostgresBucketBatch.d.ts +2 -20
- package/dist/storage/batch/PostgresBucketBatch.js +162 -151
- package/dist/storage/batch/PostgresBucketBatch.js.map +1 -1
- package/dist/storage/checkpoints/PostgresWriteCheckpointAPI.d.ts +1 -1
- package/dist/storage/checkpoints/PostgresWriteCheckpointAPI.js +156 -36
- package/dist/storage/checkpoints/PostgresWriteCheckpointAPI.js.map +1 -1
- package/dist/storage/current-data-store.d.ts +8 -2
- package/dist/storage/current-data-store.js +66 -11
- package/dist/storage/current-data-store.js.map +1 -1
- package/dist/types/models/WriteCheckpoint.d.ts +2 -0
- package/dist/types/models/WriteCheckpoint.js +5 -2
- package/dist/types/models/WriteCheckpoint.js.map +1 -1
- package/dist/utils/checkpoints.d.ts +9 -0
- package/dist/utils/checkpoints.js +26 -0
- package/dist/utils/checkpoints.js.map +1 -0
- package/package.json +8 -8
- package/src/migrations/scripts/1782950400000-checkpoint-requested-at.ts +51 -0
- package/src/storage/PostgresBucketStorageFactory.ts +0 -3
- package/src/storage/PostgresCompactor.ts +24 -0
- package/src/storage/PostgresSyncRulesStorage.ts +219 -137
- package/src/storage/batch/PostgresBucketBatch.ts +169 -154
- package/src/storage/checkpoints/PostgresWriteCheckpointAPI.ts +165 -37
- package/src/storage/current-data-store.ts +66 -11
- package/src/types/models/WriteCheckpoint.ts +5 -2
- package/src/utils/checkpoints.ts +31 -0
- package/test/src/__snapshots__/storage_sync.test.ts.snap +0 -582
- package/test/src/checkpoint_notifications.test.ts +522 -0
- package/test/src/storage.test.ts +214 -5
- package/test/src/storage_compacting.test.ts +3 -3
- package/test/src/storage_sync.test.ts +4 -4
- package/test/tsconfig.json +1 -1
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -301,19 +301,74 @@ export class PostgresCurrentDataStore {
|
|
|
301
301
|
`.execute();
|
|
302
302
|
}
|
|
303
303
|
|
|
304
|
-
|
|
304
|
+
/**
|
|
305
|
+
* Delete up to `limit` rows for the group, returning the number of candidate
|
|
306
|
+
* rows found by the scan (see PostgresSyncRulesStorage#deleteGroupBatch for
|
|
307
|
+
* why the scan is counted rather than the delete).
|
|
308
|
+
*/
|
|
309
|
+
async deleteGroupRowsBatch(db: Queryable, options: { groupId: number; limit: number }): Promise<bigint> {
|
|
305
310
|
if (this.softDeleteEnabled) {
|
|
306
|
-
await db.sql`
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
+
const result = await db.sql`
|
|
312
|
+
WITH
|
|
313
|
+
batch AS (
|
|
314
|
+
SELECT
|
|
315
|
+
ctid
|
|
316
|
+
FROM
|
|
317
|
+
v3_current_data
|
|
318
|
+
WHERE
|
|
319
|
+
group_id = ${{ type: 'int4', value: options.groupId }}
|
|
320
|
+
LIMIT
|
|
321
|
+
${{ type: 'int4', value: options.limit }}
|
|
322
|
+
),
|
|
323
|
+
deleted AS (
|
|
324
|
+
DELETE FROM v3_current_data
|
|
325
|
+
WHERE
|
|
326
|
+
ctid IN (
|
|
327
|
+
SELECT
|
|
328
|
+
ctid
|
|
329
|
+
FROM
|
|
330
|
+
batch
|
|
331
|
+
)
|
|
332
|
+
RETURNING
|
|
333
|
+
1
|
|
334
|
+
)
|
|
335
|
+
SELECT
|
|
336
|
+
COUNT(*) AS count
|
|
337
|
+
FROM
|
|
338
|
+
batch
|
|
339
|
+
`.first<{ count: bigint }>();
|
|
340
|
+
return result?.count ?? 0n;
|
|
311
341
|
} else {
|
|
312
|
-
await db.sql`
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
342
|
+
const result = await db.sql`
|
|
343
|
+
WITH
|
|
344
|
+
batch AS (
|
|
345
|
+
SELECT
|
|
346
|
+
ctid
|
|
347
|
+
FROM
|
|
348
|
+
current_data
|
|
349
|
+
WHERE
|
|
350
|
+
group_id = ${{ type: 'int4', value: options.groupId }}
|
|
351
|
+
LIMIT
|
|
352
|
+
${{ type: 'int4', value: options.limit }}
|
|
353
|
+
),
|
|
354
|
+
deleted AS (
|
|
355
|
+
DELETE FROM current_data
|
|
356
|
+
WHERE
|
|
357
|
+
ctid IN (
|
|
358
|
+
SELECT
|
|
359
|
+
ctid
|
|
360
|
+
FROM
|
|
361
|
+
batch
|
|
362
|
+
)
|
|
363
|
+
RETURNING
|
|
364
|
+
1
|
|
365
|
+
)
|
|
366
|
+
SELECT
|
|
367
|
+
COUNT(*) AS count
|
|
368
|
+
FROM
|
|
369
|
+
batch
|
|
370
|
+
`.first<{ count: bigint }>();
|
|
371
|
+
return result?.count ?? 0n;
|
|
317
372
|
}
|
|
318
373
|
}
|
|
319
374
|
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import { framework } from '@powersync/service-core';
|
|
1
2
|
import * as t from 'ts-codec';
|
|
2
3
|
import { bigint, jsonb } from '../codecs.js';
|
|
3
4
|
|
|
4
5
|
export const WriteCheckpoint = t.object({
|
|
5
6
|
user_id: t.string,
|
|
6
7
|
lsns: jsonb(t.record(t.string)),
|
|
7
|
-
write_checkpoint: bigint
|
|
8
|
+
write_checkpoint: bigint,
|
|
9
|
+
checkpoint_requested_at: t.Null.or(framework.codecs.date)
|
|
8
10
|
});
|
|
9
11
|
|
|
10
12
|
export type WriteCheckpoint = t.Encoded<typeof WriteCheckpoint>;
|
|
@@ -13,7 +15,8 @@ export type WriteCheckpointDecoded = t.Decoded<typeof WriteCheckpoint>;
|
|
|
13
15
|
export const CustomWriteCheckpoint = t.object({
|
|
14
16
|
user_id: t.string,
|
|
15
17
|
write_checkpoint: bigint,
|
|
16
|
-
sync_rules_id: bigint
|
|
18
|
+
sync_rules_id: bigint,
|
|
19
|
+
checkpoint_requested_at: t.Null.or(framework.codecs.date)
|
|
17
20
|
});
|
|
18
21
|
|
|
19
22
|
export type CustomWriteCheckpoint = t.Encoded<typeof CustomWriteCheckpoint>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as lib_postgres from '@powersync/lib-service-postgres';
|
|
2
|
+
import { storage } from '@powersync/service-core';
|
|
3
|
+
import { models } from '../types/types.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Gets the latest active checkpoint document.
|
|
7
|
+
* This is mainly exported for mocking in tests.
|
|
8
|
+
*/
|
|
9
|
+
export async function getActiveCheckpointDocument({
|
|
10
|
+
db
|
|
11
|
+
}: {
|
|
12
|
+
db: lib_postgres.DatabaseClient;
|
|
13
|
+
}): Promise<models.ActiveCheckpointDecoded | null> {
|
|
14
|
+
return db.sql`
|
|
15
|
+
SELECT
|
|
16
|
+
id,
|
|
17
|
+
last_checkpoint,
|
|
18
|
+
last_checkpoint_lsn
|
|
19
|
+
FROM
|
|
20
|
+
sync_rules
|
|
21
|
+
WHERE
|
|
22
|
+
state = ${{ value: storage.SyncRuleState.ACTIVE, type: 'varchar' }}
|
|
23
|
+
OR state = ${{ value: storage.SyncRuleState.ERRORED, type: 'varchar' }}
|
|
24
|
+
ORDER BY
|
|
25
|
+
id DESC
|
|
26
|
+
LIMIT
|
|
27
|
+
1
|
|
28
|
+
`
|
|
29
|
+
.decoded(models.ActiveCheckpoint)
|
|
30
|
+
.first();
|
|
31
|
+
}
|