Add example for reflective update

This commit is contained in:
Simon Binder 2024-02-19 22:16:19 +01:00
parent 4fa75cb30b
commit a26cc44aaf
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
2 changed files with 50 additions and 0 deletions

View File

@ -33,4 +33,38 @@ extension FindTodoEntryById on GeneratedDatabase {
return select(todos)..where((row) => row.id.equals(id)); return select(todos)..where((row) => row.id.equals(id));
} }
// #enddocregion findTodoEntryById // #enddocregion findTodoEntryById
// #docregion updateTitle
Future<Row?> updateTitle<T extends TableInfo<Table, Row>, Row>(
T table, int id, String newTitle) async {
final columnsByName = table.columnsByName;
final stmt = update(table)
..where((tbl) {
final idColumn = columnsByName['id'];
if (idColumn == null) {
throw ArgumentError.value(
this, 'this', 'Must be a table with an id column');
}
if (idColumn.type != DriftSqlType.int) {
throw ArgumentError('Column `id` is not an integer');
}
return idColumn.equals(id);
});
final rows = await stmt.writeReturning(RawValuesInsertable({
'title': Variable<String>(newTitle),
}));
return rows.singleOrNull;
}
// #enddocregion updateTitle
// #docregion updateTodo
Future<Todo?> updateTodoTitle(int id, String newTitle) {
return updateTitle(todos, id, newTitle);
}
// #enddocregion updateTodo
} }

View File

@ -49,8 +49,24 @@ To call this extension, `await myDatabase.todos.findById(3).getSingle()` could b
A nice thing about defining the method as an extension is that type inference works really well - calling `findById` on `todos` A nice thing about defining the method as an extension is that type inference works really well - calling `findById` on `todos`
returns a `Todo` instance, the generated data class for this table. returns a `Todo` instance, the generated data class for this table.
## Updates and inserts
The same approach also works to construct update, delete and insert statements (although those require a [TableInfo] instead of a [ResultSetImplementation] The same approach also works to construct update, delete and insert statements (although those require a [TableInfo] instead of a [ResultSetImplementation]
as views are read-only). as views are read-only).
Also, updates and inserts use an `Insertable` object which represents a partial row of updated or
inserted columns, respectively.
With a known table, one would use the generated typed `Companion` objects for that.
But this can also be done with schema introspection thanks to the `RawValuesInsertable`, which
can be used as a generic `Insertable` backed by a map of column names to values.
This example builds on the previous one to update the `title` column of a generic table based on a filter
of the `id` column:
{% include "blocks/snippet" snippets = snippets name = 'updateTitle' %}
This method can then be called like this:
{% include "blocks/snippet" snippets = snippets name = 'updateTodo' %}
Hopefully, this page gives you some pointers to start reflectively inspecting your drift databases. Hopefully, this page gives you some pointers to start reflectively inspecting your drift databases.
The linked Dart documentation also expains the concepts in more detail. The linked Dart documentation also expains the concepts in more detail.