mirror of https://github.com/AMT-Cheif/drift.git
Refactor ordering - Add better Docs
This commit is contained in:
parent
1da0664c08
commit
46953c3a73
|
@ -21,7 +21,7 @@ class ComposerState<DB extends GeneratedDatabase, T extends Table>
|
||||||
/// Get a random alias for a table
|
/// Get a random alias for a table
|
||||||
String _getRandomAlias(TableInfo table) {
|
String _getRandomAlias(TableInfo table) {
|
||||||
var aliasName = '${table.actualTableName}__${Random().nextInt(4294967296)}';
|
var aliasName = '${table.actualTableName}__${Random().nextInt(4294967296)}';
|
||||||
while (joinBuilders.aliasedNames.contains(aliasName)) {
|
while (joinBuilders.map((e) => (e.aliasedName)).contains(aliasName)) {
|
||||||
aliasName = '${table.actualTableName}__${Random().nextInt(4294967296)}';
|
aliasName = '${table.actualTableName}__${Random().nextInt(4294967296)}';
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -44,10 +44,26 @@ class AliasedComposerBuilder<DB extends GeneratedDatabase, RT extends Table,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Base class for all query composers
|
/// Base class for all composers
|
||||||
|
///
|
||||||
|
/// Any class that can be composed using the `&` or `|` operator is called a composable,
|
||||||
|
/// and must implement the [HasJoinBuilders] interface. [ComposableFilter] and [ComposableOrdering] are examples of composable classes.
|
||||||
|
///
|
||||||
|
/// The [Composer] class is a top level manager for this operation.
|
||||||
|
/// ```dart
|
||||||
|
/// filter((f) => f.id.equals(1) & f.name.equals('Bob'));
|
||||||
|
/// ```
|
||||||
|
/// `f` in this example is a [Composer] object, and `f.id.equals(1) & f.name.equals('Bob')` is a [ComposableFilter] object.
|
||||||
|
///
|
||||||
|
/// The [Composer] class is responsible for creating joins between tables, and passing them down to the composable classes.
|
||||||
|
/// This is done to ensure that duplicate joins are never created.
|
||||||
|
///
|
||||||
|
/// The [ComposerState] that is held in this class only holds temporary state, as the final state will be held in the composable classes.
|
||||||
|
/// E.G. In the example above, the resulting [ComposableFilter] object is returned, and the [FilterComposer] is discarded.
|
||||||
|
///
|
||||||
@internal
|
@internal
|
||||||
sealed class Composer<DB extends GeneratedDatabase, CT extends Table> {
|
sealed class Composer<DB extends GeneratedDatabase, CT extends Table> {
|
||||||
/// The state of the query composer
|
/// The state of the composer
|
||||||
final ComposerState<DB, CT> state;
|
final ComposerState<DB, CT> state;
|
||||||
|
|
||||||
Composer.withAliasedTable(AliasedComposerBuilder<DB, dynamic, CT> data)
|
Composer.withAliasedTable(AliasedComposerBuilder<DB, dynamic, CT> data)
|
||||||
|
@ -55,9 +71,7 @@ sealed class Composer<DB extends GeneratedDatabase, CT extends Table> {
|
||||||
data.state.db, data.aliasedTable, data.state.joinBuilders);
|
data.state.db, data.aliasedTable, data.state.joinBuilders);
|
||||||
Composer.empty(DB db, CT table) : state = ComposerState._(db, table, {});
|
Composer.empty(DB db, CT table) : state = ComposerState._(db, table, {});
|
||||||
|
|
||||||
/// Helper method for creaing an aliased join
|
/// Method for create a join between two tables
|
||||||
/// and adding it to the state and Composable object
|
|
||||||
|
|
||||||
B referenced<RT extends Table, QC extends Composer<DB, RT>,
|
B referenced<RT extends Table, QC extends Composer<DB, RT>,
|
||||||
B extends HasJoinBuilders>({
|
B extends HasJoinBuilders>({
|
||||||
required GeneratedColumn Function(CT) getCurrentColumn,
|
required GeneratedColumn Function(CT) getCurrentColumn,
|
||||||
|
@ -107,8 +121,6 @@ sealed class Composer<DB extends GeneratedDatabase, CT extends Table> {
|
||||||
// that state doesnt have, it is also possible that the result is missing
|
// that state doesnt have, it is also possible that the result is missing
|
||||||
// the `joinBuilder` we create above.
|
// the `joinBuilder` we create above.
|
||||||
// We will combine both sets and set it to `state.joinBuilders` and `result.joinBuilders`
|
// We will combine both sets and set it to `state.joinBuilders` and `result.joinBuilders`
|
||||||
|
|
||||||
// Add the joins that may have been created in the filterBuilder to state
|
|
||||||
for (var joinBuilder in result.joinBuilders.union(state.joinBuilders)) {
|
for (var joinBuilder in result.joinBuilders.union(state.joinBuilders)) {
|
||||||
state.addJoinBuilder(joinBuilder);
|
state.addJoinBuilder(joinBuilder);
|
||||||
result.addJoinBuilder(joinBuilder);
|
result.addJoinBuilder(joinBuilder);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
part of 'manager.dart';
|
part of 'manager.dart';
|
||||||
|
|
||||||
/// Defines a class that can be used to compose filters for a column
|
/// Defines a class which is used to wrap a column to only expose filter functions
|
||||||
class ColumnFilters<T extends Object> {
|
class ColumnFilters<T extends Object> {
|
||||||
/// This class is a wrapper on top of the generated column class
|
/// This class is a wrapper on top of the generated column class
|
||||||
///
|
///
|
||||||
|
@ -18,111 +18,99 @@ class ColumnFilters<T extends Object> {
|
||||||
/// Column that this [ColumnFilters] wraps
|
/// Column that this [ColumnFilters] wraps
|
||||||
GeneratedColumn<T> column;
|
GeneratedColumn<T> column;
|
||||||
|
|
||||||
// ignore: public_member_api_docs
|
/// Create a filter that checks if the column is null.
|
||||||
ComposableFilter isNull() => ComposableFilter.simple(column.isNull());
|
ComposableFilter isNull() => ComposableFilter.simple(column.isNull());
|
||||||
// ignore: public_member_api_docs
|
|
||||||
|
/// Create a filter that checks if the column is not null.
|
||||||
ComposableFilter isNotNull() => ComposableFilter.simple(column.isNotNull());
|
ComposableFilter isNotNull() => ComposableFilter.simple(column.isNotNull());
|
||||||
// ignore: public_member_api_docs
|
|
||||||
|
/// Create a filter that checks if the column equals a value.
|
||||||
ComposableFilter equals(T value) =>
|
ComposableFilter equals(T value) =>
|
||||||
ComposableFilter.simple(column.equals(value));
|
ComposableFilter.simple(column.equals(value));
|
||||||
|
|
||||||
|
/// Create a filter that checks if the column equals a value.
|
||||||
|
ComposableFilter call(T value) =>
|
||||||
|
ComposableFilter.simple(column.equals(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Built in filters for int/double columns
|
/// Built in filters for int/double columns
|
||||||
extension NumFilters<T extends num> on ColumnFilters<T> {
|
extension NumFilters<T extends num> on ColumnFilters<T> {
|
||||||
// ignore: public_member_api_docs
|
/// Create a filter to check if the column is bigger than a value
|
||||||
ComposableFilter isBiggerThan(T value) =>
|
ComposableFilter isBiggerThan(T value) =>
|
||||||
ComposableFilter.simple(column.isBiggerThanValue(value));
|
ComposableFilter.simple(column.isBiggerThanValue(value));
|
||||||
// ignore: public_member_api_docs
|
|
||||||
ComposableFilter isNotBiggerThan(T value) => isBiggerThan(value)._reversed();
|
/// Create a filter to check if the column is small than a value
|
||||||
// ignore: public_member_api_docs
|
|
||||||
ComposableFilter isSmallerThan(T value) =>
|
ComposableFilter isSmallerThan(T value) =>
|
||||||
ComposableFilter.simple(column.isSmallerThanValue(value));
|
ComposableFilter.simple(column.isSmallerThanValue(value));
|
||||||
// ignore: public_member_api_docs
|
|
||||||
ComposableFilter isNotSmallerThan(T value) =>
|
/// Create a filter to check if the column is bigger or equal to a value
|
||||||
isSmallerThan(value)._reversed();
|
|
||||||
// ignore: public_member_api_docs
|
|
||||||
ComposableFilter isBiggerOrEqualTo(T value) =>
|
ComposableFilter isBiggerOrEqualTo(T value) =>
|
||||||
ComposableFilter.simple(column.isBiggerOrEqualValue(value));
|
ComposableFilter.simple(column.isBiggerOrEqualValue(value));
|
||||||
// ignore: public_member_api_docs
|
|
||||||
ComposableFilter isNotBiggerOrEqualTo(T value) =>
|
/// Create a filter to check if the column is small or equal to a value
|
||||||
isBiggerOrEqualTo(value)._reversed();
|
|
||||||
// ignore: public_member_api_docs
|
|
||||||
ComposableFilter isSmallerOrEqualTo(T value) =>
|
ComposableFilter isSmallerOrEqualTo(T value) =>
|
||||||
ComposableFilter.simple(column.isSmallerOrEqualValue(value));
|
ComposableFilter.simple(column.isSmallerOrEqualValue(value));
|
||||||
// ignore: public_member_api_docs
|
|
||||||
ComposableFilter isNotSmallerOrEqualTo(T value) =>
|
/// Create a filter to check if the column is between two values
|
||||||
isSmallerOrEqualTo(value)._reversed();
|
|
||||||
// ignore: public_member_api_docs
|
|
||||||
ComposableFilter isBetween(T lower, T higher) =>
|
ComposableFilter isBetween(T lower, T higher) =>
|
||||||
ComposableFilter.simple(column.isBetweenValues(lower, higher));
|
ComposableFilter.simple(column.isBetweenValues(lower, higher));
|
||||||
// ignore: public_member_api_docs
|
|
||||||
|
/// Create a filter to check if the column is not between two values
|
||||||
ComposableFilter isNotBetween(T lower, T higher) =>
|
ComposableFilter isNotBetween(T lower, T higher) =>
|
||||||
isBetween(lower, higher)._reversed();
|
isBetween(lower, higher)._reversed();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Built in filters for BigInt columns
|
/// Built in filters for BigInt columns
|
||||||
extension BigIntFilters<T extends BigInt> on ColumnFilters<T> {
|
extension BigIntFilters<T extends BigInt> on ColumnFilters<T> {
|
||||||
// ignore: public_member_api_docs
|
/// Create a filter to check if the column is bigger than a value
|
||||||
ComposableFilter isBiggerThan(T value) =>
|
ComposableFilter isBiggerThan(T value) =>
|
||||||
ComposableFilter.simple(column.isBiggerThanValue(value));
|
ComposableFilter.simple(column.isBiggerThanValue(value));
|
||||||
// ignore: public_member_api_docs
|
|
||||||
ComposableFilter isNotBiggerThan(T value) => isBiggerThan(value)._reversed();
|
/// Create a filter to check if the column is small than a value
|
||||||
// ignore: public_member_api_docs
|
|
||||||
ComposableFilter isSmallerThan(T value) =>
|
ComposableFilter isSmallerThan(T value) =>
|
||||||
ComposableFilter.simple(column.isSmallerThanValue(value));
|
ComposableFilter.simple(column.isSmallerThanValue(value));
|
||||||
// ignore: public_member_api_docs
|
|
||||||
ComposableFilter isNotSmallerThan(T value) =>
|
/// Create a filter to check if the column is bigger or equal to a value
|
||||||
isSmallerThan(value)._reversed();
|
|
||||||
// ignore: public_member_api_docs
|
|
||||||
ComposableFilter isBiggerOrEqualTo(T value) =>
|
ComposableFilter isBiggerOrEqualTo(T value) =>
|
||||||
ComposableFilter.simple(column.isBiggerOrEqualValue(value));
|
ComposableFilter.simple(column.isBiggerOrEqualValue(value));
|
||||||
// ignore: public_member_api_docs
|
|
||||||
ComposableFilter isNotBiggerOrEqualTo(T value) =>
|
/// Create a filter to check if the column is small or equal to a value
|
||||||
isBiggerOrEqualTo(value)._reversed();
|
|
||||||
// ignore: public_member_api_docs
|
|
||||||
ComposableFilter isSmallerOrEqualTo(T value) =>
|
ComposableFilter isSmallerOrEqualTo(T value) =>
|
||||||
ComposableFilter.simple(column.isSmallerOrEqualValue(value));
|
ComposableFilter.simple(column.isSmallerOrEqualValue(value));
|
||||||
// ignore: public_member_api_docs
|
|
||||||
ComposableFilter isNotSmallerOrEqualTo(T value) =>
|
/// Create a filter to check if the column is between two values
|
||||||
isSmallerOrEqualTo(value)._reversed();
|
|
||||||
// ignore: public_member_api_docs
|
|
||||||
ComposableFilter isBetween(T lower, T higher) =>
|
ComposableFilter isBetween(T lower, T higher) =>
|
||||||
ComposableFilter.simple(column.isBetweenValues(lower, higher));
|
ComposableFilter.simple(column.isBetweenValues(lower, higher));
|
||||||
// ignore: public_member_api_docs
|
|
||||||
|
/// Create a filter to check if the column is not between two values
|
||||||
ComposableFilter isNotBetween(T lower, T higher) =>
|
ComposableFilter isNotBetween(T lower, T higher) =>
|
||||||
isBetween(lower, higher)._reversed();
|
isBetween(lower, higher)._reversed();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Built in filters for String columns
|
/// Built in filters for String columns
|
||||||
extension DateFilters<T extends DateTime> on ColumnFilters<T> {
|
extension DateFilters<T extends DateTime> on ColumnFilters<T> {
|
||||||
// ignore: public_member_api_docs
|
/// Create a filter to check if the column is after a [DateTime]
|
||||||
ComposableFilter isAfter(T value) =>
|
ComposableFilter isAfter(T value) =>
|
||||||
ComposableFilter.simple(column.isBiggerThanValue(value));
|
ComposableFilter.simple(column.isBiggerThanValue(value));
|
||||||
// ignore: public_member_api_docs
|
|
||||||
ComposableFilter isNotAfter(T value) => isAfter(value)._reversed();
|
|
||||||
|
|
||||||
// ignore: public_member_api_docs
|
/// Create a filter to check if the column is before a [DateTime]
|
||||||
ComposableFilter isBefore(T value) =>
|
ComposableFilter isBefore(T value) =>
|
||||||
ComposableFilter.simple(column.isSmallerThanValue(value));
|
ComposableFilter.simple(column.isSmallerThanValue(value));
|
||||||
// ignore: public_member_api_docs
|
|
||||||
ComposableFilter isNotBefore(T value) => isBefore(value)._reversed();
|
|
||||||
|
|
||||||
// ignore: public_member_api_docs
|
/// Create a filter to check if the column is on or after a [DateTime]
|
||||||
ComposableFilter isAfterOrOn(T value) =>
|
ComposableFilter isAfterOrOn(T value) =>
|
||||||
ComposableFilter.simple(column.isBiggerOrEqualValue(value));
|
ComposableFilter.simple(column.isBiggerOrEqualValue(value));
|
||||||
// ignore: public_member_api_docs
|
|
||||||
ComposableFilter isNotAfterOrOn(T value) => isAfterOrOn(value)._reversed();
|
|
||||||
|
|
||||||
// ignore: public_member_api_docs
|
/// Create a filter to check if the column is before or on a [DateTime]
|
||||||
ComposableFilter isBeforeOrOn(T value) =>
|
ComposableFilter isBeforeOrOn(T value) =>
|
||||||
ComposableFilter.simple(column.isSmallerOrEqualValue(value));
|
ComposableFilter.simple(column.isSmallerOrEqualValue(value));
|
||||||
// ignore: public_member_api_docs
|
|
||||||
ComposableFilter isNotBeforeOrOn(T value) => isBeforeOrOn(value)._reversed();
|
|
||||||
|
|
||||||
// ignore: public_member_api_docs
|
/// Create a filter to check if the column is between 2 [DateTime]s
|
||||||
|
|
||||||
ComposableFilter isBetween(T lower, T higher) =>
|
ComposableFilter isBetween(T lower, T higher) =>
|
||||||
ComposableFilter.simple(column.isBetweenValues(lower, higher));
|
ComposableFilter.simple(column.isBetweenValues(lower, higher));
|
||||||
// ignore: public_member_api_docs
|
|
||||||
|
/// Create a filter to check if the column is not between 2 [DateTime]s
|
||||||
ComposableFilter isNotBetween(T lower, T higher) =>
|
ComposableFilter isNotBetween(T lower, T higher) =>
|
||||||
isBetween(lower, higher)._reversed();
|
isBetween(lower, higher)._reversed();
|
||||||
}
|
}
|
||||||
|
@ -186,12 +174,11 @@ class ComposableFilter implements HasJoinBuilders {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The class that orchestrates the composition of filtering
|
/// The class that orchestrates the composition of filtering
|
||||||
class FilterComposer<DB extends GeneratedDatabase, T extends TableInfo>
|
class FilterComposer<DB extends GeneratedDatabase, T extends Table>
|
||||||
extends Composer<DB, T> {
|
extends Composer<DB, T> {
|
||||||
/// Create a new filter composer from existing query state
|
|
||||||
// FilterComposer(super.state);
|
|
||||||
|
|
||||||
/// Create a filter composer with an empty state
|
/// Create a filter composer with an empty state
|
||||||
FilterComposer.empty(super.db, super.table) : super.empty();
|
FilterComposer.empty(super.db, super.table) : super.empty();
|
||||||
|
|
||||||
|
/// Create a filter composer using another composers state
|
||||||
FilterComposer.withAliasedTable(super.data) : super.withAliasedTable();
|
FilterComposer.withAliasedTable(super.data) : super.withAliasedTable();
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,8 +58,3 @@ abstract interface class HasJoinBuilders {
|
||||||
/// Add a join builder to this class
|
/// Add a join builder to this class
|
||||||
void addJoinBuilder(JoinBuilder builder);
|
void addJoinBuilder(JoinBuilder builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper for getting all the aliased names of a set of join builders
|
|
||||||
extension on Set<JoinBuilder> {
|
|
||||||
List<String> get aliasedNames => map((e) => (e.aliasedName)).toList();
|
|
||||||
}
|
|
||||||
|
|
|
@ -7,10 +7,10 @@ part 'filter.dart';
|
||||||
part 'join.dart';
|
part 'join.dart';
|
||||||
part 'ordering.dart';
|
part 'ordering.dart';
|
||||||
|
|
||||||
/// Defines a class that holds the state for a table manager
|
/// Defines a class that holds the state for a [BaseTableManager]
|
||||||
class TableManagerState<
|
class TableManagerState<
|
||||||
DB extends GeneratedDatabase,
|
DB extends GeneratedDatabase,
|
||||||
T extends TableInfo,
|
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>> {
|
||||||
|
@ -23,10 +23,12 @@ class TableManagerState<
|
||||||
/// The expression that will be applied to the query
|
/// The expression that will be applied to the query
|
||||||
final Expression<bool>? filter;
|
final Expression<bool>? filter;
|
||||||
|
|
||||||
/// The orderings that will be applied to the query
|
/// A set of [OrderingBuilder] which will be used to apply
|
||||||
|
/// [OrderingTerm]s to the statement when it's eventually built
|
||||||
final Set<OrderingBuilder> orderingBuilders;
|
final Set<OrderingBuilder> orderingBuilders;
|
||||||
|
|
||||||
/// The joins that will be applied to the query
|
/// A set of [JoinBuilder] which will be used to create [Join]s
|
||||||
|
/// that will be applied to the build statement
|
||||||
final Set<JoinBuilder> joinBuilders;
|
final Set<JoinBuilder> joinBuilders;
|
||||||
|
|
||||||
/// Whether the query should return distinct results
|
/// Whether the query should return distinct results
|
||||||
|
@ -38,15 +40,19 @@ class TableManagerState<
|
||||||
/// If set, the number of rows that will be skipped
|
/// If set, the number of rows that will be skipped
|
||||||
final int? offset;
|
final int? offset;
|
||||||
|
|
||||||
/// The composer for the filters
|
/// The [FilterComposer] for this [TableManagerState]
|
||||||
|
/// This class will be used to create filtering [Expression]s
|
||||||
|
/// which will be applied to the statement when its eventually created
|
||||||
final FS filteringComposer;
|
final FS filteringComposer;
|
||||||
|
|
||||||
/// The composer for the orderings
|
/// The [OrderingComposer] for this [TableManagerState]
|
||||||
|
/// This class will be used to create [OrderingTerm]s
|
||||||
|
/// which will be applied to the statement when its eventually created
|
||||||
final OS orderingComposer;
|
final OS orderingComposer;
|
||||||
|
|
||||||
/// Defines a class which holds the state for a table manager
|
/// Defines a class which holds the state for a table manager
|
||||||
/// It contains the database instance, the table instance, and any filters/orderings that will be applied to the query
|
/// It contains the database instance, the table instance, and any filters/orderings that will be applied to the query
|
||||||
/// This is held in a seperate class so that the state can be passed down from the root manager to the lower level managers
|
/// This is held in a seperate class than the [BaseTableManager] so that the state can be passed down from the root manager to the lower level managers
|
||||||
TableManagerState({
|
TableManagerState({
|
||||||
required this.db,
|
required this.db,
|
||||||
required this.table,
|
required this.table,
|
||||||
|
@ -88,7 +94,8 @@ class TableManagerState<
|
||||||
/// This is needed due to dart's limitations with generics
|
/// This is needed due to dart's limitations with generics
|
||||||
TableInfo<T, DT> get _tableAsTableInfo => table as TableInfo<T, DT>;
|
TableInfo<T, DT> get _tableAsTableInfo => table as TableInfo<T, DT>;
|
||||||
|
|
||||||
/// Builds a joined select statement.
|
/// Builds a joined select statement, should be used when joins are present
|
||||||
|
/// Will order, filter, and limit the statement using the state
|
||||||
JoinedSelectStatement _buildJoinedSelectStatement() {
|
JoinedSelectStatement _buildJoinedSelectStatement() {
|
||||||
// Build the joins
|
// Build the joins
|
||||||
final joins = joinBuilders.map((e) => e.buildJoin()).toList();
|
final joins = joinBuilders.map((e) => e.buildJoin()).toList();
|
||||||
|
@ -112,9 +119,10 @@ class TableManagerState<
|
||||||
return statement;
|
return statement;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds a simple select statement
|
/// Builds a simple select statement, this should be used when there are no joins
|
||||||
|
/// Will order, filter, and limit the statement using the state
|
||||||
SimpleSelectStatement<T, DT> _buildSimpleSelectStatement() {
|
SimpleSelectStatement<T, DT> _buildSimpleSelectStatement() {
|
||||||
// Create the joined statement
|
// Create the statement
|
||||||
final statement = db.select(_tableAsTableInfo, distinct: distinct ?? false);
|
final statement = db.select(_tableAsTableInfo, distinct: distinct ?? false);
|
||||||
|
|
||||||
// Apply the expression to the statement
|
// Apply the expression to the statement
|
||||||
|
|
|
@ -1,5 +1,35 @@
|
||||||
part of 'manager.dart';
|
part of 'manager.dart';
|
||||||
|
|
||||||
|
/// Defines a class which is used to wrap a column to only expose ordering functions
|
||||||
|
class ColumnOrderings<T extends Object> {
|
||||||
|
/// This class is a wrapper on top of the generated column class
|
||||||
|
///
|
||||||
|
/// It's used to expose ordering functions for a column
|
||||||
|
///
|
||||||
|
/// ```dart
|
||||||
|
/// extension on FilterComposer<DateTime>{
|
||||||
|
/// FitlerBuilder after2000() => isAfter(DateTime(2000));
|
||||||
|
///}
|
||||||
|
/// ```
|
||||||
|
ColumnOrderings(this.column);
|
||||||
|
|
||||||
|
/// Column that this [ColumnOrderings] wraps
|
||||||
|
GeneratedColumn<T> column;
|
||||||
|
|
||||||
|
/// Sort this column in ascending order
|
||||||
|
///
|
||||||
|
/// 10 -> 1 | Z -> A | Dec 31 -> Jan 1
|
||||||
|
ComposableOrdering asc() =>
|
||||||
|
ComposableOrdering.simple({OrderingBuilder(OrderingMode.asc, column)});
|
||||||
|
|
||||||
|
/// Sort this column in descending order
|
||||||
|
///
|
||||||
|
/// 1 -> 10 | A -> Z | Jan 1 -> Dec 31
|
||||||
|
ComposableOrdering desc() =>
|
||||||
|
ComposableOrdering.simple({OrderingBuilder(OrderingMode.desc, column)});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Defines a class which will hold the information needed to create an ordering
|
||||||
class OrderingBuilder {
|
class OrderingBuilder {
|
||||||
/// The mode of the ordering
|
/// The mode of the ordering
|
||||||
final OrderingMode mode;
|
final OrderingMode mode;
|
||||||
|
@ -7,6 +37,7 @@ class OrderingBuilder {
|
||||||
/// The column that the ordering is applied to
|
/// The column that the ordering is applied to
|
||||||
final GeneratedColumn column;
|
final GeneratedColumn column;
|
||||||
|
|
||||||
|
/// Create a new ordering builder, will be used by the [TableManagerState] to create [OrderingTerm]s
|
||||||
OrderingBuilder(this.mode, this.column);
|
OrderingBuilder(this.mode, this.column);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -26,7 +57,11 @@ class OrderingBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Defines a class that can be used to compose orderings for a column
|
/// Defines a class that can be used to compose orderings for a column
|
||||||
|
///
|
||||||
|
/// Multiple orderings can be composed together using the `&` operator.
|
||||||
|
/// The orderings will be executed from left to right.
|
||||||
class ComposableOrdering implements HasJoinBuilders {
|
class ComposableOrdering implements HasJoinBuilders {
|
||||||
|
/// The orderings that are being composed
|
||||||
final Set<OrderingBuilder> orderingBuilders;
|
final Set<OrderingBuilder> orderingBuilders;
|
||||||
@override
|
@override
|
||||||
final Set<JoinBuilder> joinBuilders;
|
final Set<JoinBuilder> joinBuilders;
|
||||||
|
@ -35,11 +70,14 @@ class ComposableOrdering implements HasJoinBuilders {
|
||||||
joinBuilders.add(builder);
|
joinBuilders.add(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new ordering for a column
|
/// Create a new [ComposableOrdering] for a column without any joins
|
||||||
ComposableOrdering.simple(this.orderingBuilders) : joinBuilders = {};
|
ComposableOrdering.simple(this.orderingBuilders) : joinBuilders = {};
|
||||||
|
|
||||||
|
/// Create a new [ComposableOrdering] for a column with joins
|
||||||
ComposableOrdering.withJoin(this.orderingBuilders, this.joinBuilders);
|
ComposableOrdering.withJoin(this.orderingBuilders, this.joinBuilders);
|
||||||
|
|
||||||
ComposableOrdering operator |(ComposableOrdering other) {
|
/// Combine two orderings with THEN
|
||||||
|
ComposableOrdering operator &(ComposableOrdering other) {
|
||||||
return ComposableOrdering.withJoin(
|
return ComposableOrdering.withJoin(
|
||||||
orderingBuilders.union(other.orderingBuilders),
|
orderingBuilders.union(other.orderingBuilders),
|
||||||
joinBuilders.union(other.joinBuilders));
|
joinBuilders.union(other.joinBuilders));
|
||||||
|
@ -52,12 +90,13 @@ class ComposableOrdering implements HasJoinBuilders {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The class that orchestrates the composition of orderings
|
/// The class that orchestrates the composition of orderings
|
||||||
|
///
|
||||||
|
///
|
||||||
class OrderingComposer<DB extends GeneratedDatabase, T extends Table>
|
class OrderingComposer<DB extends GeneratedDatabase, T extends Table>
|
||||||
extends Composer<DB, T> {
|
extends Composer<DB, T> {
|
||||||
/// Create a new ordering composer from existing query state
|
|
||||||
// OrderingComposer.fromComposer(super.state);
|
|
||||||
|
|
||||||
/// Create an ordering composer with an empty state
|
/// Create an ordering composer with an empty state
|
||||||
OrderingComposer.empty(super.db, super.table) : super.empty();
|
OrderingComposer.empty(super.db, super.table) : super.empty();
|
||||||
|
|
||||||
|
/// Create an ordering composer using another composers state
|
||||||
OrderingComposer.withAliasedTable(super.data) : super.withAliasedTable();
|
OrderingComposer.withAliasedTable(super.data) : super.withAliasedTable();
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,9 +29,7 @@ class ManagerWriter {
|
||||||
filters.writeln(
|
filters.writeln(
|
||||||
"ColumnFilters get $getterName => ColumnFilters(state.table.${col.nameInDart});");
|
"ColumnFilters get $getterName => ColumnFilters(state.table.${col.nameInDart});");
|
||||||
orderings.writeln(
|
orderings.writeln(
|
||||||
"ComposableOrdering get ${getterName}Asc => ComposableOrdering.simple({OrderingBuilder( OrderingMode.asc, state.table.${col.nameInDart})});");
|
"ColumnOrderings get $getterName => ColumnOrderings(state.table.${col.nameInDart});");
|
||||||
orderings.writeln(
|
|
||||||
"ComposableOrdering get ${getterName}Desc => ComposableOrdering.simple({OrderingBuilder( OrderingMode.desc, state.table.${col.nameInDart})});");
|
|
||||||
|
|
||||||
if (col.isForeignKey) {
|
if (col.isForeignKey) {
|
||||||
final referencedCol = col.constraints
|
final referencedCol = col.constraints
|
||||||
|
|
Loading…
Reference in New Issue