mirror of https://github.com/AMT-Cheif/drift.git
Merge branch 'views' of github.com:westito/drift into views
This commit is contained in:
commit
9e753e7837
|
@ -167,3 +167,66 @@ Applying a `customConstraint` will override all other constraints that would be
|
|||
particular, that means that we need to also include the `NOT NULL` constraint again.
|
||||
|
||||
You can also add table-wide constraints by overriding the `customConstraints` getter in your table class.
|
||||
|
||||
## References
|
||||
|
||||
[Foreign key references](https://www.sqlite.org/foreignkeys.html) can be expressed
|
||||
in Dart tables with the `references()` method when building a column:
|
||||
|
||||
```dart
|
||||
class Todos extends Table {
|
||||
// ...
|
||||
IntColumn get category => integer().nullable().references(Categories, #id)();
|
||||
}
|
||||
|
||||
@DataClassName("Category")
|
||||
class Categories extends Table {
|
||||
IntColumn get id => integer().autoIncrement()();
|
||||
// and more columns...
|
||||
}
|
||||
```
|
||||
|
||||
The first parameter to `references` points to the table on which a reference should be created.
|
||||
The second parameter is a [symbol](https://dart.dev/guides/language/language-tour#symbols) of the column to use for the reference.
|
||||
|
||||
Optionally, the `onUpdate` and `onDelete` parameters can be used to describe what
|
||||
should happen when the target row gets updated or deleted.
|
||||
|
||||
Be aware that, in sqlite3, foreign key references aren't enabled by default.
|
||||
They need to be enabled with `PRAGMA foreign_keys = ON`.
|
||||
A suitable place to issue that pragma with drift is in a [post-migration callback]({{ '../Advanced Features/migrations.md#post-migration-callbacks' | pageUrl }}).
|
||||
|
||||
## Views
|
||||
|
||||
It is also possible to define [SQL views](https://www.sqlite.org/lang_createview.html)
|
||||
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]({{ 'index.md' | pageUrl }}):
|
||||
|
||||
```dart
|
||||
abstract class CategoryTodoCount extends View {
|
||||
TodosTable get todos;
|
||||
Categories get categories;
|
||||
|
||||
Expression<int> get itemCount => todos.id.count();
|
||||
|
||||
@override
|
||||
Query as() => 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
|
||||
|
||||
Finally, a view needs to be added to a database or accessor by including it in the
|
||||
`views` parameter:
|
||||
|
||||
```dart
|
||||
@DriftDatabase(tables: [Todos, Categories], views: [CategoryTodoCount])
|
||||
class MyDatabase extends _$MyDatabase {
|
||||
```
|
||||
|
|
|
@ -95,7 +95,7 @@ class DriftAccessor {
|
|||
/// The tables accessed by this DAO.
|
||||
final List<Type> tables;
|
||||
|
||||
/// The views to include in the database
|
||||
/// The views to make accessible in this DAO.
|
||||
final List<Type> views;
|
||||
|
||||
/// {@macro drift_compile_queries_param}
|
||||
|
|
|
@ -7,6 +7,8 @@ abstract class HasResultSet {
|
|||
}
|
||||
|
||||
/// Subclasses represent a table in a database generated by drift.
|
||||
///
|
||||
/// For more information on how to write tables, see [the documentation](https://drift.simonbinder.eu/docs/getting-started/advanced_dart_tables/)
|
||||
abstract class Table extends HasResultSet {
|
||||
/// Defines a table to be used with drift.
|
||||
const Table();
|
||||
|
@ -119,19 +121,41 @@ abstract class Table extends HasResultSet {
|
|||
}
|
||||
|
||||
/// Subclasses represent a view in a database generated by drift.
|
||||
///
|
||||
/// For more information on how to define views in Dart, see
|
||||
/// [the documentation](https://drift.simonbinder.eu/docs/getting-started/advanced_dart_tables/#views)
|
||||
abstract class View extends HasResultSet {
|
||||
/// Defines a view to be used with drift.
|
||||
const View();
|
||||
|
||||
/// The select method can be used in [as] to define the select query backing
|
||||
/// this view.
|
||||
///
|
||||
/// The select statement should select all columns defined on this view.
|
||||
@protected
|
||||
View select(List<Expression> columns) => _isGenerated();
|
||||
|
||||
/// This method should be called on [select] to define the main table of this
|
||||
/// view:
|
||||
///
|
||||
/// ```dart
|
||||
/// abstract class CategoryTodoCount extends View {
|
||||
/// TodosTable get todos;
|
||||
/// Categories get categories;
|
||||
///
|
||||
/// Expression<int> get itemCount => todos.id.count();
|
||||
///
|
||||
/// @override
|
||||
/// Query as() => select([categories.description, itemCount])
|
||||
/// .from(categories)
|
||||
/// .join([innerJoin(todos, todos.category.equalsExp(categories.id))]);
|
||||
/// }
|
||||
/// ```
|
||||
@protected
|
||||
SimpleSelectStatement from(Table table) => _isGenerated();
|
||||
|
||||
///
|
||||
/// This method is overridden by Dart-defined views to declare the right
|
||||
/// query to run.
|
||||
@visibleForOverriding
|
||||
Query as();
|
||||
}
|
||||
|
@ -210,13 +234,3 @@ class DriftView {
|
|||
/// Customize view name and data class name
|
||||
const DriftView({this.name, this.dataClassName});
|
||||
}
|
||||
|
||||
///
|
||||
@Target({TargetKind.getter})
|
||||
class Reference {
|
||||
///
|
||||
final Type type;
|
||||
|
||||
///
|
||||
const Reference(this.type);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ part of '../query_builder.dart';
|
|||
///
|
||||
/// [sqlite-docs]: https://www.sqlite.org/lang_createview.html
|
||||
/// [sql-tut]: https://www.sqlitetutorial.net/sqlite-create-view/
|
||||
abstract class ViewInfo<Self extends HasResultSet, Row>
|
||||
abstract class ViewInfo<Self extends View, Row>
|
||||
implements ResultSetImplementation<Self, Row> {
|
||||
@override
|
||||
String get entityName;
|
||||
|
@ -17,6 +17,6 @@ abstract class ViewInfo<Self extends HasResultSet, Row>
|
|||
/// The `CREATE VIEW` sql statement that can be used to create this view.
|
||||
String? get createViewStmt;
|
||||
|
||||
/// Predefined query from View.as()
|
||||
/// Predefined query from `View.as()`
|
||||
Query? get query;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ dependencies:
|
|||
io: ^1.0.3
|
||||
|
||||
# Moor-specific analysis and apis
|
||||
drift: ^1.1.0-dev
|
||||
drift: '>=1.1.0-dev <1.2.0'
|
||||
sqlite3: '>=0.1.6 <2.0.0'
|
||||
sqlparser: ^0.18.0
|
||||
|
||||
|
|
Loading…
Reference in New Issue