Skip to content

Conversation

@simolus3
Copy link
Contributor

@simolus3 simolus3 commented Feb 11, 2026

This adds the powersync_create_raw_table_crud_trigger function, taking three arguments:

  1. A JSON string description of the raw table.
  2. The name of the trigger to create.
  3. The type of write (INSERT, UPDATE or DELETE for which to generate a trigger). Typically users would create all three, but maybe they want the default trigger for some types only and customize the rest 🤷.

The function generates and executes a CREATE TRIGGER statement mirroring our suggestions from the documentation. To do this,

  • The definitions of raw tables is extended to contain the same options (include_old and boolean flags like insert_only) we already have for regular tables. Also, the optional local_name field has been added to describe the name of the table in the local schema (since name in raw tables describes the sync optype to match).
  • To infer column names used to generate JSON fragments, we query pragma_table_info at the time the trigger is created.

Triggers are not created automatically, and users have full control over their name. So this is a tool that users would invoke in their schema migrations if they can use the default patterns for triggers (which we assume to be the case in most scenarios).

The created trigger follows the scheme of the one we create for JSON-based views. Insert-only tables are implemented by raising on updates and deletes.
I've introduced the SchemaTable enum to wrap either a JSON-based table or a raw tables + inferred column names. This allows some methods generating JSON fragments to be reused between the two. I've also removed type arguments on SqlBuffer::insert_into_powersync_crud in favor of &dyn references to avoid monomorphization on that fairly large function.

@simolus3 simolus3 requested a review from rkistner February 11, 2026 11:32
Copy link
Contributor

@rkistner rkistner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add tests for the generated trigger SQL? Not sure if Dart has something like snapshot tests for this - it's fine if it changes over time, but it would be good to see the specific record of that.

Then I'm also wondering - is there a nice way to handle "local-only" columns like documented here? https://docs.powersync.com/client-sdks/advanced/raw-tables#exclude-local-only-columns-from-triggers (recently added). Otherwise we just need to be explicit that those are considered "advanced" use cases that needs manually-defined triggers.

@simolus3
Copy link
Contributor Author

Could you add tests for the generated trigger SQL?

There aren't vitest-like automated snapshots that I'm aware of, but I've added a few hardcoded examples as matches.

Otherwise we just need to be explicit that those are considered "advanced" use cases that needs manually-defined triggers

That was what I had in mind originally, but it seems like a fairly simple pattern to handle internally. I've added the local_only_columns field for this. It generates this trigger.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants