Skip to content

Commit a8396b1

Browse files
committed
Add powersync_clear().
1 parent e259a2e commit a8396b1

File tree

1 file changed

+68
-1
lines changed

1 file changed

+68
-1
lines changed

crates/core/src/view_admin.rs

+68-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use sqlite_nostd::{Connection, Context};
1212

1313
use crate::error::{PSResult, SQLiteError};
1414
use crate::util::quote_identifier;
15-
use crate::{create_auto_tx_function, create_sqlite_text_fn};
15+
use crate::{create_auto_tx_function, create_sqlite_optional_text_fn, create_sqlite_text_fn};
1616

1717
fn powersync_drop_view_impl(
1818
ctx: *mut sqlite::context,
@@ -254,6 +254,61 @@ INSERT INTO ps_migration(id, down_migrations) VALUES(3, json_array(json_object('
254254
create_auto_tx_function!(powersync_init_tx, powersync_init_impl);
255255
create_sqlite_text_fn!(powersync_init, powersync_init_tx, "powersync_init");
256256

257+
fn powersync_clear_impl(
258+
ctx: *mut sqlite::context,
259+
args: &[*mut sqlite::value],
260+
) -> Result<String, SQLiteError> {
261+
let local_db = ctx.db_handle();
262+
263+
let clear_local = args[0].int();
264+
265+
// language=SQLite
266+
local_db.exec_safe(
267+
"\
268+
DELETE FROM ps_oplog;
269+
DELETE FROM ps_crud;
270+
DELETE FROM ps_buckets;
271+
DELETE FROM ps_untyped;
272+
DELETE FROM ps_kv WHERE key != 'client_id';
273+
",
274+
)?;
275+
276+
let table_glob = if clear_local != 0 {
277+
"ps_data_*"
278+
} else {
279+
"ps_data__*"
280+
};
281+
282+
let tables_stmt = local_db
283+
.prepare_v2("SELECT name FROM sqlite_master WHERE type='table' AND name GLOB ?1")?;
284+
tables_stmt.bind_text(1, table_glob, sqlite::Destructor::STATIC);
285+
286+
let mut tables: Vec<String> = alloc::vec![];
287+
288+
while tables_stmt.step()? == ResultCode::ROW {
289+
let name = tables_stmt.column_text(0)?;
290+
tables.push(name.to_string());
291+
}
292+
293+
for name in tables {
294+
let quoted = quote_identifier(&name);
295+
// The first delete statement deletes a single row, to trigger an update notification for the table.
296+
// The second delete statement uses the truncate optimization to delete the remainder of the data.
297+
let delete_sql = format!(
298+
"\
299+
DELETE FROM {table} WHERE rowid IN (SELECT rowid FROM {table} LIMIT 1);
300+
DELETE FROM {table};",
301+
table = quoted
302+
);
303+
local_db.exec_safe(&delete_sql)?;
304+
}
305+
306+
Ok(String::from(""))
307+
}
308+
309+
create_auto_tx_function!(powersync_clear_tx, powersync_clear_impl);
310+
create_sqlite_text_fn!(powersync_clear, powersync_clear_tx, "powersync_clear");
311+
257312
pub fn register(db: *mut sqlite::sqlite3) -> Result<(), ResultCode> {
258313
// This entire module is just making it easier to edit sqlite_master using queries.
259314
// The primary interfaces exposed are:
@@ -312,6 +367,18 @@ pub fn register(db: *mut sqlite::sqlite3) -> Result<(), ResultCode> {
312367
None,
313368
)?;
314369

370+
// Initialize the extension internal tables.
371+
db.create_function_v2(
372+
"powersync_clear",
373+
1,
374+
sqlite::UTF8,
375+
None,
376+
Some(powersync_clear),
377+
None,
378+
None,
379+
None,
380+
)?;
381+
315382
db.create_function_v2(
316383
"powersync_external_table_name",
317384
1,

0 commit comments

Comments
 (0)