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));
}
// #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`
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]
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.
The linked Dart documentation also expains the concepts in more detail.