@@ -187,6 +187,8 @@ CREATE TABLE IF NOT EXISTS ps_migration(id INTEGER PRIMARY KEY, down_migrations
187187 current_version = new_version;
188188 }
189189
190+ current_version_stmt. reset ( ) ?;
191+
190192 if current_version < 1 {
191193 // language=SQLite
192194 local_db
@@ -268,6 +270,8 @@ INSERT INTO ps_migration(id, down_migrations)
268270 " ) . into_db_result ( local_db) ?;
269271 }
270272
273+ setup_internal_views ( local_db) ?;
274+
271275 Ok ( String :: from ( "" ) )
272276}
273277
@@ -329,6 +333,74 @@ DELETE FROM {table};",
329333create_auto_tx_function ! ( powersync_clear_tx, powersync_clear_impl) ;
330334create_sqlite_text_fn ! ( powersync_clear, powersync_clear_tx, "powersync_clear" ) ;
331335
336+ fn setup_internal_views ( db : * mut sqlite:: sqlite3 ) -> Result < ( ) , ResultCode > {
337+ // powersync_views - just filters sqlite_master, and combines the view and related triggers
338+ // into one row.
339+
340+ // These views are only usable while the extension is loaded, so use TEMP views.
341+ // TODO: This should not be a public view - implement internally instead
342+ // language=SQLite
343+ db. exec_safe ( "\
344+ CREATE TEMP VIEW IF NOT EXISTS powersync_views(name, sql, delete_trigger_sql, insert_trigger_sql, update_trigger_sql)
345+ AS SELECT
346+ view.name name,
347+ view.sql sql,
348+ ifnull(trigger1.sql, '') delete_trigger_sql,
349+ ifnull(trigger2.sql, '') insert_trigger_sql,
350+ ifnull(trigger3.sql, '') update_trigger_sql
351+ FROM sqlite_master view
352+ LEFT JOIN sqlite_master trigger1
353+ ON trigger1.tbl_name = view.name AND trigger1.type = 'trigger' AND trigger1.name GLOB 'ps_view_delete*'
354+ LEFT JOIN sqlite_master trigger2
355+ ON trigger2.tbl_name = view.name AND trigger2.type = 'trigger' AND trigger2.name GLOB 'ps_view_insert*'
356+ LEFT JOIN sqlite_master trigger3
357+ ON trigger3.tbl_name = view.name AND trigger3.type = 'trigger' AND trigger3.name GLOB 'ps_view_update*'
358+ WHERE view.type = 'view' AND view.sql GLOB '*-- powersync-auto-generated';
359+
360+ CREATE TRIGGER IF NOT EXISTS powersync_views_insert
361+ INSTEAD OF INSERT ON powersync_views
362+ FOR EACH ROW
363+ BEGIN
364+ SELECT powersync_drop_view(NEW.name);
365+ SELECT powersync_exec(NEW.sql);
366+ SELECT powersync_exec(NEW.delete_trigger_sql);
367+ SELECT powersync_exec(NEW.insert_trigger_sql);
368+ SELECT powersync_exec(NEW.update_trigger_sql);
369+ END;
370+
371+ CREATE TRIGGER IF NOT EXISTS powersync_views_update
372+ INSTEAD OF UPDATE ON powersync_views
373+ FOR EACH ROW
374+ BEGIN
375+ SELECT powersync_drop_view(OLD.name);
376+ SELECT powersync_exec(NEW.sql);
377+ SELECT powersync_exec(NEW.delete_trigger_sql);
378+ SELECT powersync_exec(NEW.insert_trigger_sql);
379+ SELECT powersync_exec(NEW.update_trigger_sql);
380+ END;
381+
382+ CREATE TRIGGER IF NOT EXISTS powersync_views_delete
383+ INSTEAD OF DELETE ON powersync_views
384+ FOR EACH ROW
385+ BEGIN
386+ SELECT powersync_drop_view(OLD.name);
387+ END;" ) ?;
388+
389+ // language=SQLite
390+ db. exec_safe (
391+ "\
392+ CREATE TEMP VIEW IF NOT EXISTS powersync_tables(name, internal_name, local_only)
393+ AS SELECT
394+ powersync_external_table_name(name) as name,
395+ name as internal_name,
396+ name GLOB 'ps_data_local__*' as local_only
397+ FROM sqlite_master
398+ WHERE type = 'table' AND name GLOB 'ps_data_*';" ,
399+ ) ?;
400+
401+ Ok ( ( ) )
402+ }
403+
332404pub fn register ( db : * mut sqlite:: sqlite3 ) -> Result < ( ) , ResultCode > {
333405 // This entire module is just making it easier to edit sqlite_master using queries.
334406 // The primary interfaces exposed are:
@@ -421,69 +493,5 @@ pub fn register(db: *mut sqlite::sqlite3) -> Result<(), ResultCode> {
421493 None ,
422494 ) ?;
423495
424- // powersync_views - just filters sqlite_master, and combines the view and related triggers
425- // into one row.
426-
427- // These views are only usable while the extension is loaded, so use TEMP views.
428- // TODO: This should not be a public view - implement internally instead
429- // language=SQLite
430- db. exec_safe ( "\
431- CREATE TEMP VIEW powersync_views(name, sql, delete_trigger_sql, insert_trigger_sql, update_trigger_sql)
432- AS SELECT
433- view.name name,
434- view.sql sql,
435- ifnull(trigger1.sql, '') delete_trigger_sql,
436- ifnull(trigger2.sql, '') insert_trigger_sql,
437- ifnull(trigger3.sql, '') update_trigger_sql
438- FROM sqlite_master view
439- LEFT JOIN sqlite_master trigger1
440- ON trigger1.tbl_name = view.name AND trigger1.type = 'trigger' AND trigger1.name GLOB 'ps_view_delete*'
441- LEFT JOIN sqlite_master trigger2
442- ON trigger2.tbl_name = view.name AND trigger2.type = 'trigger' AND trigger2.name GLOB 'ps_view_insert*'
443- LEFT JOIN sqlite_master trigger3
444- ON trigger3.tbl_name = view.name AND trigger3.type = 'trigger' AND trigger3.name GLOB 'ps_view_update*'
445- WHERE view.type = 'view' AND view.sql GLOB '*-- powersync-auto-generated';
446-
447- CREATE TRIGGER powersync_views_insert
448- INSTEAD OF INSERT ON powersync_views
449- FOR EACH ROW
450- BEGIN
451- SELECT powersync_drop_view(NEW.name);
452- SELECT powersync_exec(NEW.sql);
453- SELECT powersync_exec(NEW.delete_trigger_sql);
454- SELECT powersync_exec(NEW.insert_trigger_sql);
455- SELECT powersync_exec(NEW.update_trigger_sql);
456- END;
457-
458- CREATE TRIGGER powersync_views_update
459- INSTEAD OF UPDATE ON powersync_views
460- FOR EACH ROW
461- BEGIN
462- SELECT powersync_drop_view(OLD.name);
463- SELECT powersync_exec(NEW.sql);
464- SELECT powersync_exec(NEW.delete_trigger_sql);
465- SELECT powersync_exec(NEW.insert_trigger_sql);
466- SELECT powersync_exec(NEW.update_trigger_sql);
467- END;
468-
469- CREATE TRIGGER powersync_views_delete
470- INSTEAD OF DELETE ON powersync_views
471- FOR EACH ROW
472- BEGIN
473- SELECT powersync_drop_view(OLD.name);
474- END;" ) ?;
475-
476- // language=SQLite
477- db. exec_safe (
478- "\
479- CREATE TEMP VIEW powersync_tables(name, internal_name, local_only)
480- AS SELECT
481- powersync_external_table_name(name) as name,
482- name as internal_name,
483- name GLOB 'ps_data_local__*' as local_only
484- FROM sqlite_master
485- WHERE type = 'table' AND name GLOB 'ps_data_*';" ,
486- ) ?;
487-
488496 Ok ( ( ) )
489497}
0 commit comments