-
Notifications
You must be signed in to change notification settings - Fork 60
Experimental: Trigger Based Table Diff Tracking #663
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
🦋 Changeset detectedLatest commit: 1501c24 The changes in this PR will be included in the next version bump. This PR includes changesets to release 8 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
simolus3
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's great to have this functionality! I have some general API notes:
- I see how
trackTableDiffneatly builds ontop ofcreateDiffTrigger, but I'm not sure if the latter needs to be a public API. It sounds to me like it would be easy to misuse by e.g. forgtting to clean up the pending changes after processing them. I can't think of scenarios where the additional flexibility is required, do you have some? - I'm not that familiar with the JS libraries, but I think we should check if it's possible to use Drizzle / Kysely with this API. I don't think we need dedicated APIs in our packages for those, but it could be worth checking whether we can e.g. build the
WHENclause with Kysely APIs. Similarly, can we run the inner query intrackTableDiffwith those query builders or do they need access to some connection context that would be hard to pass down?
…triggers are active. Fix DELETE triggers not filtering columns with JSON fragment. Add throttleMs as option.
That's a fair point. I currently view the
I took a brief look-in to this. I think building the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR introduces SQLite trigger-based table change tracking functionality to PowerSync. It allows developers to monitor and process changes to individual SQLite tables using temporary triggers and tables.
- Adds two new methods:
createDiffTriggerfor basic trigger setup andtrackTableDifffor automated change processing - Implements a comprehensive trigger management system with support for INSERT, UPDATE, and DELETE operations
- Provides filtering capabilities through columns and WHEN conditions with built-in sanitization helpers
Reviewed Changes
Copilot reviewed 10 out of 11 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/common/src/client/triggers/TriggerManager.ts | Defines core interfaces and types for trigger management |
| packages/common/src/client/triggers/TriggerManagerImpl.ts | Implements the trigger management functionality |
| packages/common/src/client/triggers/whenClause.ts | Provides SQL sanitization utilities for WHEN clauses |
| packages/common/src/client/AbstractPowerSyncDatabase.ts | Integrates trigger manager into main database class |
| packages/common/src/index.ts | Exports new trigger functionality |
| packages/node/tests/trigger.test.ts | Comprehensive test suite for trigger functionality |
| packages/node/tests/tsconfig.json | TypeScript configuration for tests |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
Co-authored-by: benitav <[email protected]>
Co-authored-by: benitav <[email protected]>
simolus3
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The implementation and tests look good to me 👍
I have one suggestion to possibly simplify the API, but I don't think it's that important.
simolus3
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Happy with these changes, I think this is a very useful addition 👍
Co-authored-by: benitav <[email protected]>
Overview
We currently expose watched query functionality which allows watching changes of an arbitrary SQLite query's result set. This PR adds methods which can be used to track and process row level changes to individual SQLite tables.
Temporary SQLite triggers and tables are used to populate a set of table change operations. Records for table row
INSERT, UPDATEandDELETE` operations are created, and persisted in a temporary SQLite table, as changes occur.Diff Differences
This API provides a similar result to the diff from
WatchedQuerys created withdifferentialWatch(), but there are a few key differences to consider.WatchedQuerys can track the diff of arbitrary query results, while triggers are limited to row level changes of a single table.WatchedQuerys run off read-connections which have the ability to run concurrently in some platforms.WatchedQuerydiffs expose the diff in JS as a JS objects/arrays.WatchedQuerys query the SQLite DB on any change to the query's dependent tables, the changes are filtered after querying SQLite. Trigger based diffs can filter/skip storing diff records inside the SQLite trigger, which prevents emissions on a lower level.writeLockduring processing (we only allow a single concurrentwriteLock).This PR currently adds 2 new SQLite trigger based methods.
Creating a Diff Trigger
createDiffTriggerConfigures temporary SQLite triggers which populate a temporary SQLite table with operations as they occur.Processing Change Operations
A more convenient
trackTableDiffmethod usescreateDiffTriggerto get table changes, but adds additional logic to consume the changes as they occur.The example below uses triggers to process
todorecords as they are inserted/created.Docs
For more info see the unit tests and API doc comments.