Skip to content

Commit d7a4637

Browse files
committed
Create views on powersync_init(), not extension init.
1 parent 4aeb732 commit d7a4637

File tree

1 file changed

+72
-64
lines changed

1 file changed

+72
-64
lines changed

crates/core/src/view_admin.rs

+72-64
Original file line numberDiff line numberDiff line change
@@ -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
@@ -248,6 +250,8 @@ INSERT INTO ps_migration(id, down_migrations) VALUES(3, json_array(json_object('
248250
").into_db_result(local_db)?;
249251
}
250252

253+
setup_internal_views(local_db)?;
254+
251255
Ok(String::from(""))
252256
}
253257

@@ -309,6 +313,74 @@ DELETE FROM {table};",
309313
create_auto_tx_function!(powersync_clear_tx, powersync_clear_impl);
310314
create_sqlite_text_fn!(powersync_clear, powersync_clear_tx, "powersync_clear");
311315

316+
fn setup_internal_views(db: *mut sqlite::sqlite3) -> Result<(), ResultCode> {
317+
// powersync_views - just filters sqlite_master, and combines the view and related triggers
318+
// into one row.
319+
320+
// These views are only usable while the extension is loaded, so use TEMP views.
321+
// TODO: This should not be a public view - implement internally instead
322+
// language=SQLite
323+
db.exec_safe("\
324+
CREATE TEMP VIEW IF NOT EXISTS powersync_views(name, sql, delete_trigger_sql, insert_trigger_sql, update_trigger_sql)
325+
AS SELECT
326+
view.name name,
327+
view.sql sql,
328+
ifnull(trigger1.sql, '') delete_trigger_sql,
329+
ifnull(trigger2.sql, '') insert_trigger_sql,
330+
ifnull(trigger3.sql, '') update_trigger_sql
331+
FROM sqlite_master view
332+
LEFT JOIN sqlite_master trigger1
333+
ON trigger1.tbl_name = view.name AND trigger1.type = 'trigger' AND trigger1.name GLOB 'ps_view_delete*'
334+
LEFT JOIN sqlite_master trigger2
335+
ON trigger2.tbl_name = view.name AND trigger2.type = 'trigger' AND trigger2.name GLOB 'ps_view_insert*'
336+
LEFT JOIN sqlite_master trigger3
337+
ON trigger3.tbl_name = view.name AND trigger3.type = 'trigger' AND trigger3.name GLOB 'ps_view_update*'
338+
WHERE view.type = 'view' AND view.sql GLOB '*-- powersync-auto-generated';
339+
340+
CREATE TRIGGER IF NOT EXISTS powersync_views_insert
341+
INSTEAD OF INSERT ON powersync_views
342+
FOR EACH ROW
343+
BEGIN
344+
SELECT powersync_drop_view(NEW.name);
345+
SELECT powersync_exec(NEW.sql);
346+
SELECT powersync_exec(NEW.delete_trigger_sql);
347+
SELECT powersync_exec(NEW.insert_trigger_sql);
348+
SELECT powersync_exec(NEW.update_trigger_sql);
349+
END;
350+
351+
CREATE TRIGGER IF NOT EXISTS powersync_views_update
352+
INSTEAD OF UPDATE ON powersync_views
353+
FOR EACH ROW
354+
BEGIN
355+
SELECT powersync_drop_view(OLD.name);
356+
SELECT powersync_exec(NEW.sql);
357+
SELECT powersync_exec(NEW.delete_trigger_sql);
358+
SELECT powersync_exec(NEW.insert_trigger_sql);
359+
SELECT powersync_exec(NEW.update_trigger_sql);
360+
END;
361+
362+
CREATE TRIGGER IF NOT EXISTS powersync_views_delete
363+
INSTEAD OF DELETE ON powersync_views
364+
FOR EACH ROW
365+
BEGIN
366+
SELECT powersync_drop_view(OLD.name);
367+
END;")?;
368+
369+
// language=SQLite
370+
db.exec_safe(
371+
"\
372+
CREATE TEMP VIEW IF NOT EXISTS powersync_tables(name, internal_name, local_only)
373+
AS SELECT
374+
powersync_external_table_name(name) as name,
375+
name as internal_name,
376+
name GLOB 'ps_data_local__*' as local_only
377+
FROM sqlite_master
378+
WHERE type = 'table' AND name GLOB 'ps_data_*';",
379+
)?;
380+
381+
Ok(())
382+
}
383+
312384
pub fn register(db: *mut sqlite::sqlite3) -> Result<(), ResultCode> {
313385
// This entire module is just making it easier to edit sqlite_master using queries.
314386
// The primary interfaces exposed are:
@@ -401,69 +473,5 @@ pub fn register(db: *mut sqlite::sqlite3) -> Result<(), ResultCode> {
401473
None,
402474
)?;
403475

404-
// powersync_views - just filters sqlite_master, and combines the view and related triggers
405-
// into one row.
406-
407-
// These views are only usable while the extension is loaded, so use TEMP views.
408-
// TODO: This should not be a public view - implement internally instead
409-
// language=SQLite
410-
db.exec_safe("\
411-
CREATE TEMP VIEW powersync_views(name, sql, delete_trigger_sql, insert_trigger_sql, update_trigger_sql)
412-
AS SELECT
413-
view.name name,
414-
view.sql sql,
415-
ifnull(trigger1.sql, '') delete_trigger_sql,
416-
ifnull(trigger2.sql, '') insert_trigger_sql,
417-
ifnull(trigger3.sql, '') update_trigger_sql
418-
FROM sqlite_master view
419-
LEFT JOIN sqlite_master trigger1
420-
ON trigger1.tbl_name = view.name AND trigger1.type = 'trigger' AND trigger1.name GLOB 'ps_view_delete*'
421-
LEFT JOIN sqlite_master trigger2
422-
ON trigger2.tbl_name = view.name AND trigger2.type = 'trigger' AND trigger2.name GLOB 'ps_view_insert*'
423-
LEFT JOIN sqlite_master trigger3
424-
ON trigger3.tbl_name = view.name AND trigger3.type = 'trigger' AND trigger3.name GLOB 'ps_view_update*'
425-
WHERE view.type = 'view' AND view.sql GLOB '*-- powersync-auto-generated';
426-
427-
CREATE TRIGGER powersync_views_insert
428-
INSTEAD OF INSERT ON powersync_views
429-
FOR EACH ROW
430-
BEGIN
431-
SELECT powersync_drop_view(NEW.name);
432-
SELECT powersync_exec(NEW.sql);
433-
SELECT powersync_exec(NEW.delete_trigger_sql);
434-
SELECT powersync_exec(NEW.insert_trigger_sql);
435-
SELECT powersync_exec(NEW.update_trigger_sql);
436-
END;
437-
438-
CREATE TRIGGER powersync_views_update
439-
INSTEAD OF UPDATE ON powersync_views
440-
FOR EACH ROW
441-
BEGIN
442-
SELECT powersync_drop_view(OLD.name);
443-
SELECT powersync_exec(NEW.sql);
444-
SELECT powersync_exec(NEW.delete_trigger_sql);
445-
SELECT powersync_exec(NEW.insert_trigger_sql);
446-
SELECT powersync_exec(NEW.update_trigger_sql);
447-
END;
448-
449-
CREATE TRIGGER powersync_views_delete
450-
INSTEAD OF DELETE ON powersync_views
451-
FOR EACH ROW
452-
BEGIN
453-
SELECT powersync_drop_view(OLD.name);
454-
END;")?;
455-
456-
// language=SQLite
457-
db.exec_safe(
458-
"\
459-
CREATE TEMP VIEW powersync_tables(name, internal_name, local_only)
460-
AS SELECT
461-
powersync_external_table_name(name) as name,
462-
name as internal_name,
463-
name GLOB 'ps_data_local__*' as local_only
464-
FROM sqlite_master
465-
WHERE type = 'table' AND name GLOB 'ps_data_*';",
466-
)?;
467-
468476
Ok(())
469477
}

0 commit comments

Comments
 (0)