Support for Writing to Views #1809
Replies: 1 comment 3 replies
-
Hello @stevensJourney, Thanks for opening this discussion! Indeed GRDB generously queries the database schema about primary keys. Views have none, hence those errors. The topic was brought to me a few days ago, by K. Botha. I currently have a branch that provides great support for mutable views through record types: dev/persistable-views. I invite you to check the new features in this branch, and see if they could match the needs of PowerSync. Since I could not write extensive documentation yet, let me give a quick summary: You can now provide a schema source to GRDB database connections. That schema source can instruct GRDB about the primary key of the views of your choice: struct PowerSyncSchemaSource: DatabaseSchemaSource {
func columnsForPrimaryKey(_ db: Database, inView view: DatabaseObjectID) throws -> [String]? {
// If PowerSync owns the database file, then you can assume
// that all views that need a primary key belong to PowerSync:
return ["id"]
// If PowerSync does not own the database file, you should
// allow the host applications to deal with other writable views.
// To do so, return nil for views that PowerSync does not own.
// The host app will be able to chain schema sources if needed.
// In this sample code I suppose that PowerSync uses some
// kind of naming convention:
let baseTable = view.name + "_sync"
if try db.tableExists(baseTable),
try db.columns(in: baseTable).contains(where: { $0.name == "syncTimestamp" })
{
// Very likely a PowerSync view
return ["id"]
} else {
// Not a PowerSync view:
// don't mess with user's schema
return nil
}
}
}
var config = Configuration()
config.schemaSource = PowerSyncSchemaSource()
let dbQueue = try DatabaseQueue(path: "/path/to/db.sqlite", configuration: config) That The record protocols are not modified: they still specify their table (or view) with the Once the schema source is configured, and your
|
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi there 👋
We’re exploring adding GRDB query support to PowerSync, which syncs remote data into a local SQLite database. Synced data is exposed through SQLite views, with
INSTEAD OF
triggers registered internally to allow standardINSERT
,UPDATE
, andDELETE
operations.Querying views already work in GRDB (see this discussion), but write operations currently fail. For example, when declaring a view as a
PersistableRecord
, calling.insert()
results in:This happens because GRDB attempts to resolve a primary key from the underlying "table", which doesn’t exist for a view.
Would it make sense for GRDB to support writable views? One possible direction could be a new protocol such as
PersistableViewRecord
that allows.insert()
,.update()
, and.delete()
without requiring table metadata.Like
PersistableRecord
, the default view name could be derived from the struct name, but still be overridable for flexibility.Here’s a sketch of what this might look like:
This would let developers work with views in the same way as tables, with sensible defaults but flexibility where needed, while relying on SQLite’s INSTEAD OF triggers to handle persistence behind the scenes.
We’d love your thoughts on whether writable views fit into GRDB’s design, or if you’d recommend a different approach.
Beta Was this translation helpful? Give feedback.
All reactions