First attempt to get it running again

This commit is contained in:
Simon Binder 2022-07-18 23:28:12 +02:00
parent 1af6bb78d9
commit cf8d2618fa
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
68 changed files with 753 additions and 876 deletions

View File

@ -11,15 +11,6 @@ class TodoCategory extends DataClass implements Insertable<TodoCategory> {
final int id;
final String name;
TodoCategory({required this.id, required this.name});
factory TodoCategory.fromData(Map<String, dynamic> data, {String? prefix}) {
final effectivePrefix = prefix ?? '';
return TodoCategory(
id: const IntType()
.mapFromDatabaseResponse(data['${effectivePrefix}id'])!,
name: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}name'])!,
);
}
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
@ -136,16 +127,16 @@ class $TodoCategoriesTable extends TodoCategories
$TodoCategoriesTable(this.attachedDatabase, [this._alias]);
final VerificationMeta _idMeta = const VerificationMeta('id');
@override
late final GeneratedColumn<int?> id = GeneratedColumn<int?>(
late final GeneratedColumn<int> id = GeneratedColumn<int>(
'id', aliasedName, false,
type: const IntType(),
type: DriftSqlType.int,
requiredDuringInsert: false,
defaultConstraints: 'PRIMARY KEY AUTOINCREMENT');
final VerificationMeta _nameMeta = const VerificationMeta('name');
@override
late final GeneratedColumn<String?> name = GeneratedColumn<String?>(
late final GeneratedColumn<String> name = GeneratedColumn<String>(
'name', aliasedName, false,
type: const StringType(), requiredDuringInsert: true);
type: DriftSqlType.string, requiredDuringInsert: true);
@override
List<GeneratedColumn> get $columns => [id, name];
@override
@ -173,8 +164,13 @@ class $TodoCategoriesTable extends TodoCategories
Set<GeneratedColumn> get $primaryKey => {id};
@override
TodoCategory map(Map<String, dynamic> data, {String? tablePrefix}) {
return TodoCategory.fromData(data,
prefix: tablePrefix != null ? '$tablePrefix.' : null);
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return TodoCategory(
id: attachedDatabase.options.types
.read(DriftSqlType.int, data['${effectivePrefix}id'])!,
name: attachedDatabase.options.types
.read(DriftSqlType.string, data['${effectivePrefix}name'])!,
);
}
@override
@ -195,28 +191,13 @@ class TodoItem extends DataClass implements Insertable<TodoItem> {
this.content,
required this.categoryId,
this.generatedText});
factory TodoItem.fromData(Map<String, dynamic> data, {String? prefix}) {
final effectivePrefix = prefix ?? '';
return TodoItem(
id: const IntType()
.mapFromDatabaseResponse(data['${effectivePrefix}id'])!,
title: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}title'])!,
content: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}content']),
categoryId: const IntType()
.mapFromDatabaseResponse(data['${effectivePrefix}category_id'])!,
generatedText: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}generated_text']),
);
}
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
map['id'] = Variable<int>(id);
map['title'] = Variable<String>(title);
if (!nullToAbsent || content != null) {
map['content'] = Variable<String?>(content);
map['content'] = Variable<String>(content);
}
map['category_id'] = Variable<int>(categoryId);
return map;
@ -322,7 +303,7 @@ class TodoItemsCompanion extends UpdateCompanion<TodoItem> {
static Insertable<TodoItem> custom({
Expression<int>? id,
Expression<String>? title,
Expression<String?>? content,
Expression<String>? content,
Expression<int>? categoryId,
}) {
return RawValuesInsertable({
@ -356,7 +337,7 @@ class TodoItemsCompanion extends UpdateCompanion<TodoItem> {
map['title'] = Variable<String>(title.value);
}
if (content.present) {
map['content'] = Variable<String?>(content.value);
map['content'] = Variable<String>(content.value);
}
if (categoryId.present) {
map['category_id'] = Variable<int>(categoryId.value);
@ -384,34 +365,34 @@ class $TodoItemsTable extends TodoItems
$TodoItemsTable(this.attachedDatabase, [this._alias]);
final VerificationMeta _idMeta = const VerificationMeta('id');
@override
late final GeneratedColumn<int?> id = GeneratedColumn<int?>(
late final GeneratedColumn<int> id = GeneratedColumn<int>(
'id', aliasedName, false,
type: const IntType(),
type: DriftSqlType.int,
requiredDuringInsert: false,
defaultConstraints: 'PRIMARY KEY AUTOINCREMENT');
final VerificationMeta _titleMeta = const VerificationMeta('title');
@override
late final GeneratedColumn<String?> title = GeneratedColumn<String?>(
late final GeneratedColumn<String> title = GeneratedColumn<String>(
'title', aliasedName, false,
type: const StringType(), requiredDuringInsert: true);
type: DriftSqlType.string, requiredDuringInsert: true);
final VerificationMeta _contentMeta = const VerificationMeta('content');
@override
late final GeneratedColumn<String?> content = GeneratedColumn<String?>(
late final GeneratedColumn<String> content = GeneratedColumn<String>(
'content', aliasedName, true,
type: const StringType(), requiredDuringInsert: false);
type: DriftSqlType.string, requiredDuringInsert: false);
final VerificationMeta _categoryIdMeta = const VerificationMeta('categoryId');
@override
late final GeneratedColumn<int?> categoryId = GeneratedColumn<int?>(
late final GeneratedColumn<int> categoryId = GeneratedColumn<int>(
'category_id', aliasedName, false,
type: const IntType(),
type: DriftSqlType.int,
requiredDuringInsert: true,
defaultConstraints: 'REFERENCES todo_categories (id)');
final VerificationMeta _generatedTextMeta =
const VerificationMeta('generatedText');
@override
late final GeneratedColumn<String?> generatedText = GeneratedColumn<String?>(
late final GeneratedColumn<String> generatedText = GeneratedColumn<String>(
'generated_text', aliasedName, true,
type: const StringType(),
type: DriftSqlType.string,
requiredDuringInsert: false,
generatedAs: GeneratedAs(
title + const Constant(' (') + content + const Constant(')'), false));
@ -461,8 +442,19 @@ class $TodoItemsTable extends TodoItems
Set<GeneratedColumn> get $primaryKey => {id};
@override
TodoItem map(Map<String, dynamic> data, {String? tablePrefix}) {
return TodoItem.fromData(data,
prefix: tablePrefix != null ? '$tablePrefix.' : null);
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return TodoItem(
id: attachedDatabase.options.types
.read(DriftSqlType.int, data['${effectivePrefix}id'])!,
title: attachedDatabase.options.types
.read(DriftSqlType.string, data['${effectivePrefix}title'])!,
content: attachedDatabase.options.types
.read(DriftSqlType.string, data['${effectivePrefix}content']),
categoryId: attachedDatabase.options.types
.read(DriftSqlType.int, data['${effectivePrefix}category_id'])!,
generatedText: attachedDatabase.options.types
.read(DriftSqlType.string, data['${effectivePrefix}generated_text']),
);
}
@override
@ -475,16 +467,6 @@ class TodoCategoryItemCountData extends DataClass {
final String name;
final int itemCount;
TodoCategoryItemCountData({required this.name, required this.itemCount});
factory TodoCategoryItemCountData.fromData(Map<String, dynamic> data,
{String? prefix}) {
final effectivePrefix = prefix ?? '';
return TodoCategoryItemCountData(
name: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}name'])!,
itemCount: const IntType()
.mapFromDatabaseResponse(data['${effectivePrefix}item_count'])!,
);
}
factory TodoCategoryItemCountData.fromJson(Map<String, dynamic> json,
{ValueSerializer? serializer}) {
serializer ??= driftRuntimeOptions.defaultSerializer;
@ -554,16 +536,21 @@ class $TodoCategoryItemCountView
@override
TodoCategoryItemCountData map(Map<String, dynamic> data,
{String? tablePrefix}) {
return TodoCategoryItemCountData.fromData(data,
prefix: tablePrefix != null ? '$tablePrefix.' : null);
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return TodoCategoryItemCountData(
name: attachedDatabase.options.types
.read(DriftSqlType.string, data['${effectivePrefix}name'])!,
itemCount: attachedDatabase.options.types
.read(DriftSqlType.int, data['${effectivePrefix}item_count'])!,
);
}
late final GeneratedColumn<String?> name = GeneratedColumn<String?>(
late final GeneratedColumn<String> name = GeneratedColumn<String>(
'name', aliasedName, false,
type: const StringType());
late final GeneratedColumn<int?> itemCount = GeneratedColumn<int?>(
type: DriftSqlType.string);
late final GeneratedColumn<int> itemCount = GeneratedColumn<int>(
'item_count', aliasedName, false,
type: const IntType(),
type: DriftSqlType.int,
generatedAs: GeneratedAs(todoItems.id.count(), false));
@override
$TodoCategoryItemCountView createAlias(String alias) {
@ -585,16 +572,6 @@ class TodoItemWithCategoryNameViewData extends DataClass {
final int id;
final String title;
TodoItemWithCategoryNameViewData({required this.id, required this.title});
factory TodoItemWithCategoryNameViewData.fromData(Map<String, dynamic> data,
{String? prefix}) {
final effectivePrefix = prefix ?? '';
return TodoItemWithCategoryNameViewData(
id: const IntType()
.mapFromDatabaseResponse(data['${effectivePrefix}id'])!,
title: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}title'])!,
);
}
factory TodoItemWithCategoryNameViewData.fromJson(Map<String, dynamic> json,
{ValueSerializer? serializer}) {
serializer ??= driftRuntimeOptions.defaultSerializer;
@ -664,15 +641,20 @@ class $TodoItemWithCategoryNameViewView extends ViewInfo<
@override
TodoItemWithCategoryNameViewData map(Map<String, dynamic> data,
{String? tablePrefix}) {
return TodoItemWithCategoryNameViewData.fromData(data,
prefix: tablePrefix != null ? '$tablePrefix.' : null);
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return TodoItemWithCategoryNameViewData(
id: attachedDatabase.options.types
.read(DriftSqlType.int, data['${effectivePrefix}id'])!,
title: attachedDatabase.options.types
.read(DriftSqlType.string, data['${effectivePrefix}title'])!,
);
}
late final GeneratedColumn<int?> id =
GeneratedColumn<int?>('id', aliasedName, false, type: const IntType());
late final GeneratedColumn<String?> title = GeneratedColumn<String?>(
late final GeneratedColumn<int> id =
GeneratedColumn<int>('id', aliasedName, false, type: DriftSqlType.int);
late final GeneratedColumn<String> title = GeneratedColumn<String>(
'title', aliasedName, false,
type: const StringType(),
type: DriftSqlType.string,
generatedAs: GeneratedAs(
todoItems.title +
const Constant('(') +
@ -697,7 +679,7 @@ class $TodoItemWithCategoryNameViewView extends ViewInfo<
}
abstract class _$Database extends GeneratedDatabase {
_$Database(QueryExecutor e) : super(SqlTypeSystem.defaultInstance, e);
_$Database(QueryExecutor e) : super(e);
_$Database.connect(DatabaseConnection c) : super.connect(c);
late final $TodoCategoriesTable todoCategories = $TodoCategoriesTable(this);
late final $TodoItemsTable todoItems = $TodoItemsTable(this);

View File

@ -4,10 +4,8 @@ library drift;
// field.
export 'dart:typed_data' show Uint8List;
// needed for generated code which provides an @required parameter hint where
// appropriate
export 'package:meta/meta.dart' show required;
export 'src/dsl/dsl.dart';
export 'src/runtime/api/options.dart';
export 'src/runtime/api/runtime_api.dart';
export 'src/runtime/custom_result_set.dart';
export 'src/runtime/data_class.dart';

View File

@ -11,7 +11,7 @@ import 'package:meta/meta.dart';
import '../drift.dart';
/// Defines extensions on string expressions to support the json1 api from Dart.
extension JsonExtensions on Expression<String?> {
extension JsonExtensions on Expression<String> {
/// Assuming that this string is a json array, returns the length of this json
/// array.
///
@ -47,7 +47,7 @@ extension JsonExtensions on Expression<String?> {
/// in [JoinedSelectStatement.addColumns] or compared via [Expression.equals].
/// The [T] parameter denotes the mapped Dart type for this expression,
/// such as [String].
Expression<T> jsonExtract<T>(String path) {
Expression<T> jsonExtract<T extends Object>(String path) {
return FunctionCallExpression('json_extract', [
this,
Variable.withString(path),

View File

@ -12,7 +12,7 @@ import '../drift.dart';
/// instead of `NaN`.
///
/// This function is only available when using a `NativeDatabase`.
Expression<num?> sqlPow(Expression<num?> base, Expression<num?> exponent) {
Expression<num> sqlPow(Expression<num> base, Expression<num> exponent) {
return FunctionCallExpression('pow', [base, exponent]);
}
@ -22,7 +22,7 @@ Expression<num?> sqlPow(Expression<num?> base, Expression<num?> exponent) {
/// of `NaN` for negative values.
///
/// This function is only available when using a `NativeDatabase`.
Expression<num?> sqlSqrt(Expression<num?> value) {
Expression<num> sqlSqrt(Expression<num> value) {
return FunctionCallExpression('sqrt', [value]);
}
@ -31,7 +31,7 @@ Expression<num?> sqlSqrt(Expression<num?> value) {
/// This function is equivalent to [sin].
///
/// This function is only available when using a `NativeDatabase`.
Expression<num?> sqlSin(Expression<num?> value) {
Expression<num> sqlSin(Expression<num> value) {
return FunctionCallExpression('sin', [value]);
}
@ -40,7 +40,7 @@ Expression<num?> sqlSin(Expression<num?> value) {
/// This function is equivalent to [sin].
///
/// This function is only available when using a `NativeDatabase`.
Expression<num?> sqlCos(Expression<num?> value) {
Expression<num> sqlCos(Expression<num> value) {
return FunctionCallExpression('cos', [value]);
}
@ -49,7 +49,7 @@ Expression<num?> sqlCos(Expression<num?> value) {
/// This function is equivalent to [tan].
///
/// This function is only available when using a `NativeDatabase`.
Expression<num?> sqlTan(Expression<num?> value) {
Expression<num> sqlTan(Expression<num> value) {
return FunctionCallExpression('tan', [value]);
}
@ -59,7 +59,7 @@ Expression<num?> sqlTan(Expression<num?> value) {
/// instead of `NaN`.
///
/// This function is only available when using a `NativeDatabase`.
Expression<num?> sqlAsin(Expression<num?> value) {
Expression<num> sqlAsin(Expression<num> value) {
return FunctionCallExpression('asin', [value]);
}
@ -69,7 +69,7 @@ Expression<num?> sqlAsin(Expression<num?> value) {
/// instead of `NaN`.
///
/// This function is only available when using a `NativeDatabase`.
Expression<num?> sqlAcos(Expression<num?> value) {
Expression<num> sqlAcos(Expression<num> value) {
return FunctionCallExpression('acos', [value]);
}
@ -79,13 +79,13 @@ Expression<num?> sqlAcos(Expression<num?> value) {
/// instead of `NaN`.
///
/// This function is only available when using a `NativeDatabase`.
Expression<num?> sqlAtan(Expression<num?> value) {
Expression<num> sqlAtan(Expression<num> value) {
return FunctionCallExpression('atan', [value]);
}
/// Adds functionality to string expressions that only work when using
/// a `NativeDatabase`.
extension DriftNativeStringExtensions on Expression<String?> {
extension DriftNativeStringExtensions on Expression<String> {
/// Version of `contains` that allows controlling case sensitivity better.
///
/// The default `contains` method uses sqlite's `LIKE`, which is case-
@ -100,7 +100,7 @@ extension DriftNativeStringExtensions on Expression<String?> {
/// Note that, while Dart has better support for an international alphabet,
/// it can still yield unexpected results like the
/// [Turkish İ Problem](https://haacked.com/archive/2012/07/05/turkish-i-problem-and-why-you-should-care.aspx/)
Expression<bool?> containsCase(String substring,
Expression<bool> containsCase(String substring,
{bool caseSensitive = false}) {
return FunctionCallExpression('moor_contains', [
this,

View File

@ -28,7 +28,7 @@ enum KeyAction {
/// Base class for columns in sql. Type [T] refers to the type a value of this
/// column will have in Dart.
abstract class Column<T> extends Expression<T> {
abstract class Column<T extends Object> extends Expression<T> {
@override
final Precedence precedence = Precedence.primary;
@ -43,7 +43,7 @@ abstract class Column<T> extends Expression<T> {
}
/// A column that stores int values.
typedef IntColumn = Column<int?>;
typedef IntColumn = Column<int>;
/// A column that stores BigInt values.
///
@ -53,41 +53,41 @@ typedef IntColumn = Column<int?>;
/// Dart can represent), there is no need to use an [Int64Column] for native
/// apps. For Dart compiled to JavaScript though, it may be beneficial to use
/// [BigInt]s to avoid loosing precision for values larger than 2².
typedef Int64Column = Column<BigInt?>;
typedef Int64Column = Column<BigInt>;
/// A column that stores boolean values. Booleans will be stored as an integer
/// that can either be 0 (false) or 1 (true).
typedef BoolColumn = Column<bool?>;
typedef BoolColumn = Column<bool>;
/// A column that stores text.
typedef TextColumn = Column<String?>;
typedef TextColumn = Column<String>;
/// A column that stores a [DateTime]. Times will be stored as unix timestamp
/// and will thus have a second accuracy.
typedef DateTimeColumn = Column<DateTime?>;
typedef DateTimeColumn = Column<DateTime>;
/// A column that stores arbitrary blobs of data as a [Uint8List].
typedef BlobColumn = Column<Uint8List?>;
typedef BlobColumn = Column<Uint8List>;
/// A column that stores floating point numeric values.
typedef RealColumn = Column<double?>;
typedef RealColumn = Column<double>;
class _BaseColumnBuilder<T> {}
class _BaseColumnBuilder<T extends Object> {}
/// A column builder is used to specify which columns should appear in a table.
/// All of the methods defined in this class and its subclasses are not meant to
/// be called at runtime. Instead, the generator will take a look at your
/// source code (specifically, it will analyze which of the methods you use) to
/// figure out the column structure of a table.
class ColumnBuilder<T> extends _BaseColumnBuilder<T> {}
class ColumnBuilder<T extends Object> extends _BaseColumnBuilder<T> {}
/// A column builder for virtual, generated columns.
///
/// This is a different class so that some methods are not available
class VirtualColumnBuilder<T> extends _BaseColumnBuilder<T> {}
class VirtualColumnBuilder<T extends Object> extends _BaseColumnBuilder<T> {}
/// DSL extension to define a column inside a drift table.
extension BuildColumn<T> on ColumnBuilder<T> {
extension BuildColumn<T extends Object> on ColumnBuilder<T> {
/// Tells drift to write a custom constraint after this column definition when
/// writing this column, for instance in a CREATE TABLE statement.
///
@ -221,7 +221,7 @@ extension BuildColumn<T> on ColumnBuilder<T> {
/// part of a `CREATE TABLE` statement). As a consequence, changes to the
/// [condition] need to be updated in the database schema with an explicit
/// [schema migration](https://drift.simonbinder.eu/docs/advanced-features/migrations/).
ColumnBuilder<T> check(Expression<bool?> condition) => _isGenerated();
ColumnBuilder<T> check(Expression<bool> condition) => _isGenerated();
/// Declare a generated column.
///
@ -258,13 +258,13 @@ extension BuildColumn<T> on ColumnBuilder<T> {
/// Note that generated columns are only available in sqlite3 version
/// `3.31.0`. When using `sqlite3_flutter_libs` or a web database, this is not
/// a problem.
VirtualColumnBuilder<T> generatedAs(Expression<T?> generatedAs,
VirtualColumnBuilder<T> generatedAs(Expression<T> generatedAs,
{bool stored = false}) =>
_isGenerated();
}
/// Column builders available for both virtual and non-virtual columns.
extension BuildGeneralColumn<T> on _BaseColumnBuilder<T> {
extension BuildGeneralColumn<T extends Object> on _BaseColumnBuilder<T> {
/// By default, the field name will be used as the column name, e.g.
/// `IntColumn get id = integer()` will have "id" as its associated name.
/// Columns made up of multiple words are expected to be in camelCase and will
@ -280,13 +280,13 @@ extension BuildGeneralColumn<T> on _BaseColumnBuilder<T> {
/// Marks this column as nullable. Nullable columns should not appear in a
/// primary key. Columns are non-null by default.
ColumnBuilder<T?> nullable() => _isGenerated();
ColumnBuilder<T> nullable() => _isGenerated();
/// Adds UNIQUE constraint to column.
///
/// Unique constraints spanning multiple keys can be added to a table by
/// overriding [Table.uniqueKeys].
ColumnBuilder<T?> unique() => _isGenerated();
ColumnBuilder<T> unique() => _isGenerated();
/// Uses a custom [converter] to store custom Dart objects in a single column
/// and automatically mapping them from and to sql.
@ -335,7 +335,7 @@ extension BuildGeneralColumn<T> on _BaseColumnBuilder<T> {
/// Tells the generator to build an [IntColumn]. See the docs at [ColumnBuilder]
/// for details.
extension BuildIntColumn<T extends int?> on ColumnBuilder<T> {
extension BuildIntColumn<T extends int> on ColumnBuilder<T> {
/// Enables auto-increment for this column, which will also make this column
/// the primary key of the table.
///
@ -346,7 +346,7 @@ extension BuildIntColumn<T extends int?> on ColumnBuilder<T> {
/// Tells the generator to build an [TextColumn]. See the docs at
/// [ColumnBuilder] for details.
extension BuildTextColumn<T extends String?> on ColumnBuilder<T> {
extension BuildTextColumn<T extends String> on ColumnBuilder<T> {
/// Puts a constraint on the minimum and maximum length of text that can be
/// stored in this column.
///

View File

@ -88,7 +88,7 @@ class Batch {
/// For more details on how updates work in drift, check out
/// [UpdateStatement.write] or the [documentation with examples](https://drift.simonbinder.eu/docs/getting-started/writing_queries/#updates-and-deletes)
void update<T extends Table, D>(TableInfo<T, D> table, Insertable<D> row,
{Expression<bool?> Function(T table)? where}) {
{Expression<bool> Function(T table)? where}) {
_addUpdate(table, UpdateKind.update);
final stmt = UpdateStatement(_user, table);
if (where != null) stmt.where(where);
@ -137,7 +137,7 @@ class Batch {
/// See also:
/// - [DatabaseConnectionUser.delete]
void deleteWhere<T extends Table, D>(
TableInfo<T, D> table, Expression<bool?> Function(T tbl) filter) {
TableInfo<T, D> table, Expression<bool> Function(T tbl) filter) {
_addUpdate(table, UpdateKind.delete);
final stmt = DeleteStatement(_user, table)..where(filter);
_addContext(stmt.constructQuery());

View File

@ -711,7 +711,7 @@ extension TableOperations<Tbl extends Table, Row>
/// Deletes all rows matching the [filter] from the table.
///
/// See also [SingleTableQueryMixin.where].
Future<int> deleteWhere(Expression<bool?> Function(Tbl tbl) filter) {
Future<int> deleteWhere(Expression<bool> Function(Tbl tbl) filter) {
return (delete()..where(filter)).go();
}
}

View File

@ -6,8 +6,6 @@ import 'package:drift/src/runtime/executor/stream_queries.dart';
import 'package:drift/src/runtime/executor/transactions.dart';
import 'package:meta/meta.dart';
import 'options.dart';
part 'batch.dart';
part 'connection.dart';
part 'connection_user.dart';

View File

@ -6,7 +6,7 @@ class GroupBy extends Component {
final List<Expression> groupBy;
/// Optional, a having clause to exclude some groups.
final Expression<bool?>? having;
final Expression<bool>? having;
GroupBy._(this.groupBy, this.having);

View File

@ -31,7 +31,7 @@ class Join<T extends HasResultSet, D> extends Component {
/// For joins that aren't [_JoinType.cross], contains an additional predicate
/// that must be matched for the join.
final Expression<bool?>? on;
final Expression<bool>? on;
/// Whether [table] should appear in the result set (defaults to true).
/// Default value can be changed by `includeJoinedTableColumns` in
@ -79,7 +79,7 @@ class Join<T extends HasResultSet, D> extends Component {
/// See also:
/// - https://drift.simonbinder.eu/docs/advanced-features/joins/#joins
/// - http://www.sqlitetutorial.net/sqlite-inner-join/
Join innerJoin(Table other, Expression<bool?> on, {bool? useColumns}) {
Join innerJoin(Table other, Expression<bool> on, {bool? useColumns}) {
return Join._(_JoinType.inner, other, on, includeInResult: useColumns);
}
@ -91,7 +91,7 @@ Join innerJoin(Table other, Expression<bool?> on, {bool? useColumns}) {
/// See also:
/// - https://drift.simonbinder.eu/docs/advanced-features/joins/#joins
/// - http://www.sqlitetutorial.net/sqlite-left-join/
Join leftOuterJoin(Table other, Expression<bool?> on, {bool? useColumns}) {
Join leftOuterJoin(Table other, Expression<bool> on, {bool? useColumns}) {
return Join._(_JoinType.leftOuter, other, on, includeInResult: useColumns);
}

View File

@ -4,7 +4,7 @@ part of '../query_builder.dart';
class Where extends Component {
/// The expression that determines whether a given row should be included in
/// the result.
final Expression<bool?> predicate;
final Expression<bool> predicate;
/// Construct a [Where] clause from its [predicate].
Where(this.predicate);

View File

@ -11,13 +11,13 @@ part of '../query_builder.dart';
///
/// This is equivalent to the `COUNT(*) FILTER (WHERE filter)` sql function. The
/// filter will be omitted if null.
Expression<int> countAll({Expression<bool?>? filter}) {
Expression<int> countAll({Expression<bool>? filter}) {
return _AggregateExpression('COUNT', const [_StarFunctionParameter()],
filter: filter);
}
/// Provides aggregate functions that are available for each expression.
extension BaseAggregate<DT> on Expression<DT> {
extension BaseAggregate<DT extends Object> on Expression<DT> {
/// Returns how often this expression is non-null in the current group.
///
/// For `COUNT(*)`, which would count all rows, see [countAll].
@ -25,7 +25,7 @@ extension BaseAggregate<DT> on Expression<DT> {
/// If [distinct] is set (defaults to false), duplicate values will not be
/// counted twice.
/// {@macro drift_aggregate_filter}
Expression<int> count({bool distinct = false, Expression<bool?>? filter}) {
Expression<int> count({bool distinct = false, Expression<bool>? filter}) {
return _AggregateExpression('COUNT', [this],
filter: filter, distinct: distinct);
}
@ -44,10 +44,10 @@ extension BaseAggregate<DT> on Expression<DT> {
/// See also:
/// - the sqlite documentation: https://www.sqlite.org/lang_aggfunc.html#groupconcat
/// - the conceptually similar [Iterable.join]
Expression<String?> groupConcat({
Expression<String> groupConcat({
String separator = ',',
bool distinct = false,
Expression<bool?>? filter,
Expression<bool>? filter,
}) {
const sqliteDefaultSeparator = ',';
@ -70,25 +70,25 @@ extension BaseAggregate<DT> on Expression<DT> {
}
/// Provides aggregate functions that are available for numeric expressions.
extension ArithmeticAggregates<DT extends num> on Expression<DT?> {
extension ArithmeticAggregates<DT extends num> on Expression<DT> {
/// Return the average of all non-null values in this group.
///
/// {@macro drift_aggregate_filter}
Expression<double?> avg({Expression<bool?>? filter}) =>
Expression<double> avg({Expression<bool>? filter}) =>
_AggregateExpression('AVG', [this], filter: filter);
/// Return the maximum of all non-null values in this group.
///
/// If there are no non-null values in the group, returns null.
/// {@macro drift_aggregate_filter}
Expression<DT?> max({Expression<bool?>? filter}) =>
Expression<DT> max({Expression<bool>? filter}) =>
_AggregateExpression('MAX', [this], filter: filter);
/// Return the minimum of all non-null values in this group.
///
/// If there are no non-null values in the group, returns null.
/// {@macro drift_aggregate_filter}
Expression<DT?> min({Expression<bool?>? filter}) =>
Expression<DT> min({Expression<bool>? filter}) =>
_AggregateExpression('MIN', [this], filter: filter);
/// Calculate the sum of all non-null values in the group.
@ -100,7 +100,7 @@ extension ArithmeticAggregates<DT extends num> on Expression<DT?> {
/// See also [total], which behaves similarly but returns a floating point
/// value and doesn't throw an overflow exception.
/// {@macro drift_aggregate_filter}
Expression<DT?> sum({Expression<bool?>? filter}) =>
Expression<DT> sum({Expression<bool>? filter}) =>
_AggregateExpression('SUM', [this], filter: filter);
/// Calculate the sum of all non-null values in the group.
@ -108,31 +108,31 @@ extension ArithmeticAggregates<DT extends num> on Expression<DT?> {
/// If all values in the group are null, [total] returns `0.0`. This function
/// uses floating-point values internally.
/// {@macro drift_aggregate_filter}
Expression<double?> total({Expression<bool?>? filter}) =>
Expression<double> total({Expression<bool>? filter}) =>
_AggregateExpression('TOTAL', [this], filter: filter);
}
/// Provides aggregate functions that are available for BigInt expressions.
extension BigIntAggregates<DT extends BigInt> on Expression<DT?> {
extension BigIntAggregates on Expression<BigInt> {
/// Return the average of all non-null values in this group.
///
/// {@macro drift_aggregate_filter}
Expression<double?> avg({Expression<bool?>? filter}) =>
Expression<double> avg({Expression<bool>? filter}) =>
dartCast<int>().avg(filter: filter);
/// Return the maximum of all non-null values in this group.
///
/// If there are no non-null values in the group, returns null.
/// {@macro drift_aggregate_filter}
Expression<DT?> max({Expression<bool?>? filter}) =>
dartCast<int>().max(filter: filter).dartCast<DT?>();
Expression<BigInt> max({Expression<bool>? filter}) =>
dartCast<int>().max(filter: filter).dartCast<BigInt>();
/// Return the minimum of all non-null values in this group.
///
/// If there are no non-null values in the group, returns null.
/// {@macro drift_aggregate_filter}
Expression<DT?> min({Expression<bool?>? filter}) =>
dartCast<int>().min(filter: filter).dartCast<DT?>();
Expression<BigInt> min({Expression<bool>? filter}) =>
dartCast<int>().min(filter: filter).dartCast<BigInt>();
/// Calculate the sum of all non-null values in the group.
///
@ -143,41 +143,41 @@ extension BigIntAggregates<DT extends BigInt> on Expression<DT?> {
/// See also [total], which behaves similarly but returns a floating point
/// value and doesn't throw an overflow exception.
/// {@macro drift_aggregate_filter}
Expression<DT?> sum({Expression<bool?>? filter}) =>
dartCast<int>().sum(filter: filter).dartCast<DT?>();
Expression<BigInt> sum({Expression<bool>? filter}) =>
dartCast<int>().sum(filter: filter).dartCast<BigInt>();
/// Calculate the sum of all non-null values in the group.
///
/// If all values in the group are null, [total] returns `0.0`. This function
/// uses floating-point values internally.
/// {@macro drift_aggregate_filter}
Expression<double?> total({Expression<bool?>? filter}) =>
Expression<double> total({Expression<bool>? filter}) =>
dartCast<int>().total(filter: filter);
}
/// Provides aggregate functions that are available on date time expressions.
extension DateTimeAggregate on Expression<DateTime?> {
extension DateTimeAggregate on Expression<DateTime> {
/// Return the average of all non-null values in this group.
/// {@macro drift_aggregate_filter}
Expression<DateTime?> avg({Expression<bool?>? filter}) =>
Expression<DateTime> avg({Expression<bool>? filter}) =>
secondsSinceEpoch.avg(filter: filter).roundToInt().dartCast();
/// Return the maximum of all non-null values in this group.
///
/// If there are no non-null values in the group, returns null.
/// {@macro drift_aggregate_filter}
Expression<DateTime?> max({Expression<bool?>? filter}) =>
Expression<DateTime> max({Expression<bool>? filter}) =>
_AggregateExpression('MAX', [this], filter: filter);
/// Return the minimum of all non-null values in this group.
///
/// If there are no non-null values in the group, returns null.
/// {@macro drift_aggregate_filter}
Expression<DateTime?> min({Expression<bool?>? filter}) =>
Expression<DateTime> min({Expression<bool>? filter}) =>
_AggregateExpression('MIN', [this], filter: filter);
}
class _AggregateExpression<D> extends Expression<D> {
class _AggregateExpression<D extends Object> extends Expression<D> {
final String functionName;
final bool distinct;
final List<FunctionParameter> parameter;
@ -185,7 +185,7 @@ class _AggregateExpression<D> extends Expression<D> {
final Where? filter;
_AggregateExpression(this.functionName, this.parameter,
{Expression<bool?>? filter, this.distinct = false})
{Expression<bool>? filter, this.distinct = false})
: filter = filter != null ? Where(filter) : null;
@override

View File

@ -1,7 +1,7 @@
part of '../query_builder.dart';
/// Defines the `-`, `*` and `/` operators on sql expressions that support it.
extension ArithmeticExpr<DT extends num?> on Expression<DT> {
extension ArithmeticExpr<DT extends num> on Expression<DT> {
/// Performs an addition (`this` + [other]) in sql.
Expression<DT> operator +(Expression<DT> other) {
return _BaseInfixOperator(this, '+', other,
@ -37,45 +37,45 @@ extension ArithmeticExpr<DT extends num?> on Expression<DT> {
}
/// Rounds this expression to the nearest integer.
Expression<int?> roundToInt() {
Expression<int> roundToInt() {
return FunctionCallExpression('round', [this]).cast<int>();
}
}
/// Defines the `-`, `*` and `/` operators on sql expressions that support it.
extension ArithmeticBigIntExpr<DT extends BigInt?> on Expression<DT> {
extension ArithmeticBigIntExpr on Expression<BigInt> {
/// Performs an addition (`this` + [other]) in sql.
Expression<DT> operator +(Expression<DT> other) {
return (dartCast<int>() + other.dartCast<int>()).dartCast<DT>();
Expression<BigInt> operator +(Expression<BigInt> other) {
return (dartCast<int>() + other.dartCast<int>()).dartCast<BigInt>();
}
/// Performs a subtraction (`this` - [other]) in sql.
Expression<DT> operator -(Expression<DT> other) {
return (dartCast<int>() - other.dartCast<int>()).dartCast<DT>();
Expression<BigInt> operator -(Expression<BigInt> other) {
return (dartCast<int>() - other.dartCast<int>()).dartCast<BigInt>();
}
/// Returns the negation of this value.
Expression<DT> operator -() {
return (-dartCast<int>()).dartCast<DT>();
Expression<BigInt> operator -() {
return (-dartCast<int>()).dartCast<BigInt>();
}
/// Performs a multiplication (`this` * [other]) in sql.
Expression<DT> operator *(Expression<DT> other) {
return (dartCast<int>() * other.dartCast<int>()).dartCast<DT>();
Expression<BigInt> operator *(Expression<BigInt> other) {
return (dartCast<int>() * other.dartCast<int>()).dartCast<BigInt>();
}
/// Performs a division (`this` / [other]) in sql.
Expression<DT> operator /(Expression<DT> other) {
return (dartCast<int>() / other.dartCast<int>()).dartCast<DT>();
Expression<BigInt> operator /(Expression<BigInt> other) {
return (dartCast<int>() / other.dartCast<int>()).dartCast<BigInt>();
}
/// Calculates the absolute value of this number.
Expression<DT> abs() {
return dartCast<int>().abs().dartCast<DT>();
Expression<BigInt> abs() {
return dartCast<int>().abs().dartCast<BigInt>();
}
/// Rounds this expression to the nearest integer.
Expression<int?> roundToInt() {
Expression<int> roundToInt() {
return dartCast<int>().roundToInt();
}
}

View File

@ -1,24 +1,24 @@
part of '../query_builder.dart';
/// Defines operations on boolean values.
extension BooleanExpressionOperators on Expression<bool?> {
extension BooleanExpressionOperators on Expression<bool> {
/// Negates this boolean expression. The returned expression is true if
/// `this` is false, and vice versa.
Expression<bool?> not() => _NotExpression(this);
Expression<bool> not() => _NotExpression(this);
/// Returns an expression that is true iff both `this` and [other] are true.
Expression<bool?> operator &(Expression<bool?> other) {
Expression<bool> operator &(Expression<bool> other) {
return _BaseInfixOperator(this, 'AND', other, precedence: Precedence.and);
}
/// Returns an expression that is true if `this` or [other] are true.
Expression<bool?> operator |(Expression<bool?> other) {
Expression<bool> operator |(Expression<bool> other) {
return _BaseInfixOperator(this, 'OR', other, precedence: Precedence.or);
}
}
class _NotExpression extends Expression<bool?> {
final Expression<bool?> inner;
class _NotExpression extends Expression<bool> {
final Expression<bool> inner;
_NotExpression(this.inner);

View File

@ -6,7 +6,7 @@ import '../query_builder.dart';
///
/// This class supports when expressions with or without a base expression.
@internal
class CaseWhenExpression<T> extends Expression<T?> {
class CaseWhenExpression<T extends Object> extends Expression<T> {
/// The optional base expression. If it's set, the keys in [whenThen] will be
/// compared to this expression.
final Expression? base;
@ -16,7 +16,7 @@ class CaseWhenExpression<T> extends Expression<T?> {
final List<MapEntry<Expression, Expression>> whenThen;
/// The expression to use if no entry in [whenThen] matched.
final Expression<T?>? orElse;
final Expression<T>? orElse;
/// Creates a `CASE WHEN` expression from the independent components.
CaseWhenExpression(this.base, this.whenThen, this.orElse);

View File

@ -1,51 +1,51 @@
part of '../query_builder.dart';
/// Defines extension functions to express comparisons in sql
extension ComparableExpr<DT extends Comparable<dynamic>?> on Expression<DT> {
extension ComparableExpr<DT extends Comparable<dynamic>> on Expression<DT> {
/// Returns an expression that is true if this expression is strictly bigger
/// than the other expression.
Expression<bool?> isBiggerThan(Expression<DT> other) {
Expression<bool> isBiggerThan(Expression<DT> other) {
return _Comparison(this, _ComparisonOperator.more, other);
}
/// Returns an expression that is true if this expression is strictly bigger
/// than the other value.
Expression<bool?> isBiggerThanValue(DT other) {
Expression<bool> isBiggerThanValue(DT other) {
return isBiggerThan(Variable(other));
}
/// Returns an expression that is true if this expression is bigger than or
/// equal to he other expression.
Expression<bool?> isBiggerOrEqual(Expression<DT> other) {
Expression<bool> isBiggerOrEqual(Expression<DT> other) {
return _Comparison(this, _ComparisonOperator.moreOrEqual, other);
}
/// Returns an expression that is true if this expression is bigger than or
/// equal to he other value.
Expression<bool?> isBiggerOrEqualValue(DT other) {
Expression<bool> isBiggerOrEqualValue(DT other) {
return isBiggerOrEqual(Variable(other));
}
/// Returns an expression that is true if this expression is strictly smaller
/// than the other expression.
Expression<bool?> isSmallerThan(Expression<DT> other) {
Expression<bool> isSmallerThan(Expression<DT> other) {
return _Comparison(this, _ComparisonOperator.less, other);
}
/// Returns an expression that is true if this expression is strictly smaller
/// than the other value.
Expression<bool?> isSmallerThanValue(DT other) =>
Expression<bool> isSmallerThanValue(DT other) =>
isSmallerThan(Variable(other));
/// Returns an expression that is true if this expression is smaller than or
/// equal to he other expression.
Expression<bool?> isSmallerOrEqual(Expression<DT> other) {
Expression<bool> isSmallerOrEqual(Expression<DT> other) {
return _Comparison(this, _ComparisonOperator.lessOrEqual, other);
}
/// Returns an expression that is true if this expression is smaller than or
/// equal to he other value.
Expression<bool?> isSmallerOrEqualValue(DT other) {
Expression<bool> isSmallerOrEqualValue(DT other) {
return isSmallerOrEqual(Variable(other));
}
@ -54,7 +54,7 @@ extension ComparableExpr<DT extends Comparable<dynamic>?> on Expression<DT> {
///
/// If [not] is set, the expression will be negated. To compare this
/// expression against two values, see
Expression<bool?> isBetween(Expression<DT> lower, Expression<DT> higher,
Expression<bool> isBetween(Expression<DT> lower, Expression<DT> higher,
{bool not = false}) {
return _BetweenExpression(
target: this, lower: lower, higher: higher, not: not);
@ -64,7 +64,7 @@ extension ComparableExpr<DT extends Comparable<dynamic>?> on Expression<DT> {
/// [lower] and [higher] (both inclusive).
///
/// If [not] is set, the expression will be negated.
Expression<bool?> isBetweenValues(DT lower, DT higher, {bool not = false}) {
Expression<bool> isBetweenValues(DT lower, DT higher, {bool not = false}) {
return _BetweenExpression(
target: this,
lower: Variable<DT>(lower),
@ -74,7 +74,7 @@ extension ComparableExpr<DT extends Comparable<dynamic>?> on Expression<DT> {
}
}
class _BetweenExpression extends Expression<bool?> {
class _BetweenExpression extends Expression<bool> {
final Expression target;
// https://www.sqlite.org/lang_expr.html#between

View File

@ -7,7 +7,7 @@ part of '../query_builder.dart';
/// See also:
/// - [currentDate] and [currentDateAndTime], which use a [CustomExpression]
/// internally.
class CustomExpression<D> extends Expression<D> {
class CustomExpression<D extends Object> extends Expression<D> {
/// The SQL of this expression
final String content;

View File

@ -19,46 +19,46 @@ class _CustomDateTimeExpression extends CustomExpression<DateTime> {
/// Provides expressions to extract information from date time values, or to
/// calculate the difference between datetimes.
extension DateTimeExpressions on Expression<DateTime?> {
extension DateTimeExpressions on Expression<DateTime> {
/// Extracts the (UTC) year from `this` datetime expression.
Expression<int?> get year => _StrftimeSingleFieldExpression('%Y', this);
Expression<int> get year => _StrftimeSingleFieldExpression('%Y', this);
/// Extracts the (UTC) month from `this` datetime expression.
Expression<int?> get month => _StrftimeSingleFieldExpression('%m', this);
Expression<int> get month => _StrftimeSingleFieldExpression('%m', this);
/// Extracts the (UTC) day from `this` datetime expression.
Expression<int?> get day => _StrftimeSingleFieldExpression('%d', this);
Expression<int> get day => _StrftimeSingleFieldExpression('%d', this);
/// Extracts the (UTC) hour from `this` datetime expression.
Expression<int?> get hour => _StrftimeSingleFieldExpression('%H', this);
Expression<int> get hour => _StrftimeSingleFieldExpression('%H', this);
/// Extracts the (UTC) minute from `this` datetime expression.
Expression<int?> get minute => _StrftimeSingleFieldExpression('%M', this);
Expression<int> get minute => _StrftimeSingleFieldExpression('%M', this);
/// Extracts the (UTC) second from `this` datetime expression.
Expression<int?> get second => _StrftimeSingleFieldExpression('%S', this);
Expression<int> get second => _StrftimeSingleFieldExpression('%S', this);
/// Formats this datetime in the format `year-month-day`.
Expression<String?> get date => FunctionCallExpression(
Expression<String> get date => FunctionCallExpression(
'DATE', [this, const DateTimeModifier._unixEpoch()]);
/// Formats this datetime in the format `hour:minute:second`.
Expression<String?> get time => FunctionCallExpression(
Expression<String> get time => FunctionCallExpression(
'TIME', [this, const DateTimeModifier._unixEpoch()]);
/// Formats this datetime in the format `year-month-day hour:minute:second`.
Expression<String?> get datetime => FunctionCallExpression(
Expression<String> get datetime => FunctionCallExpression(
'DATETIME', [this, const DateTimeModifier._unixEpoch()]);
/// Formats this datetime as a unix timestamp - the number of seconds since
/// 1970-01-01 00:00:00 UTC. The unixepoch() always returns an integer, even
/// if the input time-value has millisecond precision.
Expression<int?> get unixepoch => FunctionCallExpression(
Expression<int> get unixepoch => FunctionCallExpression(
'UNIXEPOCH', [this, const DateTimeModifier._unixEpoch()]);
/// Formats this datetime in the Julian day format - a fractional number of
/// days since noon in Greenwich on November 24, 4714 B.C.
Expression<double?> get julianday => FunctionCallExpression(
Expression<double> get julianday => FunctionCallExpression(
'JULIANDAY', [this, const DateTimeModifier._unixEpoch()]);
/// Formats this datetime according to the format string specified as the
@ -79,7 +79,7 @@ extension DateTimeExpressions on Expression<DateTime?> {
/// * %W week of year: 00-53
/// * %Y year: 0000-9999
/// * %% %
Expression<String?> strftime(String format) => FunctionCallExpression(
Expression<String> strftime(String format) => FunctionCallExpression(
'STRFTIME',
[Constant<String>(format), this, const DateTimeModifier._unixEpoch()]);
@ -87,7 +87,7 @@ extension DateTimeExpressions on Expression<DateTime?> {
///
/// See the factories on [DateTimeModifier] for a list of modifiers that can
/// be used with this method.
Expression<DateTime?> modify(DateTimeModifier modifier) =>
Expression<DateTime> modify(DateTimeModifier modifier) =>
FunctionCallExpression(
'unixepoch', [this, const DateTimeModifier._unixEpoch(), modifier]);
@ -96,7 +96,7 @@ extension DateTimeExpressions on Expression<DateTime?> {
/// The [modifiers] are applied in sequence from left to right.
/// For a list of modifiers and how they behave, see the docs on
/// [DateTimeModifier] factories.
Expression<DateTime?> modifyAll(Iterable<DateTimeModifier> modifiers) =>
Expression<DateTime> modifyAll(Iterable<DateTimeModifier> modifiers) =>
FunctionCallExpression('unixepoch',
[this, const DateTimeModifier._unixEpoch(), ...modifiers]);
@ -132,9 +132,9 @@ extension DateTimeExpressions on Expression<DateTime?> {
/// Expression that extracts components out of a date time by using the builtin
/// sqlite function "strftime" and casting the result to an integer.
class _StrftimeSingleFieldExpression extends Expression<int?> {
class _StrftimeSingleFieldExpression extends Expression<int> {
final String format;
final Expression<DateTime?> date;
final Expression<DateTime> date;
_StrftimeSingleFieldExpression(this.format, this.date);

View File

@ -17,7 +17,7 @@ abstract class FunctionParameter implements Component {}
/// [JoinedSelectStatement], e.g. through [DatabaseConnectionUser.selectOnly]:
///
/// ```dart
/// Expression<int?> countUsers = users.id.count();
/// Expression<int> countUsers = users.id.count();
///
/// // Add the expression to a select statement to evaluate it.
/// final query = selectOnly(users)..addColumns([countUsers]);
@ -29,7 +29,7 @@ abstract class FunctionParameter implements Component {}
///
/// It's important that all subclasses properly implement [hashCode] and
/// [==].
abstract class Expression<D> implements FunctionParameter {
abstract class Expression<D extends Object> implements FunctionParameter {
/// Constant constructor so that subclasses can be constant.
const Expression();
@ -59,7 +59,7 @@ abstract class Expression<D> implements FunctionParameter {
/// in sql, use [cast].
///
/// This method is used internally by drift.
Expression<D2> dartCast<D2>() {
Expression<D2> dartCast<D2 extends Object>() {
return _DartCastExpression<D, D2>(this);
}
@ -68,19 +68,19 @@ abstract class Expression<D> implements FunctionParameter {
/// Note that this does not do a meaningful conversion for drift-only types
/// like `bool` or `DateTime`. Both would simply generate a `CAST AS INT`
/// expression.
Expression<D2?> cast<D2 extends Object>() {
Expression<D2> cast<D2 extends Object>() {
return _CastInSqlExpression<D, D2>(this);
}
/// An expression that is true if `this` resolves to any of the values in
/// [values].
Expression<bool?> isIn(Iterable<D> values) {
Expression<bool> isIn(Iterable<D> values) {
return _InExpression(this, values.toList(), false);
}
/// An expression that is true if `this` does not resolve to any of the values
/// in [values].
Expression<bool?> isNotIn(Iterable<D> values) {
Expression<bool> isNotIn(Iterable<D> values) {
return _InExpression(this, values.toList(), true);
}
@ -88,7 +88,7 @@ abstract class Expression<D> implements FunctionParameter {
/// provided [select] statement.
///
/// The [select] statement may only have one column.
Expression<bool?> isInQuery(BaseSelectStatement select) {
Expression<bool> isInQuery(BaseSelectStatement select) {
_checkSubquery(select);
return _InSelectExpression(select, this, false);
}
@ -97,7 +97,7 @@ abstract class Expression<D> implements FunctionParameter {
/// provided [select] statement.
///
/// The [select] statement may only have one column.
Expression<bool?> isNotInQuery(BaseSelectStatement select) {
Expression<bool> isNotInQuery(BaseSelectStatement select) {
_checkSubquery(select);
return _InSelectExpression(select, this, true);
}
@ -129,9 +129,9 @@ abstract class Expression<D> implements FunctionParameter {
/// orElse: Constant('(unknown)'),
/// );
/// ```
Expression<T?> caseMatch<T>({
required Map<Expression<D>, Expression<T?>> when,
Expression<T?>? orElse,
Expression<T> caseMatch<T extends Object>({
required Map<Expression<D>, Expression<T>> when,
Expression<T>? orElse,
}) {
if (when.isEmpty) {
throw ArgumentError.value(when, 'when', 'Must not be empty');
@ -166,6 +166,9 @@ abstract class Expression<D> implements FunctionParameter {
"Expressions with unknown precedence shouldn't have inner expressions");
inner.writeAroundPrecedence(ctx, precedence);
}
/// The supported [DriftSqlType] backing this expression.
DriftSqlType<D> get driftSqlType => DriftSqlType.forType();
}
/// Used to order the precedence of sql expressions so that we can avoid
@ -244,7 +247,7 @@ class Precedence implements Comparable<Precedence> {
/// An expression that looks like "$a operator $b", where $a and $b itself
/// are expressions and the operator is any string.
abstract class _InfixOperator<D> extends Expression<D> {
abstract class _InfixOperator<D extends Object> extends Expression<D> {
/// The left-hand side of this expression
Expression get left;
@ -275,7 +278,7 @@ abstract class _InfixOperator<D> extends Expression<D> {
}
}
class _BaseInfixOperator<D> extends _InfixOperator<D> {
class _BaseInfixOperator<D extends Object> extends _InfixOperator<D> {
@override
final Expression left;
@ -349,7 +352,7 @@ class _Comparison extends _InfixOperator<bool> {
_Comparison.equal(this.left, this.right) : op = _ComparisonOperator.equal;
}
class _UnaryMinus<DT> extends Expression<DT> {
class _UnaryMinus<DT extends Object> extends Expression<DT> {
final Expression<DT> inner;
_UnaryMinus(this.inner);
@ -372,7 +375,8 @@ class _UnaryMinus<DT> extends Expression<DT> {
}
}
class _DartCastExpression<D1, D2> extends Expression<D2> {
class _DartCastExpression<D1 extends Object, D2 extends Object>
extends Expression<D2> {
final Expression<D1> inner;
_DartCastExpression(this.inner);
@ -397,7 +401,8 @@ class _DartCastExpression<D1, D2> extends Expression<D2> {
}
}
class _CastInSqlExpression<D1, D2 extends Object> extends Expression<D2?> {
class _CastInSqlExpression<D1 extends Object, D2 extends Object>
extends Expression<D2> {
final Expression<D1> inner;
@override
@ -420,7 +425,7 @@ class _CastInSqlExpression<D1, D2 extends Object> extends Expression<D2?> {
/// This class is mainly used by drift internally. If you find yourself using
/// this class, consider [creating an issue](https://github.com/simolus3/drift/issues/new)
/// to request native support in drift.
class FunctionCallExpression<R> extends Expression<R> {
class FunctionCallExpression<R extends Object> extends Expression<R> {
/// The name of the function to call
final String functionName;
@ -466,12 +471,13 @@ void _checkSubquery(BaseSelectStatement statement) {
///
/// The statement, which can be created via [DatabaseConnectionUser.select] in
/// a database class, must return exactly one row with exactly one column.
Expression<R> subqueryExpression<R>(BaseSelectStatement statement) {
Expression<R> subqueryExpression<R extends Object>(
BaseSelectStatement statement) {
_checkSubquery(statement);
return _SubqueryExpression<R>(statement);
}
class _SubqueryExpression<R> extends Expression<R> {
class _SubqueryExpression<R extends Object> extends Expression<R> {
final BaseSelectStatement statement;
_SubqueryExpression(this.statement);

View File

@ -1,6 +1,6 @@
part of '../query_builder.dart';
abstract class _BaseInExpression extends Expression<bool?> {
abstract class _BaseInExpression extends Expression<bool> {
final Expression _expression;
final bool _not;
@ -25,7 +25,7 @@ abstract class _BaseInExpression extends Expression<bool?> {
void _writeValues(GenerationContext context);
}
class _InExpression<T> extends _BaseInExpression {
class _InExpression<T extends Object> extends _BaseInExpression {
final List<T> _values;
_InExpression(Expression expression, this._values, bool not)

View File

@ -22,7 +22,7 @@ extension SqlIsNull on Expression {
/// Evaluates to the first expression in [expressions] that's not null, or
/// null if all [expressions] evaluate to null.
Expression<T> coalesce<T>(List<Expression<T?>> expressions) {
Expression<T> coalesce<T extends Object>(List<Expression<T>> expressions) {
assert(expressions.length >= 2,
'expressions must be of length >= 2, got ${expressions.length}');

View File

@ -1,11 +1,11 @@
part of '../query_builder.dart';
/// Defines methods that operate on a column storing [String] values.
extension StringExpressionOperators on Expression<String?> {
extension StringExpressionOperators on Expression<String> {
/// Whether this column matches the given pattern. For details on what patters
/// are valid and how they are interpreted, check out
/// [this tutorial](http://www.sqlitetutorial.net/sqlite-like/).
Expression<bool?> like(String regex) {
Expression<bool> like(String regex) {
return _LikeOperator(this, Variable.withString(regex));
}
@ -17,7 +17,7 @@ extension StringExpressionOperators on Expression<String?> {
/// Note that this function is only available when using a `NativeDatabase`.
/// If you need to support the web or `moor_flutter`, consider using [like]
/// instead.
Expression<bool?> regexp(
Expression<bool> regexp(
String regex, {
bool multiLine = false,
bool caseSensitive = true,
@ -63,7 +63,7 @@ extension StringExpressionOperators on Expression<String?> {
/// Note that this is case-insensitive for the English alphabet only.
///
/// This is equivalent to calling [like] with `%<substring>%`.
Expression<bool?> contains(String substring) {
Expression<bool> contains(String substring) {
return like('%$substring%');
}
@ -74,7 +74,7 @@ extension StringExpressionOperators on Expression<String?> {
}
/// Performs a string concatenation in sql by appending [other] to `this`.
Expression<String> operator +(Expression<String?> other) {
Expression<String> operator +(Expression<String> other) {
return _BaseInfixOperator(this, '||', other,
precedence: Precedence.stringConcatenation);
}
@ -84,7 +84,7 @@ extension StringExpressionOperators on Expression<String?> {
///
/// See also:
/// - https://www.w3resource.com/sqlite/core-functions-upper.php
Expression<String?> upper() {
Expression<String> upper() {
return FunctionCallExpression('UPPER', [this]);
}
@ -93,7 +93,7 @@ extension StringExpressionOperators on Expression<String?> {
///
/// See also:
/// - https://www.w3resource.com/sqlite/core-functions-lower.php
Expression<String?> lower() {
Expression<String> lower() {
return FunctionCallExpression('LOWER', [this]);
}
@ -103,34 +103,34 @@ extension StringExpressionOperators on Expression<String?> {
///
/// See also:
/// - https://www.w3resource.com/sqlite/core-functions-length.php
Expression<int?> get length {
Expression<int> get length {
return FunctionCallExpression('LENGTH', [this]);
}
/// Removes spaces from both ends of this string.
Expression<String?> trim() {
Expression<String> trim() {
return FunctionCallExpression('TRIM', [this]);
}
/// Removes spaces from the beginning of this string.
Expression<String?> trimLeft() {
Expression<String> trimLeft() {
return FunctionCallExpression('LTRIM', [this]);
}
/// Removes spaces from the end of this string.
Expression<String?> trimRight() {
Expression<String> trimRight() {
return FunctionCallExpression('RTRIM', [this]);
}
}
/// A `text LIKE pattern` expression that will be true if the first expression
/// matches the pattern given by the second expression.
class _LikeOperator extends Expression<bool?> {
class _LikeOperator extends Expression<bool> {
/// The target expression that will be tested
final Expression<String?> target;
final Expression<String> target;
/// The regex-like expression to test the [target] against.
final Expression<String?> regex;
final Expression<String> regex;
/// The operator to use when matching. Defaults to `LIKE`.
final String operator;

View File

@ -5,9 +5,9 @@ part of '../query_builder.dart';
/// An expression that represents the value of a dart object encoded to sql
/// using prepared statements.
class Variable<T> extends Expression<T> {
class Variable<T extends Object> extends Expression<T> {
/// The Dart value that will be sent to the database
final T value;
final T? value;
// note that we keep the identity hash/equals here because each variable would
// get its own index in sqlite and is thus different.
@ -104,7 +104,7 @@ class Variable<T> extends Expression<T> {
/// An expression that represents the value of a dart object encoded to sql
/// by writing them into the sql statements. For most cases, consider using
/// [Variable] instead.
class Constant<T> extends Expression<T> {
class Constant<T extends Object> extends Expression<T> {
/// Constructs a new constant (sql literal) holding the [value].
const Constant(this.value);
@ -112,7 +112,7 @@ class Constant<T> extends Expression<T> {
Precedence get precedence => Precedence.primary;
/// The value that will be converted to an sql literal.
final T value;
final T? value;
@override
bool get isLiteral => true;

View File

@ -100,7 +100,7 @@ extension TableStatements<Tbl extends Table, Row> on TableInfo<Tbl, Row> {
/// Deletes all rows matching the [filter] from the table.
///
/// See also [SingleTableQueryMixin.where].
Future<int> deleteWhere(Expression<bool?> Function(Tbl tbl) filter) {
Future<int> deleteWhere(Expression<bool> Function(Tbl tbl) filter) {
return (delete()..where(filter)).go();
}
}

View File

@ -5,7 +5,7 @@ const VerificationResult _invalidNull = VerificationResult.failure(
"Null fields thus can't be inserted.");
/// Implementation for a [Column] declared on a table.
class GeneratedColumn<T> extends Column<T> {
class GeneratedColumn<T extends Object> extends Column<T> {
/// The sql name of this column.
final String $name; // todo: Remove, replace with `name`
@ -40,7 +40,7 @@ class GeneratedColumn<T> extends Column<T> {
/// time.
/// This field is defined as a lazy function because the check constraint
/// typically depends on the column itself.
final Expression<bool?> Function()? check;
final Expression<bool> Function()? check;
/// A function that yields a default column for inserts if no value has been
/// set. This is different to [defaultValue] since the function is written in
@ -54,7 +54,7 @@ class GeneratedColumn<T> extends Column<T> {
final VerificationResult Function(T, VerificationMeta)? additionalChecks;
/// The sql type to use for this column.
final DriftSqlType type;
final DriftSqlType<T> type;
/// If this column is generated (that is, it is a SQL expression of other)
/// columns, contains information about how to generate this column.
@ -253,9 +253,10 @@ class GeneratedColumn<T> extends Column<T> {
///
/// This provides the [equalsValue] method, which can be used to compare this
/// column against a value mapped through a type converter.
class GeneratedColumnWithTypeConverter<D, S> extends GeneratedColumn<S> {
class GeneratedColumnWithTypeConverter<D, S extends Object>
extends GeneratedColumn<S> {
/// The type converted used on this column.
final TypeConverter<D, S> converter;
final TypeConverter<D?, S?> converter;
GeneratedColumnWithTypeConverter._(
this.converter,
@ -263,14 +264,14 @@ class GeneratedColumnWithTypeConverter<D, S> extends GeneratedColumn<S> {
String tableName,
bool nullable,
S Function()? clientDefault,
DriftSqlType type,
DriftSqlType<S> type,
String? defaultConstraints,
String? customConstraints,
Expression<S>? defaultValue,
VerificationResult Function(S, VerificationMeta)? additionalChecks,
bool requiredDuringInsert,
GeneratedAs? generatedAs,
Expression<bool?> Function()? check,
Expression<bool> Function()? check,
) : super(
name,
tableName,

View File

@ -172,12 +172,12 @@ extension RowIdExtension on TableInfo {
/// the [rowId] will not be part of a drift-generated data class. In this
/// case, the [rowId] getter can be used to refer to a table's row id in a
/// query.
Expression<int?> get rowId {
Expression<int> get rowId {
if (withoutRowId || this is VirtualTableInfo) {
throw ArgumentError('Cannot use rowId on a table without a rowid!');
}
return GeneratedColumn<int?>('_rowid_', aliasedName, false,
return GeneratedColumn<int>('_rowid_', aliasedName, false,
type: DriftSqlType.int);
}
}

View File

@ -360,7 +360,7 @@ class DoUpdate<T extends Table, D> extends UpsertClause<T, D> {
///
/// For an example, see [InsertStatement.insert].
DoUpdate(Insertable<D> Function(T old) update,
{this.target, Expression<bool?> Function(T old)? where})
{this.target, Expression<bool> Function(T old)? where})
: _creator = ((old, _) => update(old)),
_where = where == null ? null : ((old, _) => Where(where(old))),
_usesExcludedTable = false;
@ -379,7 +379,7 @@ class DoUpdate<T extends Table, D> extends UpsertClause<T, D> {
///
/// For an example, see [InsertStatement.insert].
DoUpdate.withExcluded(Insertable<D> Function(T old, T excluded) update,
{this.target, Expression<bool?> Function(T old, T excluded)? where})
{this.target, Expression<bool> Function(T old, T excluded)? where})
: _creator = update,
_usesExcludedTable = true,
_where = where == null

View File

@ -325,7 +325,7 @@ mixin SingleTableQueryMixin<T extends HasResultSet, D> on Query<T, D> {
/// which explains how to express most SQL expressions in Dart.
/// If you want to remove duplicate rows from a query, use the `distinct`
/// parameter on [DatabaseConnectionUser.select].
void where(Expression<bool?> Function(T tbl) filter) {
void where(Expression<bool> Function(T tbl) filter) {
final predicate = filter(table.asDslTable);
if (whereExpr == null) {
@ -374,7 +374,7 @@ extension QueryTableExtensions<T extends Table, D>
return MapEntry(primaryKeyColumns[columnName]!, value);
});
Expression<bool?>? predicate;
Expression<bool>? predicate;
for (final entry in primaryKeyValues.entries) {
final comparison =
_Comparison(entry.key, _ComparisonOperator.equal, entry.value);

View File

@ -183,7 +183,7 @@ class TypedResult {
/// as a column, for instance via [JoinedSelectStatement.addColumns].
///
/// To access the underlying columns directly, use [rawData].
D read<D>(Expression<D> expr) {
D? read<D extends Object>(Expression<D> expr) {
if (_parsedExpressions.containsKey(expr)) {
return _parsedExpressions[expr] as D;
}

View File

@ -136,7 +136,7 @@ class JoinedSelectStatement<FirstT extends HasResultSet, FirstD>
/// ])
/// ..where(todos.name.like("%Important") & categories.name.equals("Work"));
/// ```
void where(Expression<bool?> predicate) {
void where(Expression<bool> predicate) {
if (whereExpr == null) {
whereExpr = Where(predicate);
} else {
@ -192,7 +192,7 @@ class JoinedSelectStatement<FirstT extends HasResultSet, FirstD>
/// Groups the result by values in [expressions].
///
/// An optional [having] attribute can be set to exclude certain groups.
void groupBy(Iterable<Expression> expressions, {Expression<bool?>? having}) {
void groupBy(Iterable<Expression> expressions, {Expression<bool>? having}) {
_groupBy = GroupBy._(expressions.toList(), having);
}
@ -252,8 +252,7 @@ class JoinedSelectStatement<FirstT extends HasResultSet, FirstD>
final expr = aliasedColumn.key;
final value = row[aliasedColumn.value];
final type = expr.findType(ctx.typeSystem);
readColumns[expr] = ctx.options.types.read(type, value);
readColumns[expr] = ctx.options.types.read(expr.driftSqlType, value);
}
return TypedResult(readTables, QueryRow(row, database), readColumns);

View File

@ -1,26 +0,0 @@
import 'package:drift/drift.dart';
import 'package:test/test.dart';
void main() {
final nullable =
GeneratedColumn<DateTime>('name', 'table', true, type: DriftSqlType.int);
final nonNull =
GeneratedColumn<DateTime>('name', 'table', false, type: DriftSqlType.int);
test('should write column definition', () {
final nonNullQuery = GenerationContext.fromDb(null);
final nullableQuery = GenerationContext.fromDb(null);
nonNull.writeColumnDefinition(nonNullQuery);
nullable.writeColumnDefinition(nullableQuery);
expect(nullableQuery.sql, equals('name INTEGER NULL'));
expect(nonNullQuery.sql, equals('name INTEGER NOT NULL'));
});
test('can compare', () {
final ctx = GenerationContext.fromDb(null);
nonNull.isSmallerThan(currentDateAndTime).writeInto(ctx);
expect(ctx.sql, "name < strftime('%s', CURRENT_TIMESTAMP)");
});
}

View File

@ -3,7 +3,7 @@ import 'package:test/test.dart';
import '../../test_utils/test_utils.dart';
typedef _Extractor = Expression Function(Expression<DateTime?> d);
typedef _Extractor = Expression Function(Expression<DateTime> d);
void main() {
const column =
@ -32,7 +32,7 @@ void main() {
test('can cast datetimes to unix timestamps without rewriting', () {
final expr = currentDateAndTime.secondsSinceEpoch + const Constant(10);
final ctx = GenerationContext(SqlTypeSystem.defaultInstance, null);
final ctx = stubContext();
expr.writeInto(ctx);
expect(ctx.sql, 'strftime(\'%s\', CURRENT_TIMESTAMP) + 10');

View File

@ -28,7 +28,7 @@ void main() {
test('generates parentheses for OR in AND', () {
final c =
GeneratedColumn<String>('c', 't', false, type: const StringType());
GeneratedColumn<String>('c', 't', false, type: DriftSqlType.string);
final expr =
(c.equals('A') | c.equals('B')) & (c.equals('C') | c.equals(''));
expect(

View File

@ -18,7 +18,7 @@ void main() {
tearDown(() => db.close());
Future<T> eval<T>(Expression<T> expr, {TableInfo? onTable}) {
Future<T?> eval<T extends Object>(Expression<T> expr, {TableInfo? onTable}) {
final query = db.selectOnly(onTable ?? db.users)..addColumns([expr]);
return query.getSingle().then((row) => row.read(expr));
}
@ -33,7 +33,7 @@ void main() {
..addColumns([nowStamp, tomorrowStamp]))
.getSingle();
expect(row.read(tomorrowStamp) - row.read(nowStamp),
expect(row.read(tomorrowStamp)! - row.read(nowStamp)!,
const Duration(days: 1).inSeconds);
});

View File

@ -31,7 +31,7 @@ void main() {
expect(isInExpression,
generates('name IN (SELECT users.name AS "users.name" FROM users)'));
final ctx = GenerationContext(SqlTypeSystem.defaultInstance, null);
final ctx = stubContext();
isInExpression.writeInto(ctx);
expect(ctx.watchedTables, contains(db.users));
});

View File

@ -29,8 +29,7 @@ void main() {
});
test('generates COALESCE expressions', () {
final expr =
drift.coalesce([const Constant<int?>(null), const Constant(3)]);
final expr = drift.coalesce([const Constant<int>(null), const Constant(3)]);
expect(expr, generates('COALESCE(NULL, 3)'));
});

View File

@ -18,43 +18,42 @@ void main() {
group('can write variables with wrong type parameter', () {
test('true', () {
expect(const Variable<dynamic>(true), generates('?', [1]));
expect(const Variable<Object>(true), generates('?', [1]));
});
test('false', () {
expect(const Variable<dynamic>(false), generates('?', [0]));
expect(const Variable<Object>(false), generates('?', [0]));
});
test('string', () {
expect(const Variable<dynamic>('hi'), generates('?', ['hi']));
expect(const Variable<Object>('hi'), generates('?', ['hi']));
});
test('int', () {
expect(const Variable<dynamic>(123), generates('?', [123]));
expect(const Variable<Object>(123), generates('?', [123]));
});
test('big int', () {
expect(Variable<dynamic>(BigInt.from(123)),
generates('?', [BigInt.from(123)]));
expect(Variable(BigInt.from(123)), generates('?', [BigInt.from(123)]));
});
test('date time', () {
const stamp = 12345678;
final dateTime = DateTime.fromMillisecondsSinceEpoch(stamp * 1000);
expect(Variable<dynamic>(dateTime), generates('?', [stamp]));
expect(Variable(dateTime), generates('?', [stamp]));
});
test('blob', () {
final data = Uint8List.fromList([1, 2, 3]);
expect(Variable<dynamic>(data), generates('?', [data]));
expect(Variable(data), generates('?', [data]));
});
test('double', () {
expect(const Variable<dynamic>(12.3), generates('?', [12.3]));
expect(const Variable(12.3), generates('?', [12.3]));
});
});
test('writes null directly for null values', () {
const variable = Variable<String?>(null);
const variable = Variable<String>(null);
final ctx = GenerationContext.fromDb(TodoDb());
variable.writeInto(ctx);
@ -64,7 +63,7 @@ void main() {
});
test('writes constants when variables are not supported', () {
const variable = Variable<String?>("hello world'");
const variable = Variable("hello world'");
final ctx = GenerationContext.fromDb(TodoDb(), supportsVariables: false);
variable.writeInto(ctx);

View File

@ -30,6 +30,7 @@ void main() {
});
test('does not allow empty WHEN map', () {
expect(() => x.caseMatch(when: const {}), throwsA(isA<ArgumentError>()));
expect(() => x.caseMatch<Object>(when: const {}),
throwsA(isA<ArgumentError>()));
});
}

View File

@ -190,9 +190,7 @@ void main() {
}
class _DefaultDb extends GeneratedDatabase {
_DefaultDb(QueryExecutor executor)
// ignore: prefer_const_constructors
: super(SqlTypeSystem.withDefaults(), executor);
_DefaultDb(QueryExecutor executor) : super(executor);
@override
List<TableInfo<Table, DataClass>> get allTables => [];

View File

@ -5,28 +5,29 @@ import 'package:test/test.dart';
void main() {
test('maps without transformation', () {
const type = BlobType();
final types = DriftDatabaseOptions().types;
final data = Uint8List.fromList(List.generate(256, (i) => i));
expect(type.mapToSqlVariable(data), data);
expect(type.mapFromDatabaseResponse(data), data);
expect(types.mapToSqlVariable(data), data);
expect(types.read(DriftSqlType.blob, data), data);
});
test('writes blob literals', () {
const type = BlobType();
final types = DriftDatabaseOptions().types;
const hex = '67656E6572616C206B656E6F626921';
final data = Uint8List.fromList(utf8.encode('general kenobi!'));
expect(type.mapToSqlConstant(data), equalsIgnoringCase("x'$hex'"));
expect(types.mapToSqlLiteral(data), equalsIgnoringCase("x'$hex'"));
});
test('maps of string', () {
const chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz';
const type = BlobType();
final types = DriftDatabaseOptions().types;
final data = List.generate(256, (i) => chars[i % chars.length]);
final dataString = data.join();
final dataInt = data.map((e) => e.codeUnits[0]).toList();
final dataUint8 = Uint8List.fromList(dataInt);
expect(type.mapFromDatabaseResponse(dataString), dataUint8);
expect(types.read(DriftSqlType.string, dataString), dataUint8);
});
}

View File

@ -1,36 +1,28 @@
import 'package:drift/drift.dart' as drift;
import 'package:drift/drift.dart';
import 'package:test/test.dart';
const _exampleUnixSqlite = 1550172560;
const _exampleUnixMillis = 1550172560000;
final _exampleDateTime =
DateTime.fromMillisecondsSinceEpoch(_exampleUnixMillis);
import '../../test_utils/test_utils.dart';
void main() {
const type = drift.DateTimeType();
final nullable = GeneratedColumn<DateTime>('name', 'table', true,
type: DriftSqlType.dateTime);
final nonNull = GeneratedColumn<DateTime>('name', 'table', false,
type: DriftSqlType.dateTime);
group('DateTimes', () {
test('can be read from unix stamps returned by sql', () {
expect(
type.mapFromDatabaseResponse(_exampleUnixSqlite), _exampleDateTime);
});
test('should write column definition', () {
final nonNullQuery = stubContext();
final nullableQuery = stubContext();
nonNull.writeColumnDefinition(nonNullQuery);
nullable.writeColumnDefinition(nullableQuery);
test('can read null value from sql', () {
expect(type.mapFromDatabaseResponse(null), isNull);
});
expect(nullableQuery.sql, equals('name INTEGER NULL'));
expect(nonNullQuery.sql, equals('name INTEGER NOT NULL'));
});
test('can be mapped to sql constants', () {
expect(type.mapToSqlConstant(_exampleDateTime),
_exampleUnixSqlite.toString());
});
test('can compare', () {
final ctx = stubContext();
nonNull.isSmallerThan(currentDateAndTime).writeInto(ctx);
test('can be mapped to variables', () {
expect(type.mapToSqlVariable(_exampleDateTime), _exampleUnixSqlite);
});
test('map null to null', () {
expect(type.mapToSqlConstant(null), 'NULL');
expect(type.mapToSqlVariable(null), null);
});
expect(ctx.sql, "name < strftime('%s', CURRENT_TIMESTAMP)");
});
}

View File

@ -1,7 +1,7 @@
import 'package:drift/drift.dart';
import 'package:test/test.dart';
import '../../../generated/todos.dart';
import '../../generated/todos.dart';
void main() {
test('int column writes AUTOINCREMENT constraint', () {
@ -9,7 +9,7 @@ void main() {
'foo',
'tbl',
false,
type: const IntType(),
type: DriftSqlType.int,
$customConstraints: 'NOT NULL PRIMARY KEY AUTOINCREMENT',
);
@ -22,7 +22,7 @@ void main() {
test('int column writes PRIMARY KEY constraint', () {
final column = GeneratedColumn<int>('foo', 'tbl', false,
type: const IntType(), $customConstraints: 'NOT NULL PRIMARY KEY');
type: DriftSqlType.int, $customConstraints: 'NOT NULL PRIMARY KEY');
final context = GenerationContext.fromDb(TodoDb());
column.writeColumnDefinition(context);

View File

@ -2,28 +2,28 @@ import 'package:drift/drift.dart' as drift;
import 'package:test/test.dart';
void main() {
const type = drift.RealType();
final typeSystem = drift.DriftDatabaseOptions().types;
group('RealType', () {
test('can be read from floating point values returned by sql', () {
expect(type.mapFromDatabaseResponse(3.1234), 3.1234);
expect(typeSystem.read(drift.DriftSqlType.double, 3.1234), 3.1234);
});
test('can read null value from sql', () {
expect(type.mapFromDatabaseResponse(null), isNull);
expect(typeSystem.read(drift.DriftSqlType.double, null), isNull);
});
test('can be mapped to sql constants', () {
expect(type.mapToSqlConstant(1.123), '1.123');
expect(typeSystem.mapToSqlLiteral(1.123), '1.123');
});
test('can be mapped to variables', () {
expect(type.mapToSqlVariable(1.123), 1.123);
expect(typeSystem.mapToSqlVariable(1.123), 1.123);
});
test('map null to null', () {
expect(type.mapToSqlConstant(null), 'NULL');
expect(type.mapToSqlVariable(null), null);
expect(typeSystem.mapToSqlLiteral(null), 'NULL');
expect(typeSystem.mapToSqlVariable(null), null);
});
});
}

View File

@ -3,12 +3,11 @@ import 'package:test/test.dart';
void main() {
test('types map null values to null', () {
const typeSystem = SqlTypeSystem.defaultInstance;
final options = DriftDatabaseOptions();
expect(options.types.mapToSqlVariable(null), isNull);
for (final type in typeSystem.types) {
expect(type.mapToSqlVariable(null), isNull,
reason: '$type should map null to null variables');
expect(type.mapFromDatabaseResponse(null), isNull,
for (final type in DriftSqlType.values) {
expect(options.types.read(type, null), isNull,
reason: '$type should map null response to null value');
}
});

View File

@ -36,11 +36,11 @@ void main() {
// insert exactly one row so that we can evaluate expressions from Dart
await db.into(db.pureDefaults).insert(PureDefaultsCompanion.insert());
Future<bool> evaluate(Expression<bool?> expr) async {
Future<bool?> evaluate(Expression<bool> expr) async {
final result = await (db.selectOnly(db.pureDefaults)..addColumns([expr]))
.getSingle();
return result.read<bool?>(expr)!;
return result.read<bool>(expr);
}
expect(
@ -66,11 +66,11 @@ void main() {
tearDown(() => db.close());
Future<bool> evaluate(Expression<bool?> expr) async {
Future<bool?> evaluate(Expression<bool> expr) async {
final result = await (db.selectOnly(db.pureDefaults)..addColumns([expr]))
.getSingle();
return result.read<bool?>(expr)!;
return result.read<bool>(expr)!;
}
test('multiLine', () {

View File

@ -17,35 +17,21 @@ class Config extends DataClass implements Insertable<Config> {
this.configValue,
this.syncState,
this.syncStateImplicit});
factory Config.fromData(Map<String, dynamic> data, {String? prefix}) {
final effectivePrefix = prefix ?? '';
return Config(
configKey: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}config_key'])!,
configValue: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}config_value']),
syncState: ConfigTable.$converter0n.fromSql(const IntType()
.mapFromDatabaseResponse(data['${effectivePrefix}sync_state'])),
syncStateImplicit: ConfigTable.$converter1.fromSql(const IntType()
.mapFromDatabaseResponse(
data['${effectivePrefix}sync_state_implicit'])),
);
}
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
map['config_key'] = Variable<String>(configKey);
if (!nullToAbsent || configValue != null) {
map['config_value'] = Variable<String?>(configValue);
map['config_value'] = Variable<String>(configValue);
}
if (!nullToAbsent || syncState != null) {
final converter = ConfigTable.$converter0n;
map['sync_state'] = Variable<int?>(converter.toSql(syncState));
map['sync_state'] = Variable<int>(converter.toSql(syncState));
}
if (!nullToAbsent || syncStateImplicit != null) {
final converter = ConfigTable.$converter1;
map['sync_state_implicit'] =
Variable<int?>(converter.toSql(syncStateImplicit));
Variable<int>(converter.toSql(syncStateImplicit));
}
return map;
}
@ -147,9 +133,9 @@ class ConfigCompanion extends UpdateCompanion<Config> {
}) : configKey = Value(configKey);
static Insertable<Config> custom({
Expression<String>? configKey,
Expression<String?>? configValue,
Expression<SyncType?>? syncState,
Expression<SyncType?>? syncStateImplicit,
Expression<String>? configValue,
Expression<int>? syncState,
Expression<int>? syncStateImplicit,
}) {
return RawValuesInsertable({
if (configKey != null) 'config_key': configKey,
@ -179,16 +165,16 @@ class ConfigCompanion extends UpdateCompanion<Config> {
map['config_key'] = Variable<String>(configKey.value);
}
if (configValue.present) {
map['config_value'] = Variable<String?>(configValue.value);
map['config_value'] = Variable<String>(configValue.value);
}
if (syncState.present) {
final converter = ConfigTable.$converter0n;
map['sync_state'] = Variable<int?>(converter.toSql(syncState.value));
map['sync_state'] = Variable<int>(converter.toSql(syncState.value));
}
if (syncStateImplicit.present) {
final converter = ConfigTable.$converter1;
map['sync_state_implicit'] =
Variable<int?>(converter.toSql(syncStateImplicit.value));
Variable<int>(converter.toSql(syncStateImplicit.value));
}
return map;
}
@ -211,31 +197,31 @@ class ConfigTable extends Table with TableInfo<ConfigTable, Config> {
final String? _alias;
ConfigTable(this.attachedDatabase, [this._alias]);
final VerificationMeta _configKeyMeta = const VerificationMeta('configKey');
late final GeneratedColumn<String?> configKey = GeneratedColumn<String?>(
late final GeneratedColumn<String> configKey = GeneratedColumn<String>(
'config_key', aliasedName, false,
type: const StringType(),
type: DriftSqlType.string,
requiredDuringInsert: true,
$customConstraints: 'not null primary key');
final VerificationMeta _configValueMeta =
const VerificationMeta('configValue');
late final GeneratedColumn<String?> configValue = GeneratedColumn<String?>(
late final GeneratedColumn<String> configValue = GeneratedColumn<String>(
'config_value', aliasedName, true,
type: const StringType(),
type: DriftSqlType.string,
requiredDuringInsert: false,
$customConstraints: '');
final VerificationMeta _syncStateMeta = const VerificationMeta('syncState');
late final GeneratedColumnWithTypeConverter<SyncType?, int?> syncState =
GeneratedColumn<int?>('sync_state', aliasedName, true,
type: const IntType(),
late final GeneratedColumnWithTypeConverter<SyncType?, int> syncState =
GeneratedColumn<int>('sync_state', aliasedName, true,
type: DriftSqlType.int,
requiredDuringInsert: false,
$customConstraints: '')
.withConverter<SyncType?>(ConfigTable.$converter0n);
final VerificationMeta _syncStateImplicitMeta =
const VerificationMeta('syncStateImplicit');
late final GeneratedColumnWithTypeConverter<SyncType?, int?>
syncStateImplicit = GeneratedColumn<int?>(
late final GeneratedColumnWithTypeConverter<SyncType?, int>
syncStateImplicit = GeneratedColumn<int>(
'sync_state_implicit', aliasedName, true,
type: const IntType(),
type: DriftSqlType.int,
requiredDuringInsert: false,
$customConstraints: '')
.withConverter<SyncType?>(ConfigTable.$converter1);
@ -272,8 +258,18 @@ class ConfigTable extends Table with TableInfo<ConfigTable, Config> {
Set<GeneratedColumn> get $primaryKey => {configKey};
@override
Config map(Map<String, dynamic> data, {String? tablePrefix}) {
return Config.fromData(data,
prefix: tablePrefix != null ? '$tablePrefix.' : null);
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return Config(
configKey: attachedDatabase.options.types
.read(DriftSqlType.string, data['${effectivePrefix}config_key'])!,
configValue: attachedDatabase.options.types
.read(DriftSqlType.string, data['${effectivePrefix}config_value']),
syncState: ConfigTable.$converter0n.fromSql(attachedDatabase.options.types
.read(DriftSqlType.int, data['${effectivePrefix}sync_state'])),
syncStateImplicit: ConfigTable.$converter1.fromSql(
attachedDatabase.options.types.read(
DriftSqlType.int, data['${effectivePrefix}sync_state_implicit'])),
);
}
@override
@ -297,22 +293,14 @@ class WithDefault extends DataClass implements Insertable<WithDefault> {
final String? a;
final int? b;
WithDefault({this.a, this.b});
factory WithDefault.fromData(Map<String, dynamic> data, {String? prefix}) {
final effectivePrefix = prefix ?? '';
return WithDefault(
a: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}a']),
b: const IntType().mapFromDatabaseResponse(data['${effectivePrefix}b']),
);
}
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
if (!nullToAbsent || a != null) {
map['a'] = Variable<String?>(a);
map['a'] = Variable<String>(a);
}
if (!nullToAbsent || b != null) {
map['b'] = Variable<int?>(b);
map['b'] = Variable<int>(b);
}
return map;
}
@ -382,8 +370,8 @@ class WithDefaultsCompanion extends UpdateCompanion<WithDefault> {
this.b = const Value.absent(),
});
static Insertable<WithDefault> custom({
Expression<String?>? a,
Expression<int?>? b,
Expression<String>? a,
Expression<int>? b,
}) {
return RawValuesInsertable({
if (a != null) 'a': a,
@ -402,10 +390,10 @@ class WithDefaultsCompanion extends UpdateCompanion<WithDefault> {
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
if (a.present) {
map['a'] = Variable<String?>(a.value);
map['a'] = Variable<String>(a.value);
}
if (b.present) {
map['b'] = Variable<int?>(b.value);
map['b'] = Variable<int>(b.value);
}
return map;
}
@ -426,16 +414,16 @@ class WithDefaults extends Table with TableInfo<WithDefaults, WithDefault> {
final String? _alias;
WithDefaults(this.attachedDatabase, [this._alias]);
final VerificationMeta _aMeta = const VerificationMeta('a');
late final GeneratedColumn<String?> a = GeneratedColumn<String?>(
late final GeneratedColumn<String> a = GeneratedColumn<String>(
'a', aliasedName, true,
type: const StringType(),
type: DriftSqlType.string,
requiredDuringInsert: false,
$customConstraints: 'DEFAULT \'something\'',
defaultValue: const CustomExpression<String>('\'something\''));
final VerificationMeta _bMeta = const VerificationMeta('b');
late final GeneratedColumn<int?> b = GeneratedColumn<int?>(
late final GeneratedColumn<int> b = GeneratedColumn<int>(
'b', aliasedName, true,
type: const IntType(),
type: DriftSqlType.int,
requiredDuringInsert: false,
$customConstraints: 'UNIQUE');
@override
@ -462,8 +450,13 @@ class WithDefaults extends Table with TableInfo<WithDefaults, WithDefault> {
Set<GeneratedColumn> get $primaryKey => <GeneratedColumn>{};
@override
WithDefault map(Map<String, dynamic> data, {String? tablePrefix}) {
return WithDefault.fromData(data,
prefix: tablePrefix != null ? '$tablePrefix.' : null);
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return WithDefault(
a: attachedDatabase.options.types
.read(DriftSqlType.string, data['${effectivePrefix}a']),
b: attachedDatabase.options.types
.read(DriftSqlType.int, data['${effectivePrefix}b']),
);
}
@override
@ -521,9 +514,9 @@ class NoIds extends Table with TableInfo<NoIds, NoIdRow> {
final String? _alias;
NoIds(this.attachedDatabase, [this._alias]);
final VerificationMeta _payloadMeta = const VerificationMeta('payload');
late final GeneratedColumn<Uint8List?> payload = GeneratedColumn<Uint8List?>(
late final GeneratedColumn<Uint8List> payload = GeneratedColumn<Uint8List>(
'payload', aliasedName, false,
type: const BlobType(),
type: DriftSqlType.blob,
requiredDuringInsert: true,
$customConstraints: 'NOT NULL PRIMARY KEY');
@override
@ -552,8 +545,8 @@ class NoIds extends Table with TableInfo<NoIds, NoIdRow> {
NoIdRow map(Map<String, dynamic> data, {String? tablePrefix}) {
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return NoIdRow(
const BlobType()
.mapFromDatabaseResponse(data['${effectivePrefix}payload'])!,
attachedDatabase.options.types
.read(DriftSqlType.blob, data['${effectivePrefix}payload'])!,
);
}
@ -573,24 +566,15 @@ class WithConstraint extends DataClass implements Insertable<WithConstraint> {
final int b;
final double? c;
WithConstraint({this.a, required this.b, this.c});
factory WithConstraint.fromData(Map<String, dynamic> data, {String? prefix}) {
final effectivePrefix = prefix ?? '';
return WithConstraint(
a: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}a']),
b: const IntType().mapFromDatabaseResponse(data['${effectivePrefix}b'])!,
c: const RealType().mapFromDatabaseResponse(data['${effectivePrefix}c']),
);
}
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
if (!nullToAbsent || a != null) {
map['a'] = Variable<String?>(a);
map['a'] = Variable<String>(a);
}
map['b'] = Variable<int>(b);
if (!nullToAbsent || c != null) {
map['c'] = Variable<double?>(c);
map['c'] = Variable<double>(c);
}
return map;
}
@ -672,9 +656,9 @@ class WithConstraintsCompanion extends UpdateCompanion<WithConstraint> {
this.c = const Value.absent(),
}) : b = Value(b);
static Insertable<WithConstraint> custom({
Expression<String?>? a,
Expression<String>? a,
Expression<int>? b,
Expression<double?>? c,
Expression<double>? c,
}) {
return RawValuesInsertable({
if (a != null) 'a': a,
@ -696,13 +680,13 @@ class WithConstraintsCompanion extends UpdateCompanion<WithConstraint> {
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
if (a.present) {
map['a'] = Variable<String?>(a.value);
map['a'] = Variable<String>(a.value);
}
if (b.present) {
map['b'] = Variable<int>(b.value);
}
if (c.present) {
map['c'] = Variable<double?>(c.value);
map['c'] = Variable<double>(c.value);
}
return map;
}
@ -725,21 +709,21 @@ class WithConstraints extends Table
final String? _alias;
WithConstraints(this.attachedDatabase, [this._alias]);
final VerificationMeta _aMeta = const VerificationMeta('a');
late final GeneratedColumn<String?> a = GeneratedColumn<String?>(
late final GeneratedColumn<String> a = GeneratedColumn<String>(
'a', aliasedName, true,
type: const StringType(),
type: DriftSqlType.string,
requiredDuringInsert: false,
$customConstraints: '');
final VerificationMeta _bMeta = const VerificationMeta('b');
late final GeneratedColumn<int?> b = GeneratedColumn<int?>(
late final GeneratedColumn<int> b = GeneratedColumn<int>(
'b', aliasedName, false,
type: const IntType(),
type: DriftSqlType.int,
requiredDuringInsert: true,
$customConstraints: 'NOT NULL');
final VerificationMeta _cMeta = const VerificationMeta('c');
late final GeneratedColumn<double?> c = GeneratedColumn<double?>(
late final GeneratedColumn<double> c = GeneratedColumn<double>(
'c', aliasedName, true,
type: const RealType(),
type: DriftSqlType.double,
requiredDuringInsert: false,
$customConstraints: '');
@override
@ -771,8 +755,15 @@ class WithConstraints extends Table
Set<GeneratedColumn> get $primaryKey => <GeneratedColumn>{};
@override
WithConstraint map(Map<String, dynamic> data, {String? tablePrefix}) {
return WithConstraint.fromData(data,
prefix: tablePrefix != null ? '$tablePrefix.' : null);
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return WithConstraint(
a: attachedDatabase.options.types
.read(DriftSqlType.string, data['${effectivePrefix}a']),
b: attachedDatabase.options.types
.read(DriftSqlType.int, data['${effectivePrefix}b'])!,
c: attachedDatabase.options.types
.read(DriftSqlType.double, data['${effectivePrefix}c']),
);
}
@override
@ -794,31 +785,18 @@ class MytableData extends DataClass implements Insertable<MytableData> {
final DateTime? somedate;
MytableData(
{required this.someid, this.sometext, this.isInserting, this.somedate});
factory MytableData.fromData(Map<String, dynamic> data, {String? prefix}) {
final effectivePrefix = prefix ?? '';
return MytableData(
someid: const IntType()
.mapFromDatabaseResponse(data['${effectivePrefix}someid'])!,
sometext: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}sometext']),
isInserting: const BoolType()
.mapFromDatabaseResponse(data['${effectivePrefix}is_inserting']),
somedate: const DateTimeType()
.mapFromDatabaseResponse(data['${effectivePrefix}somedate']),
);
}
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
map['someid'] = Variable<int>(someid);
if (!nullToAbsent || sometext != null) {
map['sometext'] = Variable<String?>(sometext);
map['sometext'] = Variable<String>(sometext);
}
if (!nullToAbsent || isInserting != null) {
map['is_inserting'] = Variable<bool?>(isInserting);
map['is_inserting'] = Variable<bool>(isInserting);
}
if (!nullToAbsent || somedate != null) {
map['somedate'] = Variable<DateTime?>(somedate);
map['somedate'] = Variable<DateTime>(somedate);
}
return map;
}
@ -917,9 +895,9 @@ class MytableCompanion extends UpdateCompanion<MytableData> {
});
static Insertable<MytableData> custom({
Expression<int>? someid,
Expression<String?>? sometext,
Expression<bool?>? isInserting,
Expression<DateTime?>? somedate,
Expression<String>? sometext,
Expression<bool>? isInserting,
Expression<DateTime>? somedate,
}) {
return RawValuesInsertable({
if (someid != null) 'someid': someid,
@ -949,13 +927,13 @@ class MytableCompanion extends UpdateCompanion<MytableData> {
map['someid'] = Variable<int>(someid.value);
}
if (sometext.present) {
map['sometext'] = Variable<String?>(sometext.value);
map['sometext'] = Variable<String>(sometext.value);
}
if (isInserting.present) {
map['is_inserting'] = Variable<bool?>(isInserting.value);
map['is_inserting'] = Variable<bool>(isInserting.value);
}
if (somedate.present) {
map['somedate'] = Variable<DateTime?>(somedate.value);
map['somedate'] = Variable<DateTime>(somedate.value);
}
return map;
}
@ -978,28 +956,28 @@ class Mytable extends Table with TableInfo<Mytable, MytableData> {
final String? _alias;
Mytable(this.attachedDatabase, [this._alias]);
final VerificationMeta _someidMeta = const VerificationMeta('someid');
late final GeneratedColumn<int?> someid = GeneratedColumn<int?>(
late final GeneratedColumn<int> someid = GeneratedColumn<int>(
'someid', aliasedName, false,
type: const IntType(),
type: DriftSqlType.int,
requiredDuringInsert: false,
$customConstraints: 'NOT NULL');
final VerificationMeta _sometextMeta = const VerificationMeta('sometext');
late final GeneratedColumn<String?> sometext = GeneratedColumn<String?>(
late final GeneratedColumn<String> sometext = GeneratedColumn<String>(
'sometext', aliasedName, true,
type: const StringType(),
type: DriftSqlType.string,
requiredDuringInsert: false,
$customConstraints: '');
final VerificationMeta _isInsertingMeta =
const VerificationMeta('isInserting');
late final GeneratedColumn<bool?> isInserting = GeneratedColumn<bool?>(
late final GeneratedColumn<bool> isInserting = GeneratedColumn<bool>(
'is_inserting', aliasedName, true,
type: const BoolType(),
type: DriftSqlType.bool,
requiredDuringInsert: false,
$customConstraints: '');
final VerificationMeta _somedateMeta = const VerificationMeta('somedate');
late final GeneratedColumn<DateTime?> somedate = GeneratedColumn<DateTime?>(
late final GeneratedColumn<DateTime> somedate = GeneratedColumn<DateTime>(
'somedate', aliasedName, true,
type: const IntType(),
type: DriftSqlType.dateTime,
requiredDuringInsert: false,
$customConstraints: '');
@override
@ -1040,8 +1018,17 @@ class Mytable extends Table with TableInfo<Mytable, MytableData> {
Set<GeneratedColumn> get $primaryKey => {someid};
@override
MytableData map(Map<String, dynamic> data, {String? tablePrefix}) {
return MytableData.fromData(data,
prefix: tablePrefix != null ? '$tablePrefix.' : null);
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return MytableData(
someid: attachedDatabase.options.types
.read(DriftSqlType.int, data['${effectivePrefix}someid'])!,
sometext: attachedDatabase.options.types
.read(DriftSqlType.string, data['${effectivePrefix}sometext']),
isInserting: attachedDatabase.options.types
.read(DriftSqlType.bool, data['${effectivePrefix}is_inserting']),
somedate: attachedDatabase.options.types
.read(DriftSqlType.dateTime, data['${effectivePrefix}somedate']),
);
}
@override
@ -1060,17 +1047,6 @@ class EMail extends DataClass implements Insertable<EMail> {
final String title;
final String body;
EMail({required this.sender, required this.title, required this.body});
factory EMail.fromData(Map<String, dynamic> data, {String? prefix}) {
final effectivePrefix = prefix ?? '';
return EMail(
sender: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}sender'])!,
title: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}title'])!,
body: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}body'])!,
);
}
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
@ -1207,21 +1183,21 @@ class Email extends Table
final String? _alias;
Email(this.attachedDatabase, [this._alias]);
final VerificationMeta _senderMeta = const VerificationMeta('sender');
late final GeneratedColumn<String?> sender = GeneratedColumn<String?>(
late final GeneratedColumn<String> sender = GeneratedColumn<String>(
'sender', aliasedName, false,
type: const StringType(),
type: DriftSqlType.string,
requiredDuringInsert: true,
$customConstraints: '');
final VerificationMeta _titleMeta = const VerificationMeta('title');
late final GeneratedColumn<String?> title = GeneratedColumn<String?>(
late final GeneratedColumn<String> title = GeneratedColumn<String>(
'title', aliasedName, false,
type: const StringType(),
type: DriftSqlType.string,
requiredDuringInsert: true,
$customConstraints: '');
final VerificationMeta _bodyMeta = const VerificationMeta('body');
late final GeneratedColumn<String?> body = GeneratedColumn<String?>(
late final GeneratedColumn<String> body = GeneratedColumn<String>(
'body', aliasedName, false,
type: const StringType(),
type: DriftSqlType.string,
requiredDuringInsert: true,
$customConstraints: '');
@override
@ -1260,8 +1236,15 @@ class Email extends Table
Set<GeneratedColumn> get $primaryKey => <GeneratedColumn>{};
@override
EMail map(Map<String, dynamic> data, {String? tablePrefix}) {
return EMail.fromData(data,
prefix: tablePrefix != null ? '$tablePrefix.' : null);
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return EMail(
sender: attachedDatabase.options.types
.read(DriftSqlType.string, data['${effectivePrefix}sender'])!,
title: attachedDatabase.options.types
.read(DriftSqlType.string, data['${effectivePrefix}title'])!,
body: attachedDatabase.options.types
.read(DriftSqlType.string, data['${effectivePrefix}body'])!,
);
}
@override
@ -1279,15 +1262,6 @@ class WeirdData extends DataClass implements Insertable<WeirdData> {
final int sqlClass;
final String textColumn;
WeirdData({required this.sqlClass, required this.textColumn});
factory WeirdData.fromData(Map<String, dynamic> data, {String? prefix}) {
final effectivePrefix = prefix ?? '';
return WeirdData(
sqlClass: const IntType()
.mapFromDatabaseResponse(data['${effectivePrefix}class'])!,
textColumn: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}text'])!,
);
}
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
@ -1406,15 +1380,15 @@ class WeirdTable extends Table with TableInfo<WeirdTable, WeirdData> {
final String? _alias;
WeirdTable(this.attachedDatabase, [this._alias]);
final VerificationMeta _sqlClassMeta = const VerificationMeta('sqlClass');
late final GeneratedColumn<int?> sqlClass = GeneratedColumn<int?>(
late final GeneratedColumn<int> sqlClass = GeneratedColumn<int>(
'class', aliasedName, false,
type: const IntType(),
type: DriftSqlType.int,
requiredDuringInsert: true,
$customConstraints: 'NOT NULL');
final VerificationMeta _textColumnMeta = const VerificationMeta('textColumn');
late final GeneratedColumn<String?> textColumn = GeneratedColumn<String?>(
late final GeneratedColumn<String> textColumn = GeneratedColumn<String>(
'text', aliasedName, false,
type: const StringType(),
type: DriftSqlType.string,
requiredDuringInsert: true,
$customConstraints: 'NOT NULL');
@override
@ -1447,8 +1421,13 @@ class WeirdTable extends Table with TableInfo<WeirdTable, WeirdData> {
Set<GeneratedColumn> get $primaryKey => <GeneratedColumn>{};
@override
WeirdData map(Map<String, dynamic> data, {String? tablePrefix}) {
return WeirdData.fromData(data,
prefix: tablePrefix != null ? '$tablePrefix.' : null);
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return WeirdData(
sqlClass: attachedDatabase.options.types
.read(DriftSqlType.int, data['${effectivePrefix}class'])!,
textColumn: attachedDatabase.options.types
.read(DriftSqlType.string, data['${effectivePrefix}text'])!,
);
}
@override
@ -1470,20 +1449,6 @@ class MyViewData extends DataClass {
this.configValue,
this.syncState,
this.syncStateImplicit});
factory MyViewData.fromData(Map<String, dynamic> data, {String? prefix}) {
final effectivePrefix = prefix ?? '';
return MyViewData(
configKey: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}config_key'])!,
configValue: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}config_value']),
syncState: ConfigTable.$converter0n.fromSql(const IntType()
.mapFromDatabaseResponse(data['${effectivePrefix}sync_state'])),
syncStateImplicit: ConfigTable.$converter1.fromSql(const IntType()
.mapFromDatabaseResponse(
data['${effectivePrefix}sync_state_implicit'])),
);
}
factory MyViewData.fromJson(Map<String, dynamic> json,
{ValueSerializer? serializer}) {
serializer ??= driftRuntimeOptions.defaultSerializer;
@ -1567,24 +1532,34 @@ class MyView extends ViewInfo<MyView, MyViewData> implements HasResultSet {
MyView get asDslTable => this;
@override
MyViewData map(Map<String, dynamic> data, {String? tablePrefix}) {
return MyViewData.fromData(data,
prefix: tablePrefix != null ? '$tablePrefix.' : null);
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return MyViewData(
configKey: attachedDatabase.options.types
.read(DriftSqlType.string, data['${effectivePrefix}config_key'])!,
configValue: attachedDatabase.options.types
.read(DriftSqlType.string, data['${effectivePrefix}config_value']),
syncState: ConfigTable.$converter0n.fromSql(attachedDatabase.options.types
.read(DriftSqlType.int, data['${effectivePrefix}sync_state'])),
syncStateImplicit: ConfigTable.$converter1.fromSql(
attachedDatabase.options.types.read(
DriftSqlType.int, data['${effectivePrefix}sync_state_implicit'])),
);
}
late final GeneratedColumn<String?> configKey = GeneratedColumn<String?>(
late final GeneratedColumn<String> configKey = GeneratedColumn<String>(
'config_key', aliasedName, false,
type: const StringType());
late final GeneratedColumn<String?> configValue = GeneratedColumn<String?>(
type: DriftSqlType.string);
late final GeneratedColumn<String> configValue = GeneratedColumn<String>(
'config_value', aliasedName, true,
type: const StringType());
late final GeneratedColumnWithTypeConverter<SyncType?, int?> syncState =
GeneratedColumn<int?>('sync_state', aliasedName, true,
type: const IntType())
type: DriftSqlType.string);
late final GeneratedColumnWithTypeConverter<SyncType?, int> syncState =
GeneratedColumn<int>('sync_state', aliasedName, true,
type: DriftSqlType.int)
.withConverter<SyncType?>(ConfigTable.$converter0n);
late final GeneratedColumnWithTypeConverter<SyncType?, int?>
syncStateImplicit = GeneratedColumn<int?>(
late final GeneratedColumnWithTypeConverter<SyncType?, int>
syncStateImplicit = GeneratedColumn<int>(
'sync_state_implicit', aliasedName, true,
type: const IntType())
type: DriftSqlType.int)
.withConverter<SyncType?>(ConfigTable.$converter1);
@override
MyView createAlias(String alias) {
@ -1598,7 +1573,7 @@ class MyView extends ViewInfo<MyView, MyViewData> implements HasResultSet {
}
abstract class _$CustomTablesDb extends GeneratedDatabase {
_$CustomTablesDb(QueryExecutor e) : super(SqlTypeSystem.defaultInstance, e);
_$CustomTablesDb(QueryExecutor e) : super(e);
_$CustomTablesDb.connect(DatabaseConnection c) : super.connect(c);
late final ConfigTable config = ConfigTable(this);
late final Index valueIdx = Index('value_idx',
@ -1650,7 +1625,7 @@ abstract class _$CustomTablesDb extends GeneratedDatabase {
}
Selectable<Config> readDynamic(
{Expression<bool?> Function(ConfigTable config) predicate =
{Expression<bool> Function(ConfigTable config) predicate =
_$moor$default$1}) {
var $arrayStartIndex = 1;
final generatedpredicate =
@ -1667,8 +1642,7 @@ abstract class _$CustomTablesDb extends GeneratedDatabase {
}
Selectable<String> typeConverterVar(SyncType? var1, List<SyncType?> var2,
{Expression<bool?> Function(ConfigTable config) pred =
_$moor$default$2}) {
{Expression<bool> Function(ConfigTable config) pred = _$moor$default$2}) {
var $arrayStartIndex = 2;
final generatedpred =
$write(pred(this.config), startIndex: $arrayStartIndex);
@ -1678,10 +1652,10 @@ abstract class _$CustomTablesDb extends GeneratedDatabase {
return customSelect(
'SELECT config_key FROM config WHERE ${generatedpred.sql} AND(sync_state = ?1 OR sync_state_implicit IN ($expandedvar2))',
variables: [
Variable<int?>(
Variable<int>(
NullAwareTypeConverter.wrapToSql(ConfigTable.$converter0, var1)),
...generatedpred.introducedVariables,
for (var $ in var2) Variable<int?>(ConfigTable.$converter1.toSql($))
for (var $ in var2) Variable<int>(ConfigTable.$converter1.toSql($))
],
readsFrom: {
config,
@ -1718,7 +1692,7 @@ abstract class _$CustomTablesDb extends GeneratedDatabase {
}
Selectable<MultipleResult> multiple(
{required Expression<bool?> Function(WithDefaults d, WithConstraints c)
{required Expression<bool> Function(WithDefaults d, WithConstraints c)
predicate}) {
var $arrayStartIndex = 1;
final generatedpredicate = $write(
@ -1750,7 +1724,7 @@ abstract class _$CustomTablesDb extends GeneratedDatabase {
return customSelect(
'SELECT * FROM email WHERE email MATCH ?1 ORDER BY rank',
variables: [
Variable<String?>(term)
Variable<String>(term)
],
readsFrom: {
email,
@ -1758,7 +1732,7 @@ abstract class _$CustomTablesDb extends GeneratedDatabase {
}
Selectable<ReadRowIdResult> readRowId(
{required Expression<int?> Function(ConfigTable config) expr}) {
{required Expression<int> Function(ConfigTable config) expr}) {
var $arrayStartIndex = 1;
final generatedexpr =
$write(expr(this.config), startIndex: $arrayStartIndex);
@ -1821,7 +1795,7 @@ abstract class _$CustomTablesDb extends GeneratedDatabase {
return customSelect(
'SELECT"defaults"."a" AS "nested_0.a", "defaults"."b" AS "nested_0.b", defaults.b AS "\$n_0" FROM with_defaults AS defaults WHERE a = ?1',
variables: [
Variable<String?>(var1)
Variable<String>(var1)
],
readsFrom: {
withConstraints,
@ -1846,7 +1820,7 @@ abstract class _$CustomTablesDb extends GeneratedDatabase {
Future<int> writeConfig({required String key, String? value}) {
return customInsert(
'REPLACE INTO config (config_key, config_value) VALUES (?1, ?2)',
variables: [Variable<String>(key), Variable<String?>(value)],
variables: [Variable<String>(key), Variable<String>(value)],
updates: {config},
);
}
@ -1883,9 +1857,9 @@ abstract class _$CustomTablesDb extends GeneratedDatabase {
}
OrderBy _$moor$default$0(ConfigTable _) => const OrderBy.nothing();
Expression<bool?> _$moor$default$1(ConfigTable _) =>
Expression<bool> _$moor$default$1(ConfigTable _) =>
const CustomExpression('(TRUE)');
Expression<bool?> _$moor$default$2(ConfigTable _) =>
Expression<bool> _$moor$default$2(ConfigTable _) =>
const CustomExpression('(TRUE)');
class JsonResult extends CustomResultSet {

View File

@ -17,19 +17,6 @@ class Category extends DataClass implements Insertable<Category> {
required this.description,
required this.priority,
required this.descriptionInUpperCase});
factory Category.fromData(Map<String, dynamic> data, {String? prefix}) {
final effectivePrefix = prefix ?? '';
return Category(
id: const IntType()
.mapFromDatabaseResponse(data['${effectivePrefix}id'])!,
description: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}desc'])!,
priority: $CategoriesTable.$converter0.fromSql(const IntType()
.mapFromDatabaseResponse(data['${effectivePrefix}priority'])!),
descriptionInUpperCase: const StringType().mapFromDatabaseResponse(
data['${effectivePrefix}description_in_upper_case'])!,
);
}
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
@ -131,7 +118,7 @@ class CategoriesCompanion extends UpdateCompanion<Category> {
static Insertable<Category> custom({
Expression<int>? id,
Expression<String>? description,
Expression<CategoryPriority>? priority,
Expression<int>? priority,
}) {
return RawValuesInsertable({
if (id != null) 'id': id,
@ -186,33 +173,33 @@ class $CategoriesTable extends Categories
$CategoriesTable(this.attachedDatabase, [this._alias]);
final VerificationMeta _idMeta = const VerificationMeta('id');
@override
late final GeneratedColumn<int?> id = GeneratedColumn<int?>(
late final GeneratedColumn<int> id = GeneratedColumn<int>(
'id', aliasedName, false,
type: const IntType(),
type: DriftSqlType.int,
requiredDuringInsert: false,
defaultConstraints: 'PRIMARY KEY AUTOINCREMENT');
final VerificationMeta _descriptionMeta =
const VerificationMeta('description');
@override
late final GeneratedColumn<String?> description = GeneratedColumn<String?>(
late final GeneratedColumn<String> description = GeneratedColumn<String>(
'desc', aliasedName, false,
type: const StringType(),
type: DriftSqlType.string,
requiredDuringInsert: true,
$customConstraints: 'NOT NULL UNIQUE');
final VerificationMeta _priorityMeta = const VerificationMeta('priority');
@override
late final GeneratedColumnWithTypeConverter<CategoryPriority, int?> priority =
GeneratedColumn<int?>('priority', aliasedName, false,
type: const IntType(),
late final GeneratedColumnWithTypeConverter<CategoryPriority, int> priority =
GeneratedColumn<int>('priority', aliasedName, false,
type: DriftSqlType.int,
requiredDuringInsert: false,
defaultValue: const Constant(0))
.withConverter<CategoryPriority>($CategoriesTable.$converter0);
final VerificationMeta _descriptionInUpperCaseMeta =
const VerificationMeta('descriptionInUpperCase');
@override
late final GeneratedColumn<String?> descriptionInUpperCase =
GeneratedColumn<String?>('description_in_upper_case', aliasedName, false,
type: const StringType(),
late final GeneratedColumn<String> descriptionInUpperCase =
GeneratedColumn<String>('description_in_upper_case', aliasedName, false,
type: DriftSqlType.string,
requiredDuringInsert: false,
generatedAs: GeneratedAs(description.upper(), false));
@override
@ -250,8 +237,19 @@ class $CategoriesTable extends Categories
Set<GeneratedColumn> get $primaryKey => {id};
@override
Category map(Map<String, dynamic> data, {String? tablePrefix}) {
return Category.fromData(data,
prefix: tablePrefix != null ? '$tablePrefix.' : null);
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return Category(
id: attachedDatabase.options.types
.read(DriftSqlType.int, data['${effectivePrefix}id'])!,
description: attachedDatabase.options.types
.read(DriftSqlType.string, data['${effectivePrefix}desc'])!,
priority: $CategoriesTable.$converter0.fromSql(attachedDatabase
.options.types
.read(DriftSqlType.int, data['${effectivePrefix}priority'])!),
descriptionInUpperCase: attachedDatabase.options.types.read(
DriftSqlType.string,
data['${effectivePrefix}description_in_upper_case'])!,
);
}
@override
@ -275,34 +273,19 @@ class TodoEntry extends DataClass implements Insertable<TodoEntry> {
required this.content,
this.targetDate,
this.category});
factory TodoEntry.fromData(Map<String, dynamic> data, {String? prefix}) {
final effectivePrefix = prefix ?? '';
return TodoEntry(
id: const IntType()
.mapFromDatabaseResponse(data['${effectivePrefix}id'])!,
title: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}title']),
content: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}content'])!,
targetDate: const DateTimeType()
.mapFromDatabaseResponse(data['${effectivePrefix}target_date']),
category: const IntType()
.mapFromDatabaseResponse(data['${effectivePrefix}category']),
);
}
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
map['id'] = Variable<int>(id);
if (!nullToAbsent || title != null) {
map['title'] = Variable<String?>(title);
map['title'] = Variable<String>(title);
}
map['content'] = Variable<String>(content);
if (!nullToAbsent || targetDate != null) {
map['target_date'] = Variable<DateTime?>(targetDate);
map['target_date'] = Variable<DateTime>(targetDate);
}
if (!nullToAbsent || category != null) {
map['category'] = Variable<int?>(category);
map['category'] = Variable<int>(category);
}
return map;
}
@ -410,10 +393,10 @@ class TodosTableCompanion extends UpdateCompanion<TodoEntry> {
}) : content = Value(content);
static Insertable<TodoEntry> custom({
Expression<int>? id,
Expression<String?>? title,
Expression<String>? title,
Expression<String>? content,
Expression<DateTime?>? targetDate,
Expression<int?>? category,
Expression<DateTime>? targetDate,
Expression<int>? category,
}) {
return RawValuesInsertable({
if (id != null) 'id': id,
@ -446,16 +429,16 @@ class TodosTableCompanion extends UpdateCompanion<TodoEntry> {
map['id'] = Variable<int>(id.value);
}
if (title.present) {
map['title'] = Variable<String?>(title.value);
map['title'] = Variable<String>(title.value);
}
if (content.present) {
map['content'] = Variable<String>(content.value);
}
if (targetDate.present) {
map['target_date'] = Variable<DateTime?>(targetDate.value);
map['target_date'] = Variable<DateTime>(targetDate.value);
}
if (category.present) {
map['category'] = Variable<int?>(category.value);
map['category'] = Variable<int>(category.value);
}
return map;
}
@ -481,36 +464,36 @@ class $TodosTableTable extends TodosTable
$TodosTableTable(this.attachedDatabase, [this._alias]);
final VerificationMeta _idMeta = const VerificationMeta('id');
@override
late final GeneratedColumn<int?> id = GeneratedColumn<int?>(
late final GeneratedColumn<int> id = GeneratedColumn<int>(
'id', aliasedName, false,
type: const IntType(),
type: DriftSqlType.int,
requiredDuringInsert: false,
defaultConstraints: 'PRIMARY KEY AUTOINCREMENT');
final VerificationMeta _titleMeta = const VerificationMeta('title');
@override
late final GeneratedColumn<String?> title = GeneratedColumn<String?>(
late final GeneratedColumn<String> title = GeneratedColumn<String>(
'title', aliasedName, true,
additionalChecks:
GeneratedColumn.checkTextLength(minTextLength: 4, maxTextLength: 16),
type: const StringType(),
type: DriftSqlType.string,
requiredDuringInsert: false);
final VerificationMeta _contentMeta = const VerificationMeta('content');
@override
late final GeneratedColumn<String?> content = GeneratedColumn<String?>(
late final GeneratedColumn<String> content = GeneratedColumn<String>(
'content', aliasedName, false,
type: const StringType(), requiredDuringInsert: true);
type: DriftSqlType.string, requiredDuringInsert: true);
final VerificationMeta _targetDateMeta = const VerificationMeta('targetDate');
@override
late final GeneratedColumn<DateTime?> targetDate = GeneratedColumn<DateTime?>(
late final GeneratedColumn<DateTime> targetDate = GeneratedColumn<DateTime>(
'target_date', aliasedName, true,
type: const IntType(),
type: DriftSqlType.dateTime,
requiredDuringInsert: false,
defaultConstraints: 'UNIQUE');
final VerificationMeta _categoryMeta = const VerificationMeta('category');
@override
late final GeneratedColumn<int?> category = GeneratedColumn<int?>(
late final GeneratedColumn<int> category = GeneratedColumn<int>(
'category', aliasedName, true,
type: const IntType(),
type: DriftSqlType.int,
requiredDuringInsert: false,
defaultConstraints: 'REFERENCES categories (id)');
@override
@ -560,8 +543,19 @@ class $TodosTableTable extends TodosTable
];
@override
TodoEntry map(Map<String, dynamic> data, {String? tablePrefix}) {
return TodoEntry.fromData(data,
prefix: tablePrefix != null ? '$tablePrefix.' : null);
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return TodoEntry(
id: attachedDatabase.options.types
.read(DriftSqlType.int, data['${effectivePrefix}id'])!,
title: attachedDatabase.options.types
.read(DriftSqlType.string, data['${effectivePrefix}title']),
content: attachedDatabase.options.types
.read(DriftSqlType.string, data['${effectivePrefix}content'])!,
targetDate: attachedDatabase.options.types
.read(DriftSqlType.dateTime, data['${effectivePrefix}target_date']),
category: attachedDatabase.options.types
.read(DriftSqlType.int, data['${effectivePrefix}category']),
);
}
@override
@ -582,21 +576,6 @@ class User extends DataClass implements Insertable<User> {
required this.isAwesome,
required this.profilePicture,
required this.creationTime});
factory User.fromData(Map<String, dynamic> data, {String? prefix}) {
final effectivePrefix = prefix ?? '';
return User(
id: const IntType()
.mapFromDatabaseResponse(data['${effectivePrefix}id'])!,
name: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}name'])!,
isAwesome: const BoolType()
.mapFromDatabaseResponse(data['${effectivePrefix}is_awesome'])!,
profilePicture: const BlobType()
.mapFromDatabaseResponse(data['${effectivePrefix}profile_picture'])!,
creationTime: const DateTimeType()
.mapFromDatabaseResponse(data['${effectivePrefix}creation_time'])!,
);
}
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
@ -777,43 +756,43 @@ class $UsersTable extends Users with TableInfo<$UsersTable, User> {
$UsersTable(this.attachedDatabase, [this._alias]);
final VerificationMeta _idMeta = const VerificationMeta('id');
@override
late final GeneratedColumn<int?> id = GeneratedColumn<int?>(
late final GeneratedColumn<int> id = GeneratedColumn<int>(
'id', aliasedName, false,
type: const IntType(),
type: DriftSqlType.int,
requiredDuringInsert: false,
defaultConstraints: 'PRIMARY KEY AUTOINCREMENT');
final VerificationMeta _nameMeta = const VerificationMeta('name');
@override
late final GeneratedColumn<String?> name = GeneratedColumn<String?>(
late final GeneratedColumn<String> name = GeneratedColumn<String>(
'name', aliasedName, false,
additionalChecks:
GeneratedColumn.checkTextLength(minTextLength: 6, maxTextLength: 32),
type: const StringType(),
type: DriftSqlType.string,
requiredDuringInsert: true,
defaultConstraints: 'UNIQUE');
final VerificationMeta _isAwesomeMeta = const VerificationMeta('isAwesome');
@override
late final GeneratedColumn<bool?> isAwesome = GeneratedColumn<bool?>(
late final GeneratedColumn<bool> isAwesome = GeneratedColumn<bool>(
'is_awesome', aliasedName, false,
type: const BoolType(),
type: DriftSqlType.bool,
requiredDuringInsert: false,
defaultConstraints: 'CHECK (is_awesome IN (0, 1))',
defaultValue: const Constant(true));
final VerificationMeta _profilePictureMeta =
const VerificationMeta('profilePicture');
@override
late final GeneratedColumn<Uint8List?> profilePicture =
GeneratedColumn<Uint8List?>('profile_picture', aliasedName, false,
type: const BlobType(), requiredDuringInsert: true);
late final GeneratedColumn<Uint8List> profilePicture =
GeneratedColumn<Uint8List>('profile_picture', aliasedName, false,
type: DriftSqlType.blob, requiredDuringInsert: true);
final VerificationMeta _creationTimeMeta =
const VerificationMeta('creationTime');
@override
late final GeneratedColumn<DateTime?> creationTime =
GeneratedColumn<DateTime?>('creation_time', aliasedName, false,
check: () => creationTime.isBiggerThan(Constant(DateTime.utc(1950))),
type: const IntType(),
requiredDuringInsert: false,
defaultValue: currentDateAndTime);
late final GeneratedColumn<DateTime> creationTime = GeneratedColumn<DateTime>(
'creation_time', aliasedName, false,
check: () => creationTime.isBiggerThan(Constant(DateTime.utc(1950))),
type: DriftSqlType.dateTime,
requiredDuringInsert: false,
defaultValue: currentDateAndTime);
@override
List<GeneratedColumn> get $columns =>
[id, name, isAwesome, profilePicture, creationTime];
@ -860,8 +839,19 @@ class $UsersTable extends Users with TableInfo<$UsersTable, User> {
Set<GeneratedColumn> get $primaryKey => {id};
@override
User map(Map<String, dynamic> data, {String? tablePrefix}) {
return User.fromData(data,
prefix: tablePrefix != null ? '$tablePrefix.' : null);
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return User(
id: attachedDatabase.options.types
.read(DriftSqlType.int, data['${effectivePrefix}id'])!,
name: attachedDatabase.options.types
.read(DriftSqlType.string, data['${effectivePrefix}name'])!,
isAwesome: attachedDatabase.options.types
.read(DriftSqlType.bool, data['${effectivePrefix}is_awesome'])!,
profilePicture: attachedDatabase.options.types
.read(DriftSqlType.blob, data['${effectivePrefix}profile_picture'])!,
creationTime: attachedDatabase.options.types.read(
DriftSqlType.dateTime, data['${effectivePrefix}creation_time'])!,
);
}
@override
@ -874,15 +864,6 @@ class SharedTodo extends DataClass implements Insertable<SharedTodo> {
final int todo;
final int user;
SharedTodo({required this.todo, required this.user});
factory SharedTodo.fromData(Map<String, dynamic> data, {String? prefix}) {
final effectivePrefix = prefix ?? '';
return SharedTodo(
todo: const IntType()
.mapFromDatabaseResponse(data['${effectivePrefix}todo'])!,
user: const IntType()
.mapFromDatabaseResponse(data['${effectivePrefix}user'])!,
);
}
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
@ -1002,14 +983,14 @@ class $SharedTodosTable extends SharedTodos
$SharedTodosTable(this.attachedDatabase, [this._alias]);
final VerificationMeta _todoMeta = const VerificationMeta('todo');
@override
late final GeneratedColumn<int?> todo = GeneratedColumn<int?>(
late final GeneratedColumn<int> todo = GeneratedColumn<int>(
'todo', aliasedName, false,
type: const IntType(), requiredDuringInsert: true);
type: DriftSqlType.int, requiredDuringInsert: true);
final VerificationMeta _userMeta = const VerificationMeta('user');
@override
late final GeneratedColumn<int?> user = GeneratedColumn<int?>(
late final GeneratedColumn<int> user = GeneratedColumn<int>(
'user', aliasedName, false,
type: const IntType(), requiredDuringInsert: true);
type: DriftSqlType.int, requiredDuringInsert: true);
@override
List<GeneratedColumn> get $columns => [todo, user];
@override
@ -1040,8 +1021,13 @@ class $SharedTodosTable extends SharedTodos
Set<GeneratedColumn> get $primaryKey => {todo, user};
@override
SharedTodo map(Map<String, dynamic> data, {String? tablePrefix}) {
return SharedTodo.fromData(data,
prefix: tablePrefix != null ? '$tablePrefix.' : null);
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return SharedTodo(
todo: attachedDatabase.options.types
.read(DriftSqlType.int, data['${effectivePrefix}todo'])!,
user: attachedDatabase.options.types
.read(DriftSqlType.int, data['${effectivePrefix}user'])!,
);
}
@override
@ -1071,8 +1057,8 @@ class TableWithoutPKCompanion extends UpdateCompanion<CustomRowClass> {
static Insertable<CustomRowClass> createCustom({
Expression<int>? notReallyAnId,
Expression<double>? someFloat,
Expression<BigInt?>? webSafeInt,
Expression<MyCustomObject>? custom,
Expression<BigInt>? webSafeInt,
Expression<String>? custom,
}) {
return RawValuesInsertable({
if (notReallyAnId != null) 'not_really_an_id': notReallyAnId,
@ -1105,7 +1091,7 @@ class TableWithoutPKCompanion extends UpdateCompanion<CustomRowClass> {
map['some_float'] = Variable<double>(someFloat.value);
}
if (webSafeInt.present) {
map['web_safe_int'] = Variable<BigInt?>(webSafeInt.value);
map['web_safe_int'] = Variable<BigInt>(webSafeInt.value);
}
if (custom.present) {
final converter = $TableWithoutPKTable.$converter0;
@ -1157,24 +1143,24 @@ class $TableWithoutPKTable extends TableWithoutPK
final VerificationMeta _notReallyAnIdMeta =
const VerificationMeta('notReallyAnId');
@override
late final GeneratedColumn<int?> notReallyAnId = GeneratedColumn<int?>(
late final GeneratedColumn<int> notReallyAnId = GeneratedColumn<int>(
'not_really_an_id', aliasedName, false,
type: const IntType(), requiredDuringInsert: true);
type: DriftSqlType.int, requiredDuringInsert: true);
final VerificationMeta _someFloatMeta = const VerificationMeta('someFloat');
@override
late final GeneratedColumn<double?> someFloat = GeneratedColumn<double?>(
late final GeneratedColumn<double> someFloat = GeneratedColumn<double>(
'some_float', aliasedName, false,
type: const RealType(), requiredDuringInsert: true);
type: DriftSqlType.double, requiredDuringInsert: true);
final VerificationMeta _webSafeIntMeta = const VerificationMeta('webSafeInt');
@override
late final GeneratedColumn<BigInt?> webSafeInt = GeneratedColumn<BigInt?>(
late final GeneratedColumn<BigInt> webSafeInt = GeneratedColumn<BigInt>(
'web_safe_int', aliasedName, true,
type: const BigIntType(), requiredDuringInsert: false);
type: DriftSqlType.bigInt, requiredDuringInsert: false);
final VerificationMeta _customMeta = const VerificationMeta('custom');
@override
late final GeneratedColumnWithTypeConverter<MyCustomObject, String?> custom =
GeneratedColumn<String?>('custom', aliasedName, false,
type: const StringType(),
late final GeneratedColumnWithTypeConverter<MyCustomObject, String> custom =
GeneratedColumn<String>('custom', aliasedName, false,
type: DriftSqlType.string,
requiredDuringInsert: false,
clientDefault: _uuid.v4)
.withConverter<MyCustomObject>($TableWithoutPKTable.$converter0);
@ -1220,14 +1206,15 @@ class $TableWithoutPKTable extends TableWithoutPK
CustomRowClass map(Map<String, dynamic> data, {String? tablePrefix}) {
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return CustomRowClass.map(
const IntType()
.mapFromDatabaseResponse(data['${effectivePrefix}not_really_an_id'])!,
const RealType()
.mapFromDatabaseResponse(data['${effectivePrefix}some_float'])!,
custom: $TableWithoutPKTable.$converter0.fromSql(const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}custom'])!),
webSafeInt: const BigIntType()
.mapFromDatabaseResponse(data['${effectivePrefix}web_safe_int']),
attachedDatabase.options.types
.read(DriftSqlType.int, data['${effectivePrefix}not_really_an_id'])!,
attachedDatabase.options.types
.read(DriftSqlType.double, data['${effectivePrefix}some_float'])!,
custom: $TableWithoutPKTable.$converter0.fromSql(attachedDatabase
.options.types
.read(DriftSqlType.string, data['${effectivePrefix}custom'])!),
webSafeInt: attachedDatabase.options.types
.read(DriftSqlType.bigInt, data['${effectivePrefix}web_safe_int']),
);
}
@ -1243,19 +1230,12 @@ class $TableWithoutPKTable extends TableWithoutPK
class PureDefault extends DataClass implements Insertable<PureDefault> {
final MyCustomObject? txt;
PureDefault({this.txt});
factory PureDefault.fromData(Map<String, dynamic> data, {String? prefix}) {
final effectivePrefix = prefix ?? '';
return PureDefault(
txt: $PureDefaultsTable.$converter0n.fromSql(const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}insert'])),
);
}
@override
Map<String, Expression> toColumns(bool nullToAbsent) {
final map = <String, Expression>{};
if (!nullToAbsent || txt != null) {
final converter = $PureDefaultsTable.$converter0n;
map['insert'] = Variable<String?>(converter.toSql(txt));
map['insert'] = Variable<String>(converter.toSql(txt));
}
return map;
}
@ -1271,7 +1251,7 @@ class PureDefault extends DataClass implements Insertable<PureDefault> {
serializer ??= driftRuntimeOptions.defaultSerializer;
return PureDefault(
txt: $PureDefaultsTable.$converter0n
.fromJson(serializer.fromJson<String?>(json['txt'])),
.fromJson(serializer.fromJson<String>(json['txt'])),
);
}
factory PureDefault.fromJsonString(String encodedJson,
@ -1316,7 +1296,7 @@ class PureDefaultsCompanion extends UpdateCompanion<PureDefault> {
this.txt = const Value.absent(),
});
static Insertable<PureDefault> custom({
Expression<MyCustomObject?>? txt,
Expression<String>? txt,
}) {
return RawValuesInsertable({
if (txt != null) 'insert': txt,
@ -1334,7 +1314,7 @@ class PureDefaultsCompanion extends UpdateCompanion<PureDefault> {
final map = <String, Expression>{};
if (txt.present) {
final converter = $PureDefaultsTable.$converter0n;
map['insert'] = Variable<String?>(converter.toSql(txt.value));
map['insert'] = Variable<String>(converter.toSql(txt.value));
}
return map;
}
@ -1356,9 +1336,9 @@ class $PureDefaultsTable extends PureDefaults
$PureDefaultsTable(this.attachedDatabase, [this._alias]);
final VerificationMeta _txtMeta = const VerificationMeta('txt');
@override
late final GeneratedColumnWithTypeConverter<MyCustomObject?, String?> txt =
GeneratedColumn<String?>('insert', aliasedName, true,
type: const StringType(), requiredDuringInsert: false)
late final GeneratedColumnWithTypeConverter<MyCustomObject?, String> txt =
GeneratedColumn<String>('insert', aliasedName, true,
type: DriftSqlType.string, requiredDuringInsert: false)
.withConverter<MyCustomObject?>($PureDefaultsTable.$converter0n);
@override
List<GeneratedColumn> get $columns => [txt];
@ -1379,8 +1359,12 @@ class $PureDefaultsTable extends PureDefaults
Set<GeneratedColumn> get $primaryKey => {txt};
@override
PureDefault map(Map<String, dynamic> data, {String? tablePrefix}) {
return PureDefault.fromData(data,
prefix: tablePrefix != null ? '$tablePrefix.' : null);
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return PureDefault(
txt: $PureDefaultsTable.$converter0n.fromSql(attachedDatabase
.options.types
.read(DriftSqlType.string, data['${effectivePrefix}insert'])),
);
}
@override
@ -1399,16 +1383,6 @@ class CategoryTodoCountViewData extends DataClass {
final int itemCount;
CategoryTodoCountViewData(
{required this.description, required this.itemCount});
factory CategoryTodoCountViewData.fromData(Map<String, dynamic> data,
{String? prefix}) {
final effectivePrefix = prefix ?? '';
return CategoryTodoCountViewData(
description: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}description'])!,
itemCount: const IntType()
.mapFromDatabaseResponse(data['${effectivePrefix}item_count'])!,
);
}
factory CategoryTodoCountViewData.fromJson(Map<String, dynamic> json,
{ValueSerializer? serializer}) {
serializer ??= driftRuntimeOptions.defaultSerializer;
@ -1478,18 +1452,24 @@ class $CategoryTodoCountViewView
@override
CategoryTodoCountViewData map(Map<String, dynamic> data,
{String? tablePrefix}) {
return CategoryTodoCountViewData.fromData(data,
prefix: tablePrefix != null ? '$tablePrefix.' : null);
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return CategoryTodoCountViewData(
description: attachedDatabase.options.types
.read(DriftSqlType.string, data['${effectivePrefix}description'])!,
itemCount: attachedDatabase.options.types
.read(DriftSqlType.int, data['${effectivePrefix}item_count'])!,
);
}
late final GeneratedColumn<String?> description = GeneratedColumn<String?>(
late final GeneratedColumn<String> description = GeneratedColumn<String>(
'description', aliasedName, false,
type: const StringType(),
type: DriftSqlType.string,
generatedAs:
GeneratedAs(categories.description + const Variable('!'), false));
late final GeneratedColumn<int?> itemCount = GeneratedColumn<int?>(
late final GeneratedColumn<int> itemCount = GeneratedColumn<int>(
'item_count', aliasedName, false,
type: const IntType(), generatedAs: GeneratedAs(todos.id.count(), false));
type: DriftSqlType.int,
generatedAs: GeneratedAs(todos.id.count(), false));
@override
$CategoryTodoCountViewView createAlias(String alias) {
return $CategoryTodoCountViewView(attachedDatabase, alias);
@ -1509,16 +1489,6 @@ class TodoWithCategoryViewData extends DataClass {
final String? title;
final String description;
TodoWithCategoryViewData({this.title, required this.description});
factory TodoWithCategoryViewData.fromData(Map<String, dynamic> data,
{String? prefix}) {
final effectivePrefix = prefix ?? '';
return TodoWithCategoryViewData(
title: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}title']),
description: const StringType()
.mapFromDatabaseResponse(data['${effectivePrefix}desc'])!,
);
}
factory TodoWithCategoryViewData.fromJson(Map<String, dynamic> json,
{ValueSerializer? serializer}) {
serializer ??= driftRuntimeOptions.defaultSerializer;
@ -1589,16 +1559,21 @@ class $TodoWithCategoryViewView
@override
TodoWithCategoryViewData map(Map<String, dynamic> data,
{String? tablePrefix}) {
return TodoWithCategoryViewData.fromData(data,
prefix: tablePrefix != null ? '$tablePrefix.' : null);
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return TodoWithCategoryViewData(
title: attachedDatabase.options.types
.read(DriftSqlType.string, data['${effectivePrefix}title']),
description: attachedDatabase.options.types
.read(DriftSqlType.string, data['${effectivePrefix}desc'])!,
);
}
late final GeneratedColumn<String?> title = GeneratedColumn<String?>(
late final GeneratedColumn<String> title = GeneratedColumn<String>(
'title', aliasedName, false,
type: const StringType());
late final GeneratedColumn<String?> description = GeneratedColumn<String?>(
type: DriftSqlType.string);
late final GeneratedColumn<String> description = GeneratedColumn<String>(
'desc', aliasedName, false,
type: const StringType());
type: DriftSqlType.string);
@override
$TodoWithCategoryViewView createAlias(String alias) {
return $TodoWithCategoryViewView(attachedDatabase, alias);
@ -1614,7 +1589,7 @@ class $TodoWithCategoryViewView
}
abstract class _$TodoDb extends GeneratedDatabase {
_$TodoDb(QueryExecutor e) : super(SqlTypeSystem.defaultInstance, e);
_$TodoDb(QueryExecutor e) : super(e);
_$TodoDb.connect(DatabaseConnection c) : super.connect(c);
late final $CategoriesTable categories = $CategoriesTable(this);
late final $TodosTableTable todosTable = $TodosTableTable(this);
@ -1664,8 +1639,8 @@ abstract class _$TodoDb extends GeneratedDatabase {
return customSelect(
'SELECT * FROM todos WHERE title = ?2 OR id IN ($expandedvar3) OR title = ?1',
variables: [
Variable<String?>(var1),
Variable<String?>(var2),
Variable<String>(var1),
Variable<String>(var2),
for (var $ in var3) Variable<int>($)
],
readsFrom: {

View File

@ -368,7 +368,7 @@ void main() {
class _TestDatabase extends GeneratedDatabase {
_TestDatabase(QueryExecutor executor, this.schemaVersion, this.migration)
: super(const SqlTypeSystem.withDefaults(), executor);
: super(executor);
@override
Iterable<TableInfo<Table, dynamic>> get allTables => const Iterable.empty();

View File

@ -43,8 +43,7 @@ CREATE TABLE IF NOT EXISTS todo_categories (
}
class _Database extends GeneratedDatabase {
_Database(QueryExecutor executor)
: super(SqlTypeSystem.defaultInstance, executor);
_Database(QueryExecutor executor) : super(executor);
@override
Iterable<TableInfo<Table, dynamic>> get allTables => const Iterable.empty();

View File

@ -1,6 +1,8 @@
import 'package:drift/drift.dart';
import 'package:test/test.dart';
import 'test_utils.dart';
void expectEquals(dynamic a, dynamic expected) {
expect(a, equals(expected));
expect(a.hashCode, equals(expected.hashCode));
@ -66,7 +68,7 @@ class _GeneratesSqlMatcher extends Matcher {
return false;
}
final ctx = GenerationContext(SqlTypeSystem.defaultInstance, null);
final ctx = stubContext();
item.writeInto(ctx);
var matches = true;

View File

@ -1,5 +1,25 @@
import 'package:drift/drift.dart';
import 'package:mockito/mockito.dart';
export 'database_stub.dart'
if (dart.library.ffi) 'database_vm.dart'
if (dart.library.js) 'database_web.dart';
export 'matchers.dart';
export 'mocks.dart';
GenerationContext stubContext({DriftDatabaseOptions? options}) {
return GenerationContext(options ?? DriftDatabaseOptions(), _NullDatabase());
}
class _NullDatabase extends GeneratedDatabase {
_NullDatabase() : super(_NullExecutor());
@override
Iterable<TableInfo<Table, dynamic>> get allTables =>
throw UnsupportedError('stub');
@override
int get schemaVersion => throw UnsupportedError('stub!');
}
class _NullExecutor extends Fake implements QueryExecutor {}

View File

@ -140,10 +140,10 @@ class ViewParser {
if (sqlType == null) {
final String errorMessage;
if (typeName == 'dynamic') {
errorMessage = 'You must specify Expression<?> type argument';
errorMessage = 'You must specify Expression<> type argument';
} else {
errorMessage =
'Invalid Expression<?> type argument `$typeName` found. '
'Invalid Expression<> type argument `$typeName` found. '
'Must be one of: '
'bool, String, int, DateTime, Uint8List, double';
}

View File

@ -1,7 +1,6 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:drift_dev/src/analyzer/options.dart';
import 'package:drift_dev/writer.dart';
import 'package:sqlparser/sqlparser.dart' show ReferenceAction;
import 'declarations/declaration.dart';
@ -127,42 +126,6 @@ class DriftColumn implements HasDeclaration, HasType {
ColumnType.real: 'RealColumn',
}[type]!;
String innerColumnType({
GenerationOptions options = const GenerationOptions(),
bool checkNullable = false,
}) {
String code;
switch (type) {
case ColumnType.integer:
code = 'int';
break;
case ColumnType.bigInt:
code = 'BigInt';
break;
case ColumnType.text:
code = 'String';
break;
case ColumnType.boolean:
code = 'bool';
break;
case ColumnType.datetime:
code = 'DateTime';
break;
case ColumnType.blob:
code = 'Uint8List';
break;
case ColumnType.real:
code = 'double';
break;
}
// We currently use nullable columns everywhere because it's not clear how
// to express nullability in joins otherwise. When serializing data with
// JsonTypeConverter it needs to match the nullability of the column
return (!checkNullable || nullable) ? '$code?' : code;
}
@override
bool get isArray => false;

View File

@ -742,7 +742,7 @@ class ExpressionDartPlaceholderType extends DartPlaceholderType {
if (columnType == null) return 'Expression';
final dartType = dartTypeNames[columnType]!;
return 'Expression<$dartType?>';
return 'Expression<$dartType>';
}
}

View File

@ -84,25 +84,45 @@ extension OperationOnTypes on HasType {
/// Basically the same as [dartTypeCode], minus custom types and nullability.
String get variableTypeName => dartTypeNames[type]!;
/// The class inside the moor library that represents the same sql type as
/// this column.
String get sqlTypeName => sqlTypes[type]!;
/// The moor Dart type that matches the type of this column.
///
/// This is the same as [dartTypeCode] but without custom types.
String variableTypeCode(
[GenerationOptions options = const GenerationOptions()]) {
String variableTypeCode({bool? nullable}) {
if (isArray) {
return 'List<${variableTypeCodeWithoutArray(options)}>';
return 'List<${innerColumnType(nullable: nullable ?? this.nullable)}>';
} else {
return variableTypeCodeWithoutArray(options);
return innerColumnType(nullable: nullable ?? this.nullable);
}
}
String variableTypeCodeWithoutArray(
[GenerationOptions options = const GenerationOptions()]) {
return nullable ? '$variableTypeName?' : variableTypeName;
String innerColumnType({bool nullable = false}) {
String code;
switch (type) {
case ColumnType.integer:
code = 'int';
break;
case ColumnType.bigInt:
code = 'BigInt';
break;
case ColumnType.text:
code = 'String';
break;
case ColumnType.boolean:
code = 'bool';
break;
case ColumnType.datetime:
code = 'DateTime';
break;
case ColumnType.blob:
code = 'Uint8List';
break;
case ColumnType.real:
code = 'double';
break;
}
return nullable ? '$code?' : code;
}
/// The dart type that matches the values of this column. For instance, if a
@ -116,7 +136,7 @@ extension OperationOnTypes on HasType {
return isArray ? 'List<$inner>' : inner;
}
return variableTypeCode(options);
return variableTypeCode();
}
DriftSqlType sqlType() {
@ -161,13 +181,3 @@ const Map<ColumnType, String> createVariable = {
ColumnType.blob: 'Variable.withBlob',
ColumnType.real: 'Variable.withReal',
};
const Map<ColumnType, String> sqlTypes = {
ColumnType.boolean: 'BoolType',
ColumnType.text: 'StringType',
ColumnType.integer: 'IntType',
ColumnType.bigInt: 'BigIntType',
ColumnType.datetime: 'DateTimeType',
ColumnType.blob: 'BlobType',
ColumnType.real: 'RealType',
};

View File

@ -47,7 +47,7 @@ class DatabaseWriter {
firstLeaf.write('class $className extends GeneratedDatabase {\n'
'$className(QueryExecutor e) : '
'super(SqlTypeSystem.defaultInstance, e); \n');
'super(e); \n');
if (dbScope.options.generateConnectConstructor) {
firstLeaf.write(

View File

@ -705,8 +705,7 @@ class _ExpandedVariableWriter {
// write all the variables sequentially.
String constructVar(String dartExpr) {
// No longer an array here, we apply a for loop if necessary
final type =
element.variableTypeCodeWithoutArray(scope.generationOptions);
final type = element.innerColumnType(nullable: false);
final buffer = StringBuffer('Variable<$type>(');
final capture = element.forCaptured;

View File

@ -1,5 +1,4 @@
import 'package:drift_dev/moor_generator.dart';
import 'package:drift_dev/src/analyzer/options.dart';
import 'package:drift_dev/src/utils/string_escaper.dart';
import 'package:drift_dev/src/writer/utils/override_toString.dart';
import 'package:drift_dev/writer.dart';
@ -70,9 +69,6 @@ class DataClassWriter {
}).join(', '))
..write('});');
// Also write parsing factory
_writeMappingConstructor();
if (isInsertable) {
_writeToColumnsOverride();
if (scope.options.dataClassToCompanions) {
@ -97,33 +93,6 @@ class DataClassWriter {
_buffer.write('}');
}
void _writeMappingConstructor() {
final dataClassName = table.dartTypeName;
// The GeneratedDatabase db parameter is not actually used, but we need to
// keep it on tables for backwards compatibility.
final includeUnusedDbColumn =
scope.generationOptions.writeForMoorPackage && table is DriftTable;
_buffer
..write('factory $dataClassName.fromData')
..write('(Map<String, dynamic> data, ')
..write(includeUnusedDbColumn ? ' GeneratedDatabase db,' : '')
..write('{String? prefix}) { \n')
..write("final effectivePrefix = prefix ?? '';");
final writer = RowMappingWriter(
const [],
{for (final column in columns) column: column.dartGetterName},
table,
scope.generationOptions,
scope.options,
);
_buffer.write('return $dataClassName');
writer.writeArguments(_buffer);
_buffer.write(';}\n');
}
void _writeFromJson() {
final dataClassName = table.dartTypeName;
@ -141,8 +110,7 @@ class DataClassWriter {
final typeConverter = column.typeConverter;
if (typeConverter != null && typeConverter.alsoAppliesToJsonConversion) {
final type = column.innerColumnType(
options: scope.generationOptions, checkNullable: true);
final type = column.innerColumnType();
final fromConverter = "serializer.fromJson<$type>(json['$jsonKey'])";
final converterField =
typeConverter.tableAndField(forNullableColumn: column.nullable);
@ -186,8 +154,7 @@ class DataClassWriter {
final converterField =
typeConverter.tableAndField(forNullableColumn: column.nullable);
value = '$converterField.toJson($value)';
dartType =
'${column.innerColumnType(options: scope.generationOptions)}';
dartType = '${column.innerColumnType(nullable: true)}';
}
_buffer.write("'$name': serializer.toJson<$dartType>($value),");
@ -264,7 +231,7 @@ class DataClassWriter {
}
if (needsScope) _buffer.write('{');
final typeName = column.variableTypeCode(scope.generationOptions);
final typeName = column.variableTypeCode(nullable: false);
final mapSetter = 'map[${asDartLiteral(column.name.name)}] = '
'Variable<$typeName>';
@ -357,17 +324,29 @@ class RowMappingWriter {
final Map<DriftColumn, String> named;
final DriftEntityWithResultSet table;
final GenerationOptions options;
final DriftOptions moorOptions;
RowMappingWriter(
this.positional, this.named, this.table, this.options, this.moorOptions);
/// Code to obtain an instance of a `DatabaseConnectionUser` in the generated
/// code.
///
/// This is used to lookup the connection options necessary for mapping values
/// from SQL to Dart.
final String databaseGetter;
RowMappingWriter({
required this.positional,
required this.table,
required this.options,
required this.databaseGetter,
this.named = const {},
});
void writeArguments(StringBuffer buffer) {
String readAndMap(DriftColumn column) {
final columnName = column.name.name;
final rawData = "data['\${effectivePrefix}$columnName']";
final sqlType = 'const ${sqlTypes[column.type]}()';
var loadType = '$sqlType.mapFromDatabaseResponse($rawData)';
final sqlType = column.sqlType();
var loadType = '$databaseGetter.options.types.read($sqlType, $rawData)';
if (!column.nullable) {
loadType += '!';

View File

@ -39,7 +39,7 @@ abstract class TableOrViewWriter {
}
}
additionalParams['type'] = 'const ${column.sqlType().runtimeType}()';
additionalParams['type'] = column.sqlType().toString();
if (tableOrView is DriftTable) {
additionalParams['requiredDuringInsert'] = (tableOrView as DriftTable)
@ -73,7 +73,7 @@ abstract class TableOrViewWriter {
}
}
final innerType = column.innerColumnType(options: options);
final innerType = column.innerColumnType();
var type = 'GeneratedColumn<$innerType>';
expressionBuffer
..write(type)
@ -136,13 +136,13 @@ abstract class TableOrViewWriter {
final dataClassName = tableOrView.dartTypeCode(scope.generationOptions);
buffer.write('@override\n$dataClassName map(Map<String, dynamic> data, '
'{String? tablePrefix}) {\n');
if (tableOrView.hasExistingRowClass) {
buffer.write('final effectivePrefix = '
buffer
..write('@override\n$dataClassName map(Map<String, dynamic> data, '
'{String? tablePrefix}) {\n')
..write('final effectivePrefix = '
"tablePrefix != null ? '\$tablePrefix.' : '';");
if (tableOrView.hasExistingRowClass) {
final info = tableOrView.existingRowClass!;
final positionalToIndex = <DriftColumn, int>{};
final named = <DriftColumn, String>{};
@ -163,11 +163,11 @@ abstract class TableOrViewWriter {
(a, b) => positionalToIndex[a]!.compareTo(positionalToIndex[b]!));
final writer = RowMappingWriter(
positional,
named,
tableOrView,
scope.generationOptions,
scope.options,
positional: positional,
named: named,
table: tableOrView,
options: scope.generationOptions,
databaseGetter: 'attachedDatabase',
);
final classElement = info.targetClass;
@ -184,16 +184,26 @@ abstract class TableOrViewWriter {
writer.writeArguments(buffer);
buffer.write(';\n');
} else {
// Use default .fromData constructor in the moor-generated data class
final hasDbParameter = scope.generationOptions.writeForMoorPackage &&
tableOrView is DriftTable;
if (hasDbParameter) {
buffer.write('return $dataClassName.fromData(data, attachedDatabase, '
"prefix: tablePrefix != null ? '\$tablePrefix.' : null);\n");
List<DriftColumn> columns;
final view = tableOrView;
if (view is MoorView && view.viewQuery != null) {
columns = view.viewQuery!.columns.map((e) => e.value).toList();
} else {
buffer.write('return $dataClassName.fromData(data, '
"prefix: tablePrefix != null ? '\$tablePrefix.' : null);\n");
columns = tableOrView.columns;
}
final writer = RowMappingWriter(
positional: const [],
named: {for (final column in columns) column: column.dartGetterName},
table: tableOrView,
options: scope.generationOptions,
databaseGetter: 'attachedDatabase',
);
buffer.write('return ${tableOrView.dartTypeName}');
writer.writeArguments(buffer);
buffer.writeln(';');
}
buffer.write('}\n');

View File

@ -122,8 +122,7 @@ class UpdateCompanionWriter {
..write('({');
for (final column in columns) {
// todo (breaking change): This should not consider type converters.
final typeName = column.dartTypeCode(scope.generationOptions);
final typeName = column.innerColumnType();
_buffer.write('Expression<$typeName>? ${column.dartGetterName}, \n');
}
@ -179,7 +178,7 @@ class UpdateCompanionWriter {
final getterName = column.thisIfNeeded(locals);
_buffer.write('if ($getterName.present) {');
final typeName = column.variableTypeCode(scope.generationOptions);
final typeName = column.variableTypeCode(nullable: false);
final mapSetter = 'map[${asDartLiteral(column.name.name)}] = '
'Variable<$typeName>';

View File

@ -340,8 +340,8 @@ class TodoEntriesCompanion extends UpdateCompanion<TodoEntry> {
static Insertable<TodoEntry> custom({
Expression<int>? id,
Expression<String>? description,
Expression<int?>? category,
Expression<DateTime?>? dueDate,
Expression<int>? category,
Expression<DateTime>? dueDate,
}) {
return RawValuesInsertable({
if (id != null) 'id': id,

View File

@ -106,7 +106,7 @@ class UsersCompanion extends UpdateCompanion<User> {
static Insertable<User> custom({
Expression<int>? id,
Expression<String>? name,
Expression<int?>? nextUser,
Expression<int>? nextUser,
}) {
return RawValuesInsertable({
if (id != null) 'id': id,
@ -332,7 +332,7 @@ class GroupsCompanion extends UpdateCompanion<Group> {
static Insertable<Group> custom({
Expression<int>? id,
Expression<String>? title,
Expression<bool?>? deleted,
Expression<bool>? deleted,
Expression<int>? owner,
}) {
return RawValuesInsertable({

View File

@ -272,7 +272,7 @@ class GroupsCompanion extends UpdateCompanion<GroupsData> {
static Insertable<GroupsData> custom({
Expression<int>? id,
Expression<String>? title,
Expression<bool?>? deleted,
Expression<bool>? deleted,
Expression<int>? owner,
}) {
return RawValuesInsertable({

View File

@ -274,7 +274,7 @@ class GroupsCompanion extends UpdateCompanion<GroupsData> {
static Insertable<GroupsData> custom({
Expression<int>? id,
Expression<String>? title,
Expression<bool?>? deleted,
Expression<bool>? deleted,
Expression<int>? owner,
}) {
return RawValuesInsertable({

View File

@ -101,7 +101,7 @@ class UsersCompanion extends UpdateCompanion<UsersData> {
static Insertable<UsersData> custom({
Expression<int>? id,
Expression<String>? name,
Expression<int?>? nextUser,
Expression<int>? nextUser,
}) {
return RawValuesInsertable({
if (id != null) 'id': id,
@ -306,7 +306,7 @@ class GroupsCompanion extends UpdateCompanion<GroupsData> {
static Insertable<GroupsData> custom({
Expression<int>? id,
Expression<String>? title,
Expression<bool?>? deleted,
Expression<bool>? deleted,
Expression<int>? owner,
}) {
return RawValuesInsertable({

View File

@ -174,8 +174,8 @@ class UsersCompanion extends UpdateCompanion<User> {
Expression<int>? id,
Expression<String>? name,
Expression<DateTime>? birthDate,
Expression<Uint8List?>? profilePicture,
Expression<Preferences?>? preferences,
Expression<Uint8List>? profilePicture,
Expression<Preferences>? preferences,
}) {
return RawValuesInsertable({
if (id != null) 'id': id,

View File

@ -100,7 +100,7 @@ class CategoriesCompanion extends UpdateCompanion<Category> {
});
static Insertable<Category> custom({
Expression<int>? id,
Expression<String?>? description,
Expression<String>? description,
}) {
return RawValuesInsertable({
if (id != null) 'id': id,
@ -318,7 +318,7 @@ class RecipesCompanion extends UpdateCompanion<Recipe> {
Expression<int>? id,
Expression<String>? title,
Expression<String>? instructions,
Expression<int?>? category,
Expression<int>? category,
}) {
return RawValuesInsertable({
if (id != null) 'id': id,

View File

@ -130,8 +130,8 @@ class TodosCompanion extends UpdateCompanion<TodoEntry> {
static Insertable<TodoEntry> custom({
Expression<int>? id,
Expression<String>? content,
Expression<DateTime?>? targetDate,
Expression<int?>? category,
Expression<DateTime>? targetDate,
Expression<int>? category,
}) {
return RawValuesInsertable({
if (id != null) 'id': id,