Views
It is also possible to define SQL views
as Dart classes.
To do so, write an abstract class extending View
. This example declares a view reading
the amount of todo-items added to a category in the schema from the example:
abstract class CategoryTodoCount extends View {
// Getters define the tables that this view is reading from.
Todos get todos;
Categories get categories;
// Custom expressions can be given a name by defining them as a getter:.
Expression<int> get itemCount => todos.id.count();
@override
Query as() =>
// Views can select columns defined as expression getters on the class, or
// they can reference columns from other tables.
select([categories.description, itemCount])
.from(categories)
.join([innerJoin(todos, todos.category.equalsExp(categories.id))]);
}
Inside a Dart view, use
- abstract getters to declare tables that you'll read from (e.g.
TodosTable get todos
). Expression
getters to add columns: (e.g.itemCount => todos.id.count()
).- the overridden
as
method to define the select statement backing the view. The columns referenced inselect
may refer to two kinds of columns: - Columns defined on the view itself (like
itemCount
in the example above). - Columns defined on referenced tables (like
categories.description
in the example). For these references, advanced drift features like type converters used in the column's definition from the table are also applied to the view's column.
Both kind of columns will be added to the data class for the view when selected.
Finally, a view needs to be added to a database or accessor by including it in the
views
parameter:
@DriftDatabase(tables: [Todos, Categories], views: [CategoryTodoCount])
class MyDatabase extends _$MyDatabase {
Nullability of columns in a view¶
For a Dart-defined views, expressions defined as an Expression
getter are
always nullable. This behavior matches TypedResult.read
, the method used to
read results from a complex select statement with custom columns.
Columns that reference another table's column are nullable if the referenced
column is nullable, or if the selected table does not come from an inner join
(because the whole table could be null
in that case).
Considering the view from the example above,
- the
itemCount
column is nullable because it is defined as a complexExpression
- the
description
column, referencingcategories.description
, is non-nullable. This is because it referencescategories
, the primary table of the view's select statement.