2 releases
0.1.1 | Nov 25, 2024 |
---|---|
0.1.0 | Nov 17, 2024 |
#374 in Database interfaces
276 downloads per month
100KB
2K
SLoC
Real-Time SQLx
Rust backend for the real-time query engine.
Run tests against Sqlite:
cargo test
Behind the API
Query Syntax Tree
Queries are represented by a syntax tree that encodes a subset of SQL. They have two functions:
- Being converted into SQL queries for fetching data once (or initially when creating a subscription).
- Checking if an
OperationNotification
that just occured affects the current query subscription.
Channels
Tauri channels enable the backend to send data to the frontend. In real-time-sqlx
, channels are used to send OperationNotifications
so that the frontend updates its store accordingly.
When a subscription is created, the frontend sends 3 elements to the backend:
- A
QueryTree
- A channel instance
- A subscription
uuid
key (for targeted removal triggered by the frontend)
The (QueryTree, Channel)
tuples are stored on a per-table basis, meaning that OperationNotifications
are only checked against the current active subscriptions of their respective table. This is easy to implement and generalize to as many tables as required, but not recommended for high usage cases (in multi-user cases, you should separate subscription families further in order to avoid checking all table operations against all active subscriptions of the same table).
Granular Operations
Similarly to queries, database operations like INSERT
, DELETE
and UPDATE
are represented by the GranularOperation
enum. When executed, they are converted into an Option<OperationNotification>
, which is None
if the operation failed (represented by null
in the frontend).
Every time a GranularOperation
succeeds, its resulting OperationNotification
is used to see which subscriptions of the related table are affected by it. If an OperationNotification
matches a query, it is send to the frontend via its corresponding channel.
Exception: if an OperationNotification::Update
does not match a query, an OperationNotification::Delete
is sent to the channel. This causes the channel to remove the element of corresponding ID from its cache, in case a previously matching element was altered in a way that makes it not match the query anymore.
Real Time Dispatcher
The heart of the engine is the RealTimeDispatcher
struct. It holds, for each declared (table name, table struct)
pair, an instance of HashMap<key, (QueryTree, Channel)>
locked in a thread-safe and async-safe way behind a RwLock
.
It is responsible for adding and removing supscriptions, and it processes GranularOperations
before checking their related queries. One singleton instance is owned and managed by Tauri and passed as an argument to the Tauri commands.
Dependencies
~9–55MB
~831K SLoC