@@ -188,6 +188,8 @@ CREATE TABLE IF NOT EXISTS ps_migration(id INTEGER PRIMARY KEY, down_migrations
188188 }
189189 current_version_stmt. reset ( ) ?;
190190
191+ current_version_stmt. reset ( ) ?;
192+
191193 if current_version < 1 {
192194 // language=SQLite
193195 local_db
@@ -319,6 +321,8 @@ INSERT INTO ps_migration(id, down_migrations)
319321 . into_db_result ( local_db) ?;
320322 }
321323
324+ setup_internal_views ( local_db) ?;
325+
322326 Ok ( String :: from ( "" ) )
323327}
324328
@@ -380,6 +384,74 @@ DELETE FROM {table};",
380384create_auto_tx_function ! ( powersync_clear_tx, powersync_clear_impl) ;
381385create_sqlite_text_fn ! ( powersync_clear, powersync_clear_tx, "powersync_clear" ) ;
382386
387+ fn setup_internal_views ( db : * mut sqlite:: sqlite3 ) -> Result < ( ) , ResultCode > {
388+ // powersync_views - just filters sqlite_master, and combines the view and related triggers
389+ // into one row.
390+
391+ // These views are only usable while the extension is loaded, so use TEMP views.
392+ // TODO: This should not be a public view - implement internally instead
393+ // language=SQLite
394+ db. exec_safe ( "\
395+ CREATE TEMP VIEW IF NOT EXISTS powersync_views(name, sql, delete_trigger_sql, insert_trigger_sql, update_trigger_sql)
396+ AS SELECT
397+ view.name name,
398+ view.sql sql,
399+ ifnull(trigger1.sql, '') delete_trigger_sql,
400+ ifnull(trigger2.sql, '') insert_trigger_sql,
401+ ifnull(trigger3.sql, '') update_trigger_sql
402+ FROM sqlite_master view
403+ LEFT JOIN sqlite_master trigger1
404+ ON trigger1.tbl_name = view.name AND trigger1.type = 'trigger' AND trigger1.name GLOB 'ps_view_delete*'
405+ LEFT JOIN sqlite_master trigger2
406+ ON trigger2.tbl_name = view.name AND trigger2.type = 'trigger' AND trigger2.name GLOB 'ps_view_insert*'
407+ LEFT JOIN sqlite_master trigger3
408+ ON trigger3.tbl_name = view.name AND trigger3.type = 'trigger' AND trigger3.name GLOB 'ps_view_update*'
409+ WHERE view.type = 'view' AND view.sql GLOB '*-- powersync-auto-generated';
410+
411+ CREATE TRIGGER IF NOT EXISTS powersync_views_insert
412+ INSTEAD OF INSERT ON powersync_views
413+ FOR EACH ROW
414+ BEGIN
415+ SELECT powersync_drop_view(NEW.name);
416+ SELECT powersync_exec(NEW.sql);
417+ SELECT powersync_exec(NEW.delete_trigger_sql);
418+ SELECT powersync_exec(NEW.insert_trigger_sql);
419+ SELECT powersync_exec(NEW.update_trigger_sql);
420+ END;
421+
422+ CREATE TRIGGER IF NOT EXISTS powersync_views_update
423+ INSTEAD OF UPDATE ON powersync_views
424+ FOR EACH ROW
425+ BEGIN
426+ SELECT powersync_drop_view(OLD.name);
427+ SELECT powersync_exec(NEW.sql);
428+ SELECT powersync_exec(NEW.delete_trigger_sql);
429+ SELECT powersync_exec(NEW.insert_trigger_sql);
430+ SELECT powersync_exec(NEW.update_trigger_sql);
431+ END;
432+
433+ CREATE TRIGGER IF NOT EXISTS powersync_views_delete
434+ INSTEAD OF DELETE ON powersync_views
435+ FOR EACH ROW
436+ BEGIN
437+ SELECT powersync_drop_view(OLD.name);
438+ END;" ) ?;
439+
440+ // language=SQLite
441+ db. exec_safe (
442+ "\
443+ CREATE TEMP VIEW IF NOT EXISTS powersync_tables(name, internal_name, local_only)
444+ AS SELECT
445+ powersync_external_table_name(name) as name,
446+ name as internal_name,
447+ name GLOB 'ps_data_local__*' as local_only
448+ FROM sqlite_master
449+ WHERE type = 'table' AND name GLOB 'ps_data_*';" ,
450+ ) ?;
451+
452+ Ok ( ( ) )
453+ }
454+
383455pub fn register ( db : * mut sqlite:: sqlite3 ) -> Result < ( ) , ResultCode > {
384456 // This entire module is just making it easier to edit sqlite_master using queries.
385457 // The primary interfaces exposed are:
@@ -472,69 +544,5 @@ pub fn register(db: *mut sqlite::sqlite3) -> Result<(), ResultCode> {
472544 None ,
473545 ) ?;
474546
475- // powersync_views - just filters sqlite_master, and combines the view and related triggers
476- // into one row.
477-
478- // These views are only usable while the extension is loaded, so use TEMP views.
479- // TODO: This should not be a public view - implement internally instead
480- // language=SQLite
481- db. exec_safe ( "\
482- CREATE TEMP VIEW powersync_views(name, sql, delete_trigger_sql, insert_trigger_sql, update_trigger_sql)
483- AS SELECT
484- view.name name,
485- view.sql sql,
486- ifnull(trigger1.sql, '') delete_trigger_sql,
487- ifnull(trigger2.sql, '') insert_trigger_sql,
488- ifnull(trigger3.sql, '') update_trigger_sql
489- FROM sqlite_master view
490- LEFT JOIN sqlite_master trigger1
491- ON trigger1.tbl_name = view.name AND trigger1.type = 'trigger' AND trigger1.name GLOB 'ps_view_delete*'
492- LEFT JOIN sqlite_master trigger2
493- ON trigger2.tbl_name = view.name AND trigger2.type = 'trigger' AND trigger2.name GLOB 'ps_view_insert*'
494- LEFT JOIN sqlite_master trigger3
495- ON trigger3.tbl_name = view.name AND trigger3.type = 'trigger' AND trigger3.name GLOB 'ps_view_update*'
496- WHERE view.type = 'view' AND view.sql GLOB '*-- powersync-auto-generated';
497-
498- CREATE TRIGGER powersync_views_insert
499- INSTEAD OF INSERT ON powersync_views
500- FOR EACH ROW
501- BEGIN
502- SELECT powersync_drop_view(NEW.name);
503- SELECT powersync_exec(NEW.sql);
504- SELECT powersync_exec(NEW.delete_trigger_sql);
505- SELECT powersync_exec(NEW.insert_trigger_sql);
506- SELECT powersync_exec(NEW.update_trigger_sql);
507- END;
508-
509- CREATE TRIGGER powersync_views_update
510- INSTEAD OF UPDATE ON powersync_views
511- FOR EACH ROW
512- BEGIN
513- SELECT powersync_drop_view(OLD.name);
514- SELECT powersync_exec(NEW.sql);
515- SELECT powersync_exec(NEW.delete_trigger_sql);
516- SELECT powersync_exec(NEW.insert_trigger_sql);
517- SELECT powersync_exec(NEW.update_trigger_sql);
518- END;
519-
520- CREATE TRIGGER powersync_views_delete
521- INSTEAD OF DELETE ON powersync_views
522- FOR EACH ROW
523- BEGIN
524- SELECT powersync_drop_view(OLD.name);
525- END;" ) ?;
526-
527- // language=SQLite
528- db. exec_safe (
529- "\
530- CREATE TEMP VIEW powersync_tables(name, internal_name, local_only)
531- AS SELECT
532- powersync_external_table_name(name) as name,
533- name as internal_name,
534- name GLOB 'ps_data_local__*' as local_only
535- FROM sqlite_master
536- WHERE type = 'table' AND name GLOB 'ps_data_*';" ,
537- ) ?;
538-
539547 Ok ( ( ) )
540548}
0 commit comments