tests and fixes

This commit is contained in:
Moshe Dicker 2024-04-11 15:04:24 -04:00
parent 2f9a57317f
commit b6e15c39ed
4 changed files with 647 additions and 41 deletions

View File

@ -38,18 +38,78 @@ class ColumnFilters<T extends Object> {
/// Shortcut for [equals]
ComposableFilter call(T value) => ComposableFilter(column.equals(value));
}
/// Nested column for filtering on the count of a column
ColumnFilters<int> get count => ColumnFilters(column.count());
enum _StringFilterTypes { contains, startsWith, endsWith }
/// Built in filters for int/double columns
extension StringFilters<T extends String> on ColumnFilters<String> {
/// This function helps handle case insensitivity in like expressions
/// This helps handle all the possible scenarios:
/// 1. If a user hasn't set the database to be case sensitive in like expressions
/// Then we are ok with having the query be performed on upper case values
/// 2. If a user has set the database to be case sensitive in like expressions
/// We still can perform a case insensitive search by default. We have all filters
/// use `{bool caseInsensitive = true}` which will perform a case insensitive search
/// 3. If a user has set the database to be case sensitive in like expressions and wan't
/// to perform a case sensitive search, they can pass `caseInsensitive = false` manually
///
/// We are using the default of {bool caseInsensitive = true}, so that users who haven't set
/// the database to be case sensitive wont be confues why their like expressions are case insensitive
Expression<bool> _buildExpression(
_StringFilterTypes type, String value, bool caseInsensitive) {
final Expression<String> column;
if (caseInsensitive) {
value = value.toUpperCase();
column = this.column.upper();
} else {
column = this.column;
}
switch (type) {
case _StringFilterTypes.contains:
return column.like('%$value%');
case _StringFilterTypes.startsWith:
return column.like('$value%');
case _StringFilterTypes.endsWith:
return column.like('%$value');
}
}
/// Create a filter to check if the this text column contains a substring
/// {@template drift.manager.likeCaseSensitivity}
/// Sqlite performs a case insensitive text search by default
///
/// If you have set the database to use case sensitive in like expressions, you can
/// pass [caseInsensitive] as false to perform a case sensitive search
/// See https://www.sqlitetutorial.net/sqlite-like/ for more information
/// {@endtemplate}
ComposableFilter contains(T value, {bool caseInsensitive = true}) {
return ComposableFilter(
_buildExpression(_StringFilterTypes.contains, value, caseInsensitive));
}
/// Create a filter to check if the this text column starts with a substring
/// {@macro drift.manager.likeCaseSensitivity}
ComposableFilter startsWith(T value, {bool caseInsensitive = true}) {
return ComposableFilter(_buildExpression(
_StringFilterTypes.startsWith, value, caseInsensitive));
}
/// Create a filter to check if the this text column ends with a substring
/// {@macro drift.manager.likeCaseSensitivity}
ComposableFilter endsWith(T value, {bool caseInsensitive = true}) {
return ComposableFilter(
_buildExpression(_StringFilterTypes.endsWith, value, caseInsensitive));
}
}
/// Built in filters for bool columns
extension BoolFilters on ColumnFilters<bool> {
/// Create a filter to check if the column is bigger than a value
ComposableFilter isTrue(bool value) => ComposableFilter(column.equals(true));
ComposableFilter isTrue() => ComposableFilter(column.equals(true));
/// Create a filter to check if the column is small than a value
ComposableFilter isFalse(bool value) => ComposableFilter(column.equals(true));
ComposableFilter isFalse() => ComposableFilter(column.equals(false));
}
/// Built in filters for int/double columns
@ -71,27 +131,16 @@ extension NumFilters<T extends num> on ColumnFilters<T> {
ComposableFilter(column.isSmallerOrEqualValue(value));
/// Create a filter to check if the column is between two values
/// This is done inclusively, so the column can be equal to the lower or higher value
/// E.G isBetween(1, 3) will return true for 1, 2, and 3
ComposableFilter isBetween(T lower, T higher) =>
ComposableFilter(column.isBetweenValues(lower, higher));
/// Create a filter to check if the column is not between two values
/// This is done inclusively, so the column will not be equal to the lower or higher value
/// E.G isNotBetween(1, 3) will return false for 1, 2, and 3
ComposableFilter isNotBetween(T lower, T higher) =>
isBetween(lower, higher)._invert();
/// Nested column for filtering on the average of a column
ColumnFilters<double> get avg => ColumnFilters(column.avg());
/// Nested column for filtering on the max item of a column
ColumnFilters<T> get max => ColumnFilters(column.max());
/// Nested column for filtering on the min item of a column
ColumnFilters<T> get min => ColumnFilters(column.min());
/// Nested column for filtering on the sum of a column
ColumnFilters<T> get sum => ColumnFilters(column.sum());
/// Nested column for filtering on the total of a column
ColumnFilters<double> get total => ColumnFilters(column.total());
}
/// Built in filters for BigInt columns
@ -113,30 +162,19 @@ extension BigIntFilters<T extends BigInt> on ColumnFilters<T> {
ComposableFilter(column.isSmallerOrEqualValue(value));
/// Create a filter to check if the column is between two values
/// This is done inclusively, so the column can be equal to the lower or higher value
/// E.G isBetween(1, 3) will return true for 1, 2, and 3
ComposableFilter isBetween(T lower, T higher) =>
ComposableFilter(column.isBetweenValues(lower, higher));
/// Create a filter to check if the column is not between two values
/// This is done inclusively, so the column will not be equal to the lower or higher value
/// E.G isNotBetween(1, 3) will return false for 1, 2, and 3
ComposableFilter isNotBetween(T lower, T higher) =>
isBetween(lower, higher)._invert();
/// Nested column for filtering on the average of a column
ColumnFilters<double> get avg => ColumnFilters(column.avg());
/// Nested column for filtering on the max item of a column
ColumnFilters<T> get max => ColumnFilters(column.max());
/// Nested column for filtering on the min item of a column
ColumnFilters<T> get min => ColumnFilters(column.min());
/// Nested column for filtering on the sum of a column
ColumnFilters<BigInt> get sum => ColumnFilters(column.sum());
/// Nested column for filtering on the total of a column
ColumnFilters<double> get total => ColumnFilters(column.total());
}
/// Built in filters for String columns
/// Built in filters for DateTime columns
extension DateFilters<T extends DateTime> on ColumnFilters<T> {
/// Create a filter to check if the column is after a [DateTime]
ComposableFilter isAfter(T value) =>
@ -155,11 +193,14 @@ extension DateFilters<T extends DateTime> on ColumnFilters<T> {
ComposableFilter(column.isSmallerOrEqualValue(value));
/// Create a filter to check if the column is between 2 [DateTime]s
/// This is done inclusively, so the column can be equal to the lower or higher value
/// E.G isBetween(1, 3) will return true for 1, 2, and 3
ComposableFilter isBetween(T lower, T higher) =>
ComposableFilter(column.isBetweenValues(lower, higher));
/// Create a filter to check if the column is not between 2 [DateTime]s
/// This is done inclusively, so the column will not be equal to the lower or higher value
/// E.G isNotBetween(1, 3) will return false for 1, 2, and 3
ComposableFilter isNotBetween(T lower, T higher) =>
isBetween(lower, higher)._invert();
}
@ -185,6 +226,14 @@ class ColumnWithTypeConverterFilters<CUSTOM, T extends Object> {
/// Shortcut for [equals]
ComposableFilter call(CUSTOM value) =>
ComposableFilter(column.equalsValue(value));
/// Create a filter that checks if the column is in a list of values.
ComposableFilter isIn(Iterable<CUSTOM> values) =>
ComposableFilter(column.isInValues(values));
/// Create a filter that checks if the column is not in a list of values.
ComposableFilter isNotIn(Iterable<CUSTOM> values) =>
ComposableFilter(column.isNotInValues(values));
}
/// This class is wrapper on the expression class

View File

@ -24,6 +24,9 @@ class TodosTable extends Table with AutoIncrement {
@JsonKey('target_date')
DateTimeColumn get targetDate => dateTime().nullable().unique()();
RealColumn get someFloat => real().nullable()();
Int64Column get someInt64 => int64().nullable()();
IntColumn get category => integer().references(Categories, #id).nullable()();
TextColumn get status => textEnum<TodoStatus>().nullable()();

View File

@ -305,6 +305,18 @@ class $TodosTableTable extends TodosTable
type: DriftSqlType.dateTime,
requiredDuringInsert: false,
defaultConstraints: GeneratedColumn.constraintIsAlways('UNIQUE'));
static const VerificationMeta _someFloatMeta =
const VerificationMeta('someFloat');
@override
late final GeneratedColumn<double> someFloat = GeneratedColumn<double>(
'some_float', aliasedName, true,
type: DriftSqlType.double, requiredDuringInsert: false);
static const VerificationMeta _someInt64Meta =
const VerificationMeta('someInt64');
@override
late final GeneratedColumn<BigInt> someInt64 = GeneratedColumn<BigInt>(
'some_int64', aliasedName, true,
type: DriftSqlType.bigInt, requiredDuringInsert: false);
static const VerificationMeta _categoryMeta =
const VerificationMeta('category');
@override
@ -322,7 +334,7 @@ class $TodosTableTable extends TodosTable
.withConverter<TodoStatus?>($TodosTableTable.$converterstatusn);
@override
List<GeneratedColumn> get $columns =>
[id, title, content, targetDate, category, status];
[id, title, content, targetDate, someFloat, someInt64, category, status];
@override
String get aliasedName => _alias ?? actualTableName;
@override
@ -350,6 +362,14 @@ class $TodosTableTable extends TodosTable
targetDate.isAcceptableOrUnknown(
data['target_date']!, _targetDateMeta));
}
if (data.containsKey('some_float')) {
context.handle(_someFloatMeta,
someFloat.isAcceptableOrUnknown(data['some_float']!, _someFloatMeta));
}
if (data.containsKey('some_int64')) {
context.handle(_someInt64Meta,
someInt64.isAcceptableOrUnknown(data['some_int64']!, _someInt64Meta));
}
if (data.containsKey('category')) {
context.handle(_categoryMeta,
category.isAcceptableOrUnknown(data['category']!, _categoryMeta));
@ -377,6 +397,10 @@ class $TodosTableTable extends TodosTable
.read(DriftSqlType.string, data['${effectivePrefix}content'])!,
targetDate: attachedDatabase.typeMapping
.read(DriftSqlType.dateTime, data['${effectivePrefix}target_date']),
someFloat: attachedDatabase.typeMapping
.read(DriftSqlType.double, data['${effectivePrefix}some_float']),
someInt64: attachedDatabase.typeMapping
.read(DriftSqlType.bigInt, data['${effectivePrefix}some_int64']),
category: attachedDatabase.typeMapping
.read(DriftSqlType.int, data['${effectivePrefix}category']),
status: $TodosTableTable.$converterstatusn.fromSql(attachedDatabase
@ -403,6 +427,8 @@ class TodoEntry extends DataClass implements Insertable<TodoEntry> {
final String? title;
final String content;
final DateTime? targetDate;
final double? someFloat;
final BigInt? someInt64;
final int? category;
final TodoStatus? status;
const TodoEntry(
@ -410,6 +436,8 @@ class TodoEntry extends DataClass implements Insertable<TodoEntry> {
this.title,
required this.content,
this.targetDate,
this.someFloat,
this.someInt64,
this.category,
this.status});
@override
@ -425,6 +453,12 @@ class TodoEntry extends DataClass implements Insertable<TodoEntry> {
if (!nullToAbsent || targetDate != null) {
map['target_date'] = Variable<DateTime>(targetDate);
}
if (!nullToAbsent || someFloat != null) {
map['some_float'] = Variable<double>(someFloat);
}
if (!nullToAbsent || someInt64 != null) {
map['some_int64'] = Variable<BigInt>(someInt64);
}
if (!nullToAbsent || category != null) {
map['category'] = Variable<int>(category);
}
@ -444,6 +478,12 @@ class TodoEntry extends DataClass implements Insertable<TodoEntry> {
targetDate: targetDate == null && nullToAbsent
? const Value.absent()
: Value(targetDate),
someFloat: someFloat == null && nullToAbsent
? const Value.absent()
: Value(someFloat),
someInt64: someInt64 == null && nullToAbsent
? const Value.absent()
: Value(someInt64),
category: category == null && nullToAbsent
? const Value.absent()
: Value(category),
@ -461,6 +501,8 @@ class TodoEntry extends DataClass implements Insertable<TodoEntry> {
title: serializer.fromJson<String?>(json['title']),
content: serializer.fromJson<String>(json['content']),
targetDate: serializer.fromJson<DateTime?>(json['target_date']),
someFloat: serializer.fromJson<double?>(json['someFloat']),
someInt64: serializer.fromJson<BigInt?>(json['someInt64']),
category: serializer.fromJson<int?>(json['category']),
status: $TodosTableTable.$converterstatusn
.fromJson(serializer.fromJson<String?>(json['status'])),
@ -479,6 +521,8 @@ class TodoEntry extends DataClass implements Insertable<TodoEntry> {
'title': serializer.toJson<String?>(title),
'content': serializer.toJson<String>(content),
'target_date': serializer.toJson<DateTime?>(targetDate),
'someFloat': serializer.toJson<double?>(someFloat),
'someInt64': serializer.toJson<BigInt?>(someInt64),
'category': serializer.toJson<int?>(category),
'status': serializer
.toJson<String?>($TodosTableTable.$converterstatusn.toJson(status)),
@ -490,6 +534,8 @@ class TodoEntry extends DataClass implements Insertable<TodoEntry> {
Value<String?> title = const Value.absent(),
String? content,
Value<DateTime?> targetDate = const Value.absent(),
Value<double?> someFloat = const Value.absent(),
Value<BigInt?> someInt64 = const Value.absent(),
Value<int?> category = const Value.absent(),
Value<TodoStatus?> status = const Value.absent()}) =>
TodoEntry(
@ -497,6 +543,8 @@ class TodoEntry extends DataClass implements Insertable<TodoEntry> {
title: title.present ? title.value : this.title,
content: content ?? this.content,
targetDate: targetDate.present ? targetDate.value : this.targetDate,
someFloat: someFloat.present ? someFloat.value : this.someFloat,
someInt64: someInt64.present ? someInt64.value : this.someInt64,
category: category.present ? category.value : this.category,
status: status.present ? status.value : this.status,
);
@ -507,6 +555,8 @@ class TodoEntry extends DataClass implements Insertable<TodoEntry> {
..write('title: $title, ')
..write('content: $content, ')
..write('targetDate: $targetDate, ')
..write('someFloat: $someFloat, ')
..write('someInt64: $someInt64, ')
..write('category: $category, ')
..write('status: $status')
..write(')'))
@ -514,8 +564,8 @@ class TodoEntry extends DataClass implements Insertable<TodoEntry> {
}
@override
int get hashCode =>
Object.hash(id, title, content, targetDate, category, status);
int get hashCode => Object.hash(
id, title, content, targetDate, someFloat, someInt64, category, status);
@override
bool operator ==(Object other) =>
identical(this, other) ||
@ -524,6 +574,8 @@ class TodoEntry extends DataClass implements Insertable<TodoEntry> {
other.title == this.title &&
other.content == this.content &&
other.targetDate == this.targetDate &&
other.someFloat == this.someFloat &&
other.someInt64 == this.someInt64 &&
other.category == this.category &&
other.status == this.status);
}
@ -533,6 +585,8 @@ class TodosTableCompanion extends UpdateCompanion<TodoEntry> {
final Value<String?> title;
final Value<String> content;
final Value<DateTime?> targetDate;
final Value<double?> someFloat;
final Value<BigInt?> someInt64;
final Value<int?> category;
final Value<TodoStatus?> status;
const TodosTableCompanion({
@ -540,6 +594,8 @@ class TodosTableCompanion extends UpdateCompanion<TodoEntry> {
this.title = const Value.absent(),
this.content = const Value.absent(),
this.targetDate = const Value.absent(),
this.someFloat = const Value.absent(),
this.someInt64 = const Value.absent(),
this.category = const Value.absent(),
this.status = const Value.absent(),
});
@ -548,6 +604,8 @@ class TodosTableCompanion extends UpdateCompanion<TodoEntry> {
this.title = const Value.absent(),
required String content,
this.targetDate = const Value.absent(),
this.someFloat = const Value.absent(),
this.someInt64 = const Value.absent(),
this.category = const Value.absent(),
this.status = const Value.absent(),
}) : content = Value(content);
@ -556,6 +614,8 @@ class TodosTableCompanion extends UpdateCompanion<TodoEntry> {
Expression<String>? title,
Expression<String>? content,
Expression<DateTime>? targetDate,
Expression<double>? someFloat,
Expression<BigInt>? someInt64,
Expression<int>? category,
Expression<String>? status,
}) {
@ -564,6 +624,8 @@ class TodosTableCompanion extends UpdateCompanion<TodoEntry> {
if (title != null) 'title': title,
if (content != null) 'content': content,
if (targetDate != null) 'target_date': targetDate,
if (someFloat != null) 'some_float': someFloat,
if (someInt64 != null) 'some_int64': someInt64,
if (category != null) 'category': category,
if (status != null) 'status': status,
});
@ -574,6 +636,8 @@ class TodosTableCompanion extends UpdateCompanion<TodoEntry> {
Value<String?>? title,
Value<String>? content,
Value<DateTime?>? targetDate,
Value<double?>? someFloat,
Value<BigInt?>? someInt64,
Value<int?>? category,
Value<TodoStatus?>? status}) {
return TodosTableCompanion(
@ -581,6 +645,8 @@ class TodosTableCompanion extends UpdateCompanion<TodoEntry> {
title: title ?? this.title,
content: content ?? this.content,
targetDate: targetDate ?? this.targetDate,
someFloat: someFloat ?? this.someFloat,
someInt64: someInt64 ?? this.someInt64,
category: category ?? this.category,
status: status ?? this.status,
);
@ -601,6 +667,12 @@ class TodosTableCompanion extends UpdateCompanion<TodoEntry> {
if (targetDate.present) {
map['target_date'] = Variable<DateTime>(targetDate.value);
}
if (someFloat.present) {
map['some_float'] = Variable<double>(someFloat.value);
}
if (someInt64.present) {
map['some_int64'] = Variable<BigInt>(someInt64.value);
}
if (category.present) {
map['category'] = Variable<int>(category.value);
}
@ -618,6 +690,8 @@ class TodosTableCompanion extends UpdateCompanion<TodoEntry> {
..write('title: $title, ')
..write('content: $content, ')
..write('targetDate: $targetDate, ')
..write('someFloat: $someFloat, ')
..write('someInt64: $someInt64, ')
..write('category: $category, ')
..write('status: $status')
..write(')'))
@ -1890,6 +1964,8 @@ abstract class _$TodoDb extends GeneratedDatabase {
title: row.readNullable<String>('title'),
content: row.read<String>('content'),
targetDate: row.readNullable<DateTime>('target_date'),
someFloat: row.readNullable<double>('some_float'),
someInt64: row.readNullable<BigInt>('some_int64'),
category: row.readNullable<int>('category'),
status: NullAwareTypeConverter.wrapFromSql(
$TodosTableTable.$converterstatus,
@ -2070,6 +2146,8 @@ class $$TodosTableTableFilterComposer
ColumnFilters<String> get title => ColumnFilters($table.title);
ColumnFilters<String> get content => ColumnFilters($table.content);
ColumnFilters<DateTime> get targetDate => ColumnFilters($table.targetDate);
ColumnFilters<double> get someFloat => ColumnFilters($table.someFloat);
ColumnFilters<BigInt> get someInt64 => ColumnFilters($table.someInt64);
ColumnFilters<int> get categoryId => ColumnFilters($table.category);
ComposableFilter category(
ComposableFilter Function($$CategoriesTableFilterComposer f) f) {
@ -2096,6 +2174,8 @@ class $$TodosTableTableOrderingComposer
ColumnOrderings get title => ColumnOrderings($table.title);
ColumnOrderings get content => ColumnOrderings($table.content);
ColumnOrderings get targetDate => ColumnOrderings($table.targetDate);
ColumnOrderings get someFloat => ColumnOrderings($table.someFloat);
ColumnOrderings get someInt64 => ColumnOrderings($table.someInt64);
ColumnOrderings get categoryId => ColumnOrderings($table.category);
ComposableOrdering category(
ComposableOrdering Function($$CategoriesTableOrderingComposer o) o) {
@ -2130,6 +2210,8 @@ typedef $$TodosTableTableInsertCompanionBuilder = TodosTableCompanion Function({
Value<String?> title,
required String content,
Value<DateTime?> targetDate,
Value<double?> someFloat,
Value<BigInt?> someInt64,
Value<int?> category,
Value<TodoStatus?> status,
});
@ -2138,6 +2220,8 @@ typedef $$TodosTableTableUpdateCompanionBuilder = TodosTableCompanion Function({
Value<String?> title,
Value<String> content,
Value<DateTime?> targetDate,
Value<double?> someFloat,
Value<BigInt?> someInt64,
Value<int?> category,
Value<TodoStatus?> status,
});
@ -2164,6 +2248,8 @@ class $$TodosTableTableTableManager extends RootTableManager<
Value<String?> title = const Value.absent(),
Value<String> content = const Value.absent(),
Value<DateTime?> targetDate = const Value.absent(),
Value<double?> someFloat = const Value.absent(),
Value<BigInt?> someInt64 = const Value.absent(),
Value<int?> category = const Value.absent(),
Value<TodoStatus?> status = const Value.absent(),
}) =>
@ -2172,6 +2258,8 @@ class $$TodosTableTableTableManager extends RootTableManager<
title: title,
content: content,
targetDate: targetDate,
someFloat: someFloat,
someInt64: someInt64,
category: category,
status: status,
),
@ -2180,6 +2268,8 @@ class $$TodosTableTableTableManager extends RootTableManager<
Value<String?> title = const Value.absent(),
required String content,
Value<DateTime?> targetDate = const Value.absent(),
Value<double?> someFloat = const Value.absent(),
Value<BigInt?> someInt64 = const Value.absent(),
Value<int?> category = const Value.absent(),
Value<TodoStatus?> status = const Value.absent(),
}) =>
@ -2188,6 +2278,8 @@ class $$TodosTableTableTableManager extends RootTableManager<
title: title,
content: content,
targetDate: targetDate,
someFloat: someFloat,
someInt64: someInt64,
category: category,
status: status,
)));
@ -2532,6 +2624,8 @@ class AllTodosWithCategoryResult extends CustomResultSet {
final String? title;
final String content;
final DateTime? targetDate;
final double? someFloat;
final BigInt? someInt64;
final int? category;
final TodoStatus? status;
final RowId catId;
@ -2542,14 +2636,16 @@ class AllTodosWithCategoryResult extends CustomResultSet {
this.title,
required this.content,
this.targetDate,
this.someFloat,
this.someInt64,
this.category,
this.status,
required this.catId,
required this.catDesc,
}) : super(row);
@override
int get hashCode => Object.hash(
id, title, content, targetDate, category, status, catId, catDesc);
int get hashCode => Object.hash(id, title, content, targetDate, someFloat,
someInt64, category, status, catId, catDesc);
@override
bool operator ==(Object other) =>
identical(this, other) ||
@ -2558,6 +2654,8 @@ class AllTodosWithCategoryResult extends CustomResultSet {
other.title == this.title &&
other.content == this.content &&
other.targetDate == this.targetDate &&
other.someFloat == this.someFloat &&
other.someInt64 == this.someInt64 &&
other.category == this.category &&
other.status == this.status &&
other.catId == this.catId &&
@ -2569,6 +2667,8 @@ class AllTodosWithCategoryResult extends CustomResultSet {
..write('title: $title, ')
..write('content: $content, ')
..write('targetDate: $targetDate, ')
..write('someFloat: $someFloat, ')
..write('someInt64: $someInt64, ')
..write('category: $category, ')
..write('status: $status, ')
..write('catId: $catId, ')

View File

@ -12,5 +12,459 @@ void main() {
db = TodoDb(testInMemoryDatabase());
});
// // Create a dataset for the tests
// schoolId = await db.managers.categories.create((o) =>
// o(priority: Value(CategoryPriority.high), description: "School"));
// workId = await db.managers.categories.create(
// (o) => o(priority: Value(CategoryPriority.low), description: "Work"));
// homeId = await db.managers.categories.create((o) =>
// o(priority: Value(CategoryPriority.medium), description: "Home"));
// otherId = await db.managers.categories.create(
// (o) => o(priority: Value(CategoryPriority.high), description: "Other"));
// // School
// await db.managers.todosTable.create((o) => o(
// content: "Get that math homework done",
// title: Value("Math Homework"),
// category: Value(schoolId),
// status: Value(TodoStatus.open),
// targetDate: Value(DateTime.now().add(Duration(days: 1,seconds: 10)))));
// await db.managers.todosTable.create((o) => o(
// content: "Finish that report",
// title: Value("Report"),
// category: Value(workId),
// status: Value(TodoStatus.workInProgress),
// targetDate: Value(DateTime.now().add(Duration(days: 2,seconds: 10)))));
// await db.managers.todosTable.create((o) => o(
// content: "Get that english homework done",
// title: Value("English Homework"),
// category: Value(schoolId),
// status: Value(TodoStatus.open),
// targetDate: Value(DateTime.now().add(Duration(days: 1,seconds: 15)))));
// await db.managers.todosTable.create((o) => o(
// content: "Finish that Book report",
// title: Value("Book Report"),
// category: Value(workId),
// status: Value(TodoStatus.done),
// targetDate: Value(DateTime.now().subtract(Duration(days: 2,seconds: 15)))));
// // Work
// await db.managers.todosTable.create((o) => o(
// content: "File those reports",
// title: Value("File Reports"),
// category: Value(workId),
// status: Value(TodoStatus.open),
// targetDate: Value(DateTime.now().add(Duration(days: 1, seconds: 20)))););
// await db.managers.todosTable.create((o) => o(
// content: "Clean the office",
// title: Value("Clean Office"),
// category: Value(workId),
// status: Value(TodoStatus.workInProgress),
// targetDate: Value(DateTime.now().add(Duration(days: 2, seconds: 20)))););
// await db.managers.todosTable.create((o) => o(
// content: "Nail that presentation",
// title: Value("Presentation"),
// category: Value(workId),
// status: Value(TodoStatus.open),
// targetDate: Value(DateTime.now().add(Duration(days: 1, seconds: 25)))));
// await db.managers.todosTable.create((o) => o(
// content: "Take a break",
// title: Value("Break"),
// category: Value(workId),
// status: Value(TodoStatus.done),
// targetDate: Value(DateTime.now().subtract(Duration(days: 2, seconds: 25)))));
// // Work
// await db.managers.todosTable.create((o) => o(
// content: "Take out the trash",
// title: Value("Trash"),
// category: Value(homeId),
// status: Value(TodoStatus.open),
// targetDate: Value(DateTime.now().add(Duration(days: 1, seconds: 30)))););
// await db.managers.todosTable.create((o) => o(
// content: "Mow the lawn",
// title: Value("Lawn"),
// category: Value(homeId),
// status: Value(TodoStatus.workInProgress),
// targetDate: Value(DateTime.now().add(Duration(days: 2, seconds: 30)))));
// await db.managers.todosTable.create((o) => o(
// content: "Fix the sink",
// title: Value("Sink"),
// category: Value(homeId),
// status: Value(TodoStatus.open),
// targetDate: Value(DateTime.now().add(Duration(days: 1, seconds: 35)))););
// await db.managers.todosTable.create((o) => o(
// content: "Paint the walls",
// title: Value("Paint"),
// category: Value(homeId),
// status: Value(TodoStatus.done),
// targetDate: Value(DateTime.now().subtract(Duration(days: 2, seconds: 35)))));
// // Other
// await db.managers.todosTable.create((o) => o(
// content: "Get groceries",
// title: Value("Groceries"),
// category: Value(otherId),
// status: Value(TodoStatus.open),
// targetDate: Value(DateTime.now().add(Duration(days: 1, seconds: 40)))););
// await db.managers.todosTable.create((o) => o(
// content: "Pick up the kids",
// title: Value("Kids"),
// category: Value(otherId),
// status: Value(TodoStatus.workInProgress),
// targetDate: Value(DateTime.now().add(Duration(days: 2, seconds: 40)))););
// await db.managers.todosTable.create((o) => o(
// content: "Take the dog for a walk",
// title: Value("Dog"),
// category: Value(otherId),
// status: Value(TodoStatus.open),
// targetDate: Value(DateTime.now().add(Duration(days: 1, seconds: 45)))));
// // Items with no category
// await db.managers.todosTable.create((o) => o(
// content: "Get Whiteboard",
// title: Value("Whiteboard"),
// status: Value(TodoStatus.open),
// targetDate: Value(DateTime.now().add(Duration(days: 1, seconds: 50)))););
// await db.managers.todosTable.create((o) => o(
// content: "Drink Water",
// title: Value("Water"),
// status: Value(TodoStatus.workInProgress),
// targetDate: Value(DateTime.now().add(Duration(days: 2, seconds: 50)))));
// });
tearDown(() => db.close());
test('manager - query generic', () async {
await db.managers.todosTable.create((o) => o(
content: "Get that math homework done",
status: Value(TodoStatus.open),
someFloat: Value(5.0),
targetDate: Value(DateTime.now().add(Duration(days: 1)))));
await db.managers.todosTable.create((o) => o(
content: "Get that math homework done",
status: Value(TodoStatus.open),
targetDate: Value(DateTime.now().add(Duration(days: 2)))));
await db.managers.todosTable.create((o) => o(
content: "Get that math homework done",
status: Value(TodoStatus.open),
someFloat: Value(3.0),
targetDate: Value(DateTime.now().add(Duration(days: 3)))));
// Equals
expect(
db.managers.todosTable.filter((f) => f.someFloat.equals(5.0)).count(),
completion(1));
expect(db.managers.todosTable.filter((f) => f.someFloat(3.0)).count(),
completion(1));
// In
expect(
db.managers.todosTable
.filter((f) => f.someFloat.isIn([3.0, 5.0]))
.count(),
completion(2));
// Not In
expect(
db.managers.todosTable
.filter((f) => f.someFloat.isNotIn([3.0, 5.0]))
.count(),
completion(0));
// Null check
expect(db.managers.todosTable.filter((f) => f.someFloat.isNull()).count(),
completion(1));
expect(
db.managers.todosTable.filter((f) => f.someFloat.isNotNull()).count(),
completion(2));
});
test('manager - query number', () async {
final objId1 = await db.managers.todosTable.create((o) => o(
content: "Get that math homework done",
status: Value(TodoStatus.open),
someFloat: Value(5.0),
targetDate: Value(DateTime.now().add(Duration(days: 1)))));
final objId2 = await db.managers.todosTable.create((o) => o(
content: "Get that math homework done",
status: Value(TodoStatus.open),
targetDate: Value(DateTime.now().add(Duration(days: 2)))));
final objId3 = await db.managers.todosTable.create((o) => o(
content: "Get that math homework done",
status: Value(TodoStatus.open),
someFloat: Value(3.0),
targetDate: Value(DateTime.now().add(Duration(days: 3)))));
// More than
expect(
db.managers.todosTable
.filter((f) => f.someFloat.isBiggerThan(3.0))
.count(),
completion(1));
expect(
db.managers.todosTable
.filter((f) => f.someFloat.isBiggerOrEqualTo(3.0))
.count(),
completion(2));
// Less than
expect(
db.managers.todosTable
.filter((f) => f.someFloat.isSmallerThan(5.0))
.count(),
completion(1));
expect(
db.managers.todosTable
.filter((f) => f.someFloat.isSmallerOrEqualTo(5.0))
.count(),
completion(2));
// Between
expect(
db.managers.todosTable
.filter((f) => f.someFloat.isBetween(3.0, 5.0))
.count(),
completion(2));
expect(
db.managers.todosTable
.filter((f) => f.someFloat.isNotBetween(3.0, 5.0))
.count(),
completion(0));
});
test('manager - query string', () async {
await db.managers.todosTable.create((o) => o(
content: "Get that math homework done",
status: Value(TodoStatus.open),
));
await db.managers.todosTable.create((o) => o(
content: "That homework Done",
));
await db.managers.todosTable.create((o) => o(
content: "that MATH homework",
status: Value(TodoStatus.open),
));
// StartsWith
expect(
db.managers.todosTable
.filter((f) => f.content.startsWith("that"))
.count(),
completion(2));
// EndsWith
expect(
db.managers.todosTable
.filter((f) => f.content.endsWith("done"))
.count(),
completion(2));
// Contains
expect(
db.managers.todosTable
.filter((f) => f.content.contains("math"))
.count(),
completion(2));
// Make the database case sensitive
await db.customStatement('PRAGMA case_sensitive_like = ON');
// StartsWith
expect(
db.managers.todosTable
.filter((f) => f.content.startsWith("that", caseInsensitive: false))
.count(),
completion(1));
// EndsWith
expect(
db.managers.todosTable
.filter((f) => f.content.endsWith("done", caseInsensitive: false))
.count(),
completion(1));
// Contains
expect(
db.managers.todosTable
.filter((f) => f.content.contains("math", caseInsensitive: false))
.count(),
completion(1));
});
test('manager - query int64', () async {
final objId1 = await db.managers.todosTable.create((o) => o(
content: "Get that math homework done",
status: Value(TodoStatus.open),
someInt64: Value(BigInt.from(5.0)),
targetDate: Value(DateTime.now().add(Duration(days: 1)))));
final objId2 = await db.managers.todosTable.create((o) => o(
content: "Get that math homework done",
status: Value(TodoStatus.open),
targetDate: Value(DateTime.now().add(Duration(days: 2)))));
final objId3 = await db.managers.todosTable.create((o) => o(
content: "Get that math homework done",
status: Value(TodoStatus.open),
someInt64: Value(BigInt.from(3.0)),
targetDate: Value(DateTime.now().add(Duration(days: 3)))));
// More than
expect(
db.managers.todosTable
.filter((f) => f.someInt64.isBiggerThan(BigInt.from(3.0)))
.count(),
completion(1));
expect(
db.managers.todosTable
.filter((f) => f.someInt64.isBiggerOrEqualTo(BigInt.from(3.0)))
.count(),
completion(2));
// Less than
expect(
db.managers.todosTable
.filter((f) => f.someInt64.isSmallerThan(BigInt.from(5.0)))
.count(),
completion(1));
expect(
db.managers.todosTable
.filter((f) => f.someInt64.isSmallerOrEqualTo(BigInt.from(5.0)))
.count(),
completion(2));
// Between
expect(
db.managers.todosTable
.filter((f) =>
f.someInt64.isBetween(BigInt.from(3.0), BigInt.from(5.0)))
.count(),
completion(2));
expect(
db.managers.todosTable
.filter((f) =>
f.someInt64.isNotBetween(BigInt.from(3.0), BigInt.from(5.0)))
.count(),
completion(0));
});
test('manager - query bool', () async {
final objId1 = await db.managers.users.create((o) => o(
name: "John Doe",
profilePicture: Uint8List(0),
isAwesome: Value(true),
creationTime: Value(DateTime.now().add(Duration(days: 1)))));
final objId2 = await db.managers.users.create((o) => o(
name: "Jane Doe1",
profilePicture: Uint8List(0),
isAwesome: Value(false),
creationTime: Value(DateTime.now().add(Duration(days: 2)))));
final objId3 = await db.managers.users.create((o) => o(
name: "Jane Doe2",
profilePicture: Uint8List(0),
isAwesome: Value(true),
creationTime: Value(DateTime.now().add(Duration(days: 2)))));
// False
expect(db.managers.users.filter((f) => f.isAwesome.isFalse()).count(),
completion(1));
// True
expect(db.managers.users.filter((f) => f.isAwesome.isTrue()).count(),
completion(2));
});
test('manager - query datetime', () async {
final day1 = DateTime.now().add(Duration(days: 1));
final day2 = DateTime.now().add(Duration(days: 2));
final day3 = DateTime.now().add(Duration(days: 3));
final objId1 = await db.managers.todosTable.create((o) => o(
content: "Get that math homework done",
status: Value(TodoStatus.open),
someFloat: Value(5.0),
targetDate: Value(day1)));
final objId2 = await db.managers.todosTable.create((o) => o(
content: "Get that math homework done",
status: Value(TodoStatus.open),
targetDate: Value(day2)));
final objId3 = await db.managers.todosTable.create((o) => o(
content: "Get that math homework done",
status: Value(TodoStatus.open),
someFloat: Value(3.0),
targetDate: Value(day3)));
// More than
expect(
db.managers.todosTable
.filter((f) => f.targetDate.isAfter(day2))
.count(),
completion(1));
expect(
db.managers.todosTable
.filter((f) => f.targetDate.isAfterOrOn(day2))
.count(),
completion(2));
// Less than
expect(
db.managers.todosTable
.filter((f) => f.targetDate.isBefore(day2))
.count(),
completion(1));
expect(
db.managers.todosTable
.filter((f) => f.targetDate.isBeforeOrOn(day2))
.count(),
completion(2));
// Between
expect(
db.managers.todosTable
.filter((f) => f.targetDate.isBetween(day1, day2))
.count(),
completion(2));
expect(
db.managers.todosTable
.filter((f) => f.targetDate.isNotBetween(day1, day2))
.count(),
completion(1));
});
test('manager - query custom column', () async {
final objId1 = await db.managers.todosTable.create((o) => o(
content: "Get that math homework done",
status: Value(TodoStatus.open)));
final objId2 = await db.managers.todosTable.create((o) => o(
content: "Get that math homework done",
status: Value(TodoStatus.open)));
final objId3 = await db.managers.todosTable.create((o) => o(
content: "Get that math homework done",
status: Value(TodoStatus.workInProgress)));
final objId4 = await db.managers.todosTable.create((o) => o(
content: "Get that math homework done",
status: Value(TodoStatus.done)));
// Equals
expect(
db.managers.todosTable
.filter((f) => f.status.equals(TodoStatus.open))
.count(),
completion(2));
expect(
db.managers.todosTable.filter((f) => f.status(TodoStatus.open)).count(),
completion(2));
// In
expect(
db.managers.todosTable
.filter((f) =>
f.status.isIn([TodoStatus.open, TodoStatus.workInProgress]))
.count(),
completion(3));
// Not In
expect(
db.managers.todosTable
.filter((f) =>
f.status.isNotIn([TodoStatus.open, TodoStatus.workInProgress]))
.count(),
completion(1));
});
}