From 5d64f3660f6d2f465bb784947c2b9efe3cc084d2 Mon Sep 17 00:00:00 2001 From: Ralf Kistner Date: Mon, 17 Feb 2025 14:53:57 +0200 Subject: [PATCH] Add experimental include_old and include_metadata options. --- crates/core/src/util.rs | 4 +++- crates/core/src/views.rs | 27 +++++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/crates/core/src/util.rs b/crates/core/src/util.rs index 47f1d0b..8bbe7b6 100644 --- a/crates/core/src/util.rs +++ b/crates/core/src/util.rs @@ -54,7 +54,9 @@ pub fn extract_table_info( json_extract(?1, '$.name') as name, ifnull(json_extract(?1, '$.view_name'), json_extract(?1, '$.name')) as view_name, json_extract(?1, '$.local_only') as local_only, - json_extract(?1, '$.insert_only') as insert_only", + json_extract(?1, '$.insert_only') as insert_only, + json_extract(?1, '$.include_old') as include_old, + json_extract(?1, '$.include_metadata') as include_metadata", )?; statement.bind_text(1, data, sqlite::Destructor::STATIC)?; diff --git a/crates/core/src/views.rs b/crates/core/src/views.rs index d534ee2..f196be7 100644 --- a/crates/core/src/views.rs +++ b/crates/core/src/views.rs @@ -24,6 +24,7 @@ fn powersync_view_sql_impl( let name = statement.column_text(0)?; let view_name = statement.column_text(1)?; let local_only = statement.column_int(2)? != 0; + let include_metadata = statement.column_int(5)? != 0; let quoted_name = quote_identifier(view_name); let internal_name = quote_internal_name(name, local_only); @@ -48,6 +49,11 @@ fn powersync_view_sql_impl( column_values.push(foo); } + if include_metadata { + column_names_quoted.push(quote_identifier("_metadata")); + column_values.push(String::from("NULL")); + } + let view_statement = format!( "CREATE VIEW {:}({:}) AS SELECT {:} FROM {:} -- powersync-auto-generated", quoted_name, @@ -206,6 +212,9 @@ fn powersync_trigger_update_sql_impl( let view_name = statement.column_text(1)?; let local_only = statement.column_int(2)? != 0; let insert_only = statement.column_int(3)? != 0; + // TODO: allow accepting a column list + let include_old = statement.column_type(4)? == sqlite::ColumnType::Text; + let include_metadata = statement.column_int(5)? != 0; let quoted_name = quote_identifier(view_name); let internal_name = quote_internal_name(name, local_only); @@ -218,6 +227,20 @@ fn powersync_trigger_update_sql_impl( let json_fragment_new = json_object_fragment("NEW", &stmt2)?; stmt2.reset()?; let json_fragment_old = json_object_fragment("OLD", &stmt2)?; + let old_fragment: String; + let metadata_fragment: &str; + + if include_old { + old_fragment = format!(", 'old', {:}", json_fragment_old); + } else { + old_fragment = String::from(""); + } + + if include_metadata { + metadata_fragment = ", 'metadata', NEW._metadata"; + } else { + metadata_fragment = ""; + } return if !local_only && !insert_only { let trigger = format!("\ @@ -232,10 +255,10 @@ BEGIN UPDATE {:} SET data = {:} WHERE id = NEW.id; - INSERT INTO powersync_crud_(data) VALUES(json_object('op', 'PATCH', 'type', {:}, 'id', NEW.id, 'data', json(powersync_diff({:}, {:})))); + INSERT INTO powersync_crud_(data) VALUES(json_object('op', 'PATCH', 'type', {:}, 'id', NEW.id, 'data', json(powersync_diff({:}, {:})){:}{:})); INSERT OR IGNORE INTO ps_updated_rows(row_type, row_id) VALUES({:}, NEW.id); INSERT OR REPLACE INTO ps_buckets(name, last_op, target_op) VALUES('$local', 0, {:}); -END", trigger_name, quoted_name, internal_name, json_fragment_new, type_string, json_fragment_old, json_fragment_new, type_string, MAX_OP_ID); +END", trigger_name, quoted_name, internal_name, json_fragment_new, type_string, json_fragment_old, json_fragment_new, old_fragment, metadata_fragment, type_string, MAX_OP_ID); Ok(trigger) } else if local_only { let trigger = format!(