mirror of https://github.com/AMT-Cheif/drift.git
1) Apply Limit to Single Getting
2) Move Distict to positional arg 3) Add limit as a positional arg 4) Fix _tests.dart to _test.dart for CI 5) Move all methods to base - Remove all()
This commit is contained in:
parent
f17c251126
commit
4c7f7402c1
|
@ -283,24 +283,28 @@ class TableManagerState<
|
||||||
/// This is so that the state can be passed down to lower level managers
|
/// This is so that the state can be passed down to lower level managers
|
||||||
@internal
|
@internal
|
||||||
abstract class BaseTableManager<
|
abstract class BaseTableManager<
|
||||||
DB extends GeneratedDatabase,
|
DB extends GeneratedDatabase,
|
||||||
T extends Table,
|
T extends Table,
|
||||||
DT extends DataClass,
|
DT extends DataClass,
|
||||||
FS extends FilterComposer<DB, T>,
|
FS extends FilterComposer<DB, T>,
|
||||||
OS extends OrderingComposer<DB, T>,
|
OS extends OrderingComposer<DB, T>,
|
||||||
C extends ProcessedTableManager<DB, T, DT, FS, OS, C, CI, CU>,
|
C extends ProcessedTableManager<DB, T, DT, FS, OS, C, CI, CU>,
|
||||||
CI extends Function,
|
CI extends Function,
|
||||||
CU extends Function> {
|
CU extends Function>
|
||||||
|
implements
|
||||||
|
MultiSelectable<DT>,
|
||||||
|
SingleSelectable<DT>,
|
||||||
|
SingleOrNullSelectable<DT> {
|
||||||
/// The state for this manager
|
/// The state for this manager
|
||||||
final TableManagerState<DB, T, DT, FS, OS, C, CI, CU> $state;
|
final TableManagerState<DB, T, DT, FS, OS, C, CI, CU> $state;
|
||||||
|
|
||||||
/// Create a new [BaseTableManager] instance
|
/// Create a new [BaseTableManager] instance
|
||||||
const BaseTableManager(this.$state);
|
const BaseTableManager(this.$state);
|
||||||
|
|
||||||
/// Set the distinct flag on the statement to true
|
/// Add a limit to the statement
|
||||||
/// This will ensure that only distinct rows are returned
|
C limit(int limit, {int? offset}) {
|
||||||
C distict() {
|
return $state
|
||||||
return $state._getChildManagerBuilder($state.copyWith(distinct: true));
|
._getChildManagerBuilder($state.copyWith(limit: limit, offset: offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add ordering to the statement
|
/// Add ordering to the statement
|
||||||
|
@ -322,12 +326,6 @@ abstract class BaseTableManager<
|
||||||
joinBuilders: $state.joinBuilders.union(filter.joinBuilders)));
|
joinBuilders: $state.joinBuilders.union(filter.joinBuilders)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a limit to the statement
|
|
||||||
C limit(int limit, {int? offset}) {
|
|
||||||
return $state
|
|
||||||
._getChildManagerBuilder($state.copyWith(limit: limit, offset: offset));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Writes all non-null fields from the entity into the columns of all rows
|
/// Writes all non-null fields from the entity into the columns of all rows
|
||||||
/// that match the [filter] clause. Warning: That also means that, when you're
|
/// that match the [filter] clause. Warning: That also means that, when you're
|
||||||
/// not setting a where clause explicitly, this method will update all rows in
|
/// not setting a where clause explicitly, this method will update all rows in
|
||||||
|
@ -351,25 +349,6 @@ abstract class BaseTableManager<
|
||||||
|
|
||||||
/// Checks whether any rows exist
|
/// Checks whether any rows exist
|
||||||
Future<bool> exists() => $state.exists();
|
Future<bool> exists() => $state.exists();
|
||||||
}
|
|
||||||
|
|
||||||
/// A table manager that can be used to select rows from a table
|
|
||||||
abstract class ProcessedTableManager<
|
|
||||||
DB extends GeneratedDatabase,
|
|
||||||
T extends Table,
|
|
||||||
D extends DataClass,
|
|
||||||
FS extends FilterComposer<DB, T>,
|
|
||||||
OS extends OrderingComposer<DB, T>,
|
|
||||||
C extends ProcessedTableManager<DB, T, D, FS, OS, C, CI, CU>,
|
|
||||||
CI extends Function,
|
|
||||||
CU extends Function>
|
|
||||||
extends BaseTableManager<DB, T, D, FS, OS, C, CI, CU>
|
|
||||||
implements
|
|
||||||
MultiSelectable<D>,
|
|
||||||
SingleSelectable<D>,
|
|
||||||
SingleOrNullSelectable<D> {
|
|
||||||
/// Create a new [ProcessedTableManager] instance
|
|
||||||
const ProcessedTableManager(super.$state);
|
|
||||||
|
|
||||||
/// Deletes all rows matched by built statement
|
/// Deletes all rows matched by built statement
|
||||||
///
|
///
|
||||||
|
@ -390,25 +369,47 @@ abstract class ProcessedTableManager<
|
||||||
///
|
///
|
||||||
/// See also: [getSingleOrNull], which returns `null` instead of
|
/// See also: [getSingleOrNull], which returns `null` instead of
|
||||||
/// throwing if the query completes with no rows.
|
/// throwing if the query completes with no rows.
|
||||||
|
///
|
||||||
|
/// Uses the distinct flag to ensure that only distinct rows are returned
|
||||||
@override
|
@override
|
||||||
Future<D> getSingle() => $state.buildSelectStatement().getSingle();
|
Future<DT> getSingle() =>
|
||||||
|
$state.copyWith(distinct: true).buildSelectStatement().getSingle();
|
||||||
|
|
||||||
/// Creates an auto-updating stream of this statement, similar to
|
/// Creates an auto-updating stream of this statement, similar to
|
||||||
/// [watch]. However, it is assumed that the query will only emit
|
/// [watch]. However, it is assumed that the query will only emit
|
||||||
/// one result, so instead of returning a `Stream<List<D>>`, this returns a
|
/// one result, so instead of returning a `Stream<List<D>>`, this returns a
|
||||||
/// `Stream<D>`. If, at any point, the query emits no or more than one rows,
|
/// `Stream<D>`. If, at any point, the query emits no or more than one rows,
|
||||||
/// an error will be added to the stream instead.
|
/// an error will be added to the stream instead.
|
||||||
|
///
|
||||||
|
/// Uses the distinct flag to ensure that only distinct rows are returned
|
||||||
@override
|
@override
|
||||||
Stream<D> watchSingle() => $state.buildSelectStatement().watchSingle();
|
Stream<DT> watchSingle() =>
|
||||||
|
$state.copyWith(distinct: true).buildSelectStatement().watchSingle();
|
||||||
|
|
||||||
/// Executes the statement and returns the first all rows as a list.
|
/// Executes the statement and returns the first all rows as a list.
|
||||||
|
///
|
||||||
|
/// Use [limit] and [offset] to limit the number of rows returned
|
||||||
|
/// An offset will only be applied if a limit is also set
|
||||||
|
/// Set [distinct] to true to ensure that only distinct rows are returned
|
||||||
@override
|
@override
|
||||||
Future<List<D>> get() => $state.buildSelectStatement().get();
|
Future<List<DT>> get({bool distinct = false, int? limit, int? offset}) =>
|
||||||
|
$state
|
||||||
|
.copyWith(distinct: distinct, limit: limit, offset: offset)
|
||||||
|
.buildSelectStatement()
|
||||||
|
.get();
|
||||||
|
|
||||||
/// Creates an auto-updating stream of the result that emits new items
|
/// Creates an auto-updating stream of the result that emits new items
|
||||||
/// whenever any table used in this statement changes.
|
/// whenever any table used in this statement changes.
|
||||||
|
///
|
||||||
|
/// Use [limit] and [offset] to limit the number of rows returned
|
||||||
|
/// An offset will only be applied if a limit is also set
|
||||||
|
/// Set [distinct] to true to ensure that only distinct rows are returned
|
||||||
@override
|
@override
|
||||||
Stream<List<D>> watch() => $state.buildSelectStatement().watch();
|
Stream<List<DT>> watch({bool distinct = false, int? limit, int? offset}) =>
|
||||||
|
$state
|
||||||
|
.copyWith(distinct: distinct, limit: limit, offset: offset)
|
||||||
|
.buildSelectStatement()
|
||||||
|
.watch();
|
||||||
|
|
||||||
/// Executes this statement, like [get], but only returns one
|
/// Executes this statement, like [get], but only returns one
|
||||||
/// value. If the result too many values, this method will throw. If no
|
/// value. If the result too many values, this method will throw. If no
|
||||||
|
@ -416,9 +417,11 @@ abstract class ProcessedTableManager<
|
||||||
///
|
///
|
||||||
/// See also: [getSingle], which can be used if the query will
|
/// See also: [getSingle], which can be used if the query will
|
||||||
/// always evaluate to exactly one row.
|
/// always evaluate to exactly one row.
|
||||||
|
///
|
||||||
|
/// Uses the distinct flag to ensure that only distinct rows are returned
|
||||||
@override
|
@override
|
||||||
Future<D?> getSingleOrNull() =>
|
Future<DT?> getSingleOrNull() =>
|
||||||
$state.buildSelectStatement().getSingleOrNull();
|
$state.copyWith(distinct: true).buildSelectStatement().getSingleOrNull();
|
||||||
|
|
||||||
/// Creates an auto-updating stream of this statement, similar to
|
/// Creates an auto-updating stream of this statement, similar to
|
||||||
/// [watch]. However, it is assumed that the query will only
|
/// [watch]. However, it is assumed that the query will only
|
||||||
|
@ -427,9 +430,33 @@ abstract class ProcessedTableManager<
|
||||||
/// some point, an error will be emitted to the stream instead.
|
/// some point, an error will be emitted to the stream instead.
|
||||||
/// If the query emits zero rows at some point, `null` will be added
|
/// If the query emits zero rows at some point, `null` will be added
|
||||||
/// to the stream instead.
|
/// to the stream instead.
|
||||||
|
///
|
||||||
|
/// Uses the distinct flag to ensure that only distinct rows are returned
|
||||||
@override
|
@override
|
||||||
Stream<D?> watchSingleOrNull() =>
|
Stream<DT?> watchSingleOrNull() => $state
|
||||||
$state.buildSelectStatement().watchSingleOrNull();
|
.copyWith(distinct: true)
|
||||||
|
.buildSelectStatement()
|
||||||
|
.watchSingleOrNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A table manager that exposes methods to a table manager that already has filters/orderings/limit applied
|
||||||
|
// As of now this is identical to [BaseTableManager] but it's kept seperate for future extensibility
|
||||||
|
class ProcessedTableManager<
|
||||||
|
DB extends GeneratedDatabase,
|
||||||
|
T extends Table,
|
||||||
|
D extends DataClass,
|
||||||
|
FS extends FilterComposer<DB, T>,
|
||||||
|
OS extends OrderingComposer<DB, T>,
|
||||||
|
C extends ProcessedTableManager<DB, T, D, FS, OS, C, CI, CU>,
|
||||||
|
CI extends Function,
|
||||||
|
CU extends Function>
|
||||||
|
extends BaseTableManager<DB, T, D, FS, OS, C, CI, CU>
|
||||||
|
implements
|
||||||
|
MultiSelectable<D>,
|
||||||
|
SingleSelectable<D>,
|
||||||
|
SingleOrNullSelectable<D> {
|
||||||
|
/// Create a new [ProcessedTableManager] instance
|
||||||
|
const ProcessedTableManager(super.$state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A table manager with top level function for creating, reading, updating, and deleting items
|
/// A table manager with top level function for creating, reading, updating, and deleting items
|
||||||
|
@ -445,16 +472,6 @@ abstract class RootTableManager<
|
||||||
/// Create a new [RootTableManager] instance
|
/// Create a new [RootTableManager] instance
|
||||||
const RootTableManager(super.$state);
|
const RootTableManager(super.$state);
|
||||||
|
|
||||||
/// Deletes all rows matched by built statement
|
|
||||||
///
|
|
||||||
/// Returns the amount of rows that were deleted by this statement directly
|
|
||||||
/// (not including additional rows that might be affected through triggers or
|
|
||||||
/// foreign key constraints).
|
|
||||||
Future<int> delete() => $state.db.delete($state._tableAsTableInfo).go();
|
|
||||||
|
|
||||||
/// Select all rows from the table
|
|
||||||
C all() => $state._getChildManagerBuilder($state);
|
|
||||||
|
|
||||||
/// Creates a new row in the table using the given function
|
/// Creates a new row in the table using the given function
|
||||||
///
|
///
|
||||||
/// By default, an exception will be thrown if another row with the same
|
/// By default, an exception will be thrown if another row with the same
|
||||||
|
|
|
@ -533,7 +533,6 @@ void main() {
|
||||||
db.managers.categories
|
db.managers.categories
|
||||||
.filter((f) => f.todos((f) => f.category(
|
.filter((f) => f.todos((f) => f.category(
|
||||||
(f) => f.todos((f) => f.title.equals("Math Homework")))))
|
(f) => f.todos((f) => f.title.equals("Math Homework")))))
|
||||||
.distict()
|
|
||||||
.getSingle()
|
.getSingle()
|
||||||
.then((value) => value.description),
|
.then((value) => value.description),
|
||||||
completion("School"));
|
completion("School"));
|
|
@ -16,19 +16,19 @@ void main() {
|
||||||
|
|
||||||
test('manager - create', () async {
|
test('manager - create', () async {
|
||||||
// Initial count should be 0
|
// Initial count should be 0
|
||||||
expect(db.managers.categories.all().count(), completion(0));
|
expect(db.managers.categories.count(), completion(0));
|
||||||
|
|
||||||
// Creating a row should return the id
|
// Creating a row should return the id
|
||||||
final create1 = db.managers.categories.create(
|
final create1 = db.managers.categories.create(
|
||||||
(o) => o(priority: Value(CategoryPriority.high), description: "High"));
|
(o) => o(priority: Value(CategoryPriority.high), description: "High"));
|
||||||
expect(create1, completion(1));
|
expect(create1, completion(1));
|
||||||
expect(db.managers.categories.all().count(), completion(1));
|
expect(db.managers.categories.count(), completion(1));
|
||||||
|
|
||||||
// Creating another row should increment the id
|
// Creating another row should increment the id
|
||||||
final create2 = db.managers.categories.create(
|
final create2 = db.managers.categories.create(
|
||||||
(o) => o(priority: Value(CategoryPriority.low), description: "Low"));
|
(o) => o(priority: Value(CategoryPriority.low), description: "Low"));
|
||||||
expect(create2, completion(2));
|
expect(create2, completion(2));
|
||||||
expect(db.managers.categories.all().count(), completion(2));
|
expect(db.managers.categories.count(), completion(2));
|
||||||
|
|
||||||
// Using an existing id should throw an exception
|
// Using an existing id should throw an exception
|
||||||
final create3 = db.managers.categories.create((o) => o(
|
final create3 = db.managers.categories.create((o) => o(
|
||||||
|
@ -47,7 +47,7 @@ void main() {
|
||||||
onConflict: DoNothing());
|
onConflict: DoNothing());
|
||||||
// The is incorrect when using onConflict
|
// The is incorrect when using onConflict
|
||||||
expect(create4, completion(2));
|
expect(create4, completion(2));
|
||||||
expect(db.managers.categories.all().count(), completion(2));
|
expect(db.managers.categories.count(), completion(2));
|
||||||
|
|
||||||
// Likewise, test that mode is passed to the create method
|
// Likewise, test that mode is passed to the create method
|
||||||
final create5 = db.managers.categories.create(
|
final create5 = db.managers.categories.create(
|
||||||
|
@ -59,13 +59,13 @@ void main() {
|
||||||
|
|
||||||
// The is incorrect when using mode
|
// The is incorrect when using mode
|
||||||
expect(create5, completion(2));
|
expect(create5, completion(2));
|
||||||
expect(db.managers.categories.all().count(), completion(2));
|
expect(db.managers.categories.count(), completion(2));
|
||||||
|
|
||||||
// Test the other create methods
|
// Test the other create methods
|
||||||
final create6 = db.managers.categories.createReturning((o) =>
|
final create6 = db.managers.categories.createReturning((o) =>
|
||||||
o(priority: Value(CategoryPriority.high), description: "Other High"));
|
o(priority: Value(CategoryPriority.high), description: "Other High"));
|
||||||
expect(create6, completion(isA<Category>()));
|
expect(create6, completion(isA<Category>()));
|
||||||
expect(db.managers.categories.all().count(), completion(3));
|
expect(db.managers.categories.count(), completion(3));
|
||||||
|
|
||||||
// Will return null because the description is not unique
|
// Will return null because the description is not unique
|
||||||
final create7 = db.managers.categories.createReturningOrNull(
|
final create7 = db.managers.categories.createReturningOrNull(
|
||||||
|
@ -84,7 +84,7 @@ void main() {
|
||||||
priority: Value(CategoryPriority.medium),
|
priority: Value(CategoryPriority.medium),
|
||||||
description: "Super Medium")
|
description: "Super Medium")
|
||||||
]);
|
]);
|
||||||
expect(db.managers.categories.all().count(), completion(6));
|
expect(db.managers.categories.count(), completion(6));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('manager - update', () async {
|
test('manager - update', () async {
|
||||||
|
@ -135,11 +135,11 @@ void main() {
|
||||||
final delete1 =
|
final delete1 =
|
||||||
db.managers.categories.filter(((f) => f.id(obj1.id))).delete();
|
db.managers.categories.filter(((f) => f.id(obj1.id))).delete();
|
||||||
expect(delete1, completion(1));
|
expect(delete1, completion(1));
|
||||||
expect(db.managers.categories.all().count(), completion(1));
|
expect(db.managers.categories.count(), completion(1));
|
||||||
|
|
||||||
// Delete all rows
|
// Delete all rows
|
||||||
final delete2 = db.managers.categories.delete();
|
final delete2 = db.managers.categories.delete();
|
||||||
expect(delete2, completion(1));
|
expect(delete2, completion(1));
|
||||||
expect(db.managers.categories.all().count(), completion(0));
|
expect(db.managers.categories.count(), completion(0));
|
||||||
});
|
});
|
||||||
}
|
}
|
|
@ -29,18 +29,16 @@ void main() {
|
||||||
aReal: Value(3.0),
|
aReal: Value(3.0),
|
||||||
aDateTime: Value(DateTime.now().add(Duration(days: 3)))));
|
aDateTime: Value(DateTime.now().add(Duration(days: 3)))));
|
||||||
// Test count
|
// Test count
|
||||||
expect(db.managers.tableWithEveryColumnType.all().count(), completion(3));
|
expect(db.managers.tableWithEveryColumnType.count(), completion(3));
|
||||||
// Test get
|
// Test get
|
||||||
expect(
|
expect(
|
||||||
db.managers.tableWithEveryColumnType
|
db.managers.tableWithEveryColumnType
|
||||||
.all()
|
|
||||||
.get()
|
.get()
|
||||||
.then((value) => value.length),
|
.then((value) => value.length),
|
||||||
completion(3));
|
completion(3));
|
||||||
// Test getSingle with limit
|
// Test getSingle with limit
|
||||||
expect(
|
expect(
|
||||||
db.managers.tableWithEveryColumnType
|
db.managers.tableWithEveryColumnType
|
||||||
.all()
|
|
||||||
.limit(1, offset: 1)
|
.limit(1, offset: 1)
|
||||||
.getSingle()
|
.getSingle()
|
||||||
.then((value) => value.id),
|
.then((value) => value.id),
|
Loading…
Reference in New Issue