Skip to content

Commit 1229e52

Browse files
[Fix] Bucket storage bugs (#61)
Co-authored-by: Steven Ontong <steven@journeyapps.com>
1 parent 457d890 commit 1229e52

File tree

3 files changed

+36
-40
lines changed

3 files changed

+36
-40
lines changed

.changeset/bright-nails-marry.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@journeyapps/powersync-sdk-common': patch
3+
---
4+
5+
Fixed minor bugs in BucketStorage adapter.

packages/powersync-sdk-common/src/client/AbstractPowerSyncDatabase.ts

Lines changed: 29 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
126126

127127
/**
128128
* The underlying database.
129-
*
129+
*
130130
* For the most part, behavior is the same whether querying on the underlying database, or on {@link AbstractPowerSyncDatabase}.
131131
*/
132132
protected get database() {
@@ -179,7 +179,7 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
179179

180180
/**
181181
* Replace the schema with a new version. This is for advanced use cases - typically the schema should just be specified once in the constructor.
182-
*
182+
*
183183
* Cannot be used while connected - this should only be called before {@link AbstractPowerSyncDatabase.connect}.
184184
*/
185185
async updateSchema(schema: Schema) {
@@ -247,7 +247,7 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
247247

248248
/**
249249
* Close the sync connection.
250-
*
250+
*
251251
* Use {@link connect} to connect again.
252252
*/
253253
async disconnect() {
@@ -261,7 +261,7 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
261261
* Use this when logging out.
262262
* The database can still be queried after this is called, but the tables
263263
* would be empty.
264-
*
264+
*
265265
* To preserve data in local-only tables, set clearLocal to false.
266266
*/
267267
async disconnectAndClear(options = DEFAULT_DISCONNECT_CLEAR_OPTIONS) {
@@ -363,20 +363,9 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
363363
}
364364

365365
const last = all[all.length - 1];
366-
return new CrudBatch(all, haveMore, async (writeCheckpoint?: string) => {
367-
await this.writeTransaction(async (tx) => {
368-
await tx.execute(`DELETE FROM ${PSInternalTable.CRUD} WHERE id <= ?`, [last.clientId]);
369-
if (writeCheckpoint != null && (await tx.execute(`SELECT 1 FROM ${PSInternalTable.CRUD} LIMIT 1`)) == null) {
370-
await tx.execute(`UPDATE ${PSInternalTable.BUCKETS} SET target_op = ? WHERE name='$local'`, [
371-
writeCheckpoint
372-
]);
373-
} else {
374-
await tx.execute(`UPDATE ${PSInternalTable.BUCKETS} SET target_op = ? WHERE name='$local'`, [
375-
this.bucketStorageAdapter.getMaxOpId()
376-
]);
377-
}
378-
});
379-
});
366+
return new CrudBatch(all, haveMore, async (writeCheckpoint?: string) =>
367+
this.handleCrudCheckpoint(last.clientId, writeCheckpoint)
368+
);
380369
}
381370

382371
/**
@@ -403,7 +392,7 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
403392
}
404393
const txId = first.tx_id;
405394

406-
let all: CrudEntry[] = [];
395+
let all: CrudEntry[];
407396
if (!txId) {
408397
all = [CrudEntry.fromRow(first)];
409398
} else {
@@ -418,28 +407,30 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
418407

419408
return new CrudTransaction(
420409
all,
421-
async (writeCheckpoint?: string) => {
422-
await this.writeTransaction(async (tx) => {
423-
await tx.execute(`DELETE FROM ${PSInternalTable.CRUD} WHERE id <= ?`, [last.clientId]);
424-
if (writeCheckpoint) {
425-
const check = await tx.execute(`SELECT 1 FROM ${PSInternalTable.CRUD} LIMIT 1`);
426-
if (!check.rows?.length) {
427-
await tx.execute(`UPDATE ${PSInternalTable.BUCKETS} SET target_op = ? WHERE name='$local'`, [
428-
writeCheckpoint
429-
]);
430-
}
431-
} else {
432-
await tx.execute(`UPDATE ${PSInternalTable.BUCKETS} SET target_op = ? WHERE name='$local'`, [
433-
this.bucketStorageAdapter.getMaxOpId()
434-
]);
435-
}
436-
});
437-
},
410+
async (writeCheckpoint?: string) => this.handleCrudCheckpoint(last.clientId, writeCheckpoint),
438411
txId
439412
);
440413
});
441414
}
442415

416+
private async handleCrudCheckpoint(lastClientId: number, writeCheckpoint?: string) {
417+
return this.writeTransaction(async (tx) => {
418+
await tx.execute(`DELETE FROM ${PSInternalTable.CRUD} WHERE id <= ?`, [lastClientId]);
419+
if (writeCheckpoint) {
420+
const check = await tx.execute(`SELECT 1 FROM ${PSInternalTable.CRUD} LIMIT 1`);
421+
if (!check.rows?.length) {
422+
await tx.execute(`UPDATE ${PSInternalTable.BUCKETS} SET target_op = ? WHERE name='$local'`, [
423+
writeCheckpoint
424+
]);
425+
}
426+
} else {
427+
await tx.execute(`UPDATE ${PSInternalTable.BUCKETS} SET target_op = ? WHERE name='$local'`, [
428+
this.bucketStorageAdapter.getMaxOpId()
429+
]);
430+
}
431+
});
432+
}
433+
443434
/**
444435
* Execute a statement and optionally return results.
445436
*/
@@ -557,7 +548,7 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
557548
}
558549
for await (const event of this.onChange({
559550
...(options ?? {}),
560-
tables: resolvedTables
551+
tables: _.uniq(resolvedTables)
561552
})) {
562553
yield await this.executeReadOnly(sql, parameters);
563554
}
@@ -579,7 +570,7 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
579570

580571
return new EventIterator<WatchOnChangeEvent>((eventOptions) => {
581572
const flushTableUpdates = _.throttle(
582-
async () => {
573+
() => {
583574
const intersection = _.intersection(watchedTables, throttledTableUpdates);
584575
if (intersection.length) {
585576
eventOptions.push({

packages/powersync-sdk-common/src/client/sync/bucket/SqliteBucketStorage.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ export class SqliteBucketStorage implements BucketStorageAdapter {
6767
]);
6868
this.logger.debug('saveSyncData', JSON.stringify(result));
6969
count += b.data.length;
70-
this.compactCounter += count;
7170
}
71+
this.compactCounter += count;
7272
});
7373
}
7474

@@ -293,7 +293,7 @@ export class SqliteBucketStorage implements BucketStorageAdapter {
293293
* When the objects are successfully sent to the server, call .complete()
294294
*/
295295
async getCrudBatch(limit: number = 100): Promise<CrudBatch | null> {
296-
if (!this.hasCrud()) {
296+
if (!await this.hasCrud()) {
297297
return null;
298298
}
299299

0 commit comments

Comments
 (0)