Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 27 additions & 4 deletions crates/core/src/view_admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,14 +150,21 @@ fn powersync_clear_impl(
) -> Result<String, PowerSyncError> {
let local_db = ctx.db_handle();

let clear_local = args[0].int();
let flags = PowerSyncClearFlags(args[0].int());

if !flags.soft_clear() {
// With a soft clear, we want to delete public data while keeping internal data around. When
// connect() is called with compatible JWTs yielding a large overlap of buckets, this can
// speed up the next sync.
local_db.exec_safe("DELETE FROM ps_oplog; DELETE FROM ps_buckets")?;
} else {
local_db.exec_safe("UPDATE ps_buckets SET last_applied_op = 0")?;
}

// language=SQLite
local_db.exec_safe(
"\
DELETE FROM ps_oplog;
DELETE FROM ps_crud;
DELETE FROM ps_buckets;
DELETE FROM ps_untyped;
DELETE FROM ps_updated_rows;
DELETE FROM ps_kv WHERE key != 'client_id';
Expand All @@ -166,7 +173,7 @@ DELETE FROM ps_stream_subscriptions;
",
)?;

let table_glob = if clear_local != 0 {
let table_glob = if flags.clear_local() {
"ps_data_*"
} else {
"ps_data__*"
Expand Down Expand Up @@ -199,6 +206,22 @@ DELETE FROM {table};",
Ok(String::from(""))
}

#[derive(Clone, Copy)]
struct PowerSyncClearFlags(i32);

impl PowerSyncClearFlags {
const MASK_CLEAR_LOCAL: i32 = 0x01;
const MASK_SOFT_CLEAR: i32 = 0x02;

fn clear_local(self) -> bool {
self.0 & Self::MASK_CLEAR_LOCAL != 0
}

fn soft_clear(self) -> bool {
self.0 & Self::MASK_SOFT_CLEAR != 0
}
}

create_auto_tx_function!(powersync_clear_tx, powersync_clear_impl);
create_sqlite_text_fn!(powersync_clear, powersync_clear_tx, "powersync_clear");

Expand Down
32 changes: 32 additions & 0 deletions dart/test/sync_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,38 @@ void _syncTests<T>({
expect(db.select('SELECT * FROM ps_sync_state'), hasLength(0));
});

test('can soft clear', () {
invokeControl('start', null);
pushCheckpoint(buckets: [bucketDescription('a', count: 1)]);
pushSyncData('a', '1', 'row-0', 'PUT', {'col': 'hi'});
pushCheckpointComplete();

expect(db.select('SELECT * FROM items'), hasLength(1));

// Soft clear
db.execute('SELECT powersync_clear(2)');
db.select('select powersync_replace_schema(?)', [json.encode(testSchema)]);
expect(db.select('SELECT * FROM items'), hasLength(0));

final request = invokeControl('start', null);
expect(
request,
contains(containsPair(
'EstablishSyncStream',
{
// Should request state from before clear
'request': containsPair('buckets', [
{'name': 'a', 'after': '1'}
]),
},
)),
);

pushCheckpoint(buckets: [bucketDescription('a', count: 1)]);
pushCheckpointComplete();
expect(db.select('SELECT * FROM items'), hasLength(1));
});

test('persists download progress', () {
const bucket = 'bkt';
void expectProgress(int atLast, int sinceLast) {
Expand Down
Loading