mirror of https://github.com/AMT-Cheif/drift.git
remove join from composer state
This commit is contained in:
parent
04c07a980a
commit
5875e18458
|
@ -3,73 +3,40 @@ part of 'manager.dart';
|
|||
|
||||
/// A class that holds the state for a query composer
|
||||
@internal
|
||||
class ComposerState<DB extends GeneratedDatabase, T extends Table>
|
||||
implements HasJoinBuilders {
|
||||
class ComposerState<DB extends GeneratedDatabase, T extends Table> {
|
||||
/// The database that the query will be executed on
|
||||
final DB db;
|
||||
|
||||
/// The table that the query will be executed on
|
||||
final T table;
|
||||
|
||||
@override
|
||||
final Set<JoinBuilder> joinBuilders;
|
||||
@override
|
||||
void addJoinBuilder(JoinBuilder builder) {
|
||||
joinBuilders.add(builder);
|
||||
}
|
||||
|
||||
/// Get a random alias for a table
|
||||
String _getRandomAlias(TableInfo table) {
|
||||
var aliasName = '${table.actualTableName}__${Random().nextInt(4294967296)}';
|
||||
while (joinBuilders.map((e) => (e.aliasedName)).contains(aliasName)) {
|
||||
aliasName = '${table.actualTableName}__${Random().nextInt(4294967296)}';
|
||||
continue;
|
||||
}
|
||||
return aliasName;
|
||||
}
|
||||
|
||||
/// Create a new query composer state
|
||||
ComposerState._(this.db, this.table, Set<JoinBuilder>? joinBuilders)
|
||||
: joinBuilders = joinBuilders ?? {};
|
||||
}
|
||||
|
||||
@internal
|
||||
class AliasedComposerBuilder<DB extends GeneratedDatabase, RT extends Table,
|
||||
CT extends Table> {
|
||||
ComposerState<DB, RT> state;
|
||||
CT aliasedTable;
|
||||
AliasedComposerBuilder(
|
||||
this.state,
|
||||
this.aliasedTable,
|
||||
ComposerState._(
|
||||
this.db,
|
||||
this.table,
|
||||
);
|
||||
}
|
||||
|
||||
/// 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.
|
||||
/// Any class that can be composed using the `&` or `|` operator is called a composable.
|
||||
/// [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.
|
||||
/// `f` in this example is a [Composer] object, and `f.id.equals(1)` returns 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.
|
||||
/// E.G. In the example above, only the resulting [ComposableFilter] object is returned, and the [FilterComposer] is discarded.
|
||||
///
|
||||
@internal
|
||||
sealed class Composer<DB extends GeneratedDatabase, CT extends Table> {
|
||||
/// The state of the composer
|
||||
final ComposerState<DB, CT> state;
|
||||
|
||||
Composer.withAliasedTable(AliasedComposerBuilder<DB, dynamic, CT> data)
|
||||
: state = ComposerState._(
|
||||
data.state.db, data.aliasedTable, data.state.joinBuilders);
|
||||
Composer.empty(DB db, CT table) : state = ComposerState._(db, table, {});
|
||||
Composer(DB db, CT table) : state = ComposerState._(db, table);
|
||||
|
||||
/// Method for create a join between two tables
|
||||
B referenced<RT extends Table, QC extends Composer<DB, RT>,
|
||||
|
@ -78,53 +45,38 @@ sealed class Composer<DB extends GeneratedDatabase, CT extends Table> {
|
|||
required RT referencedTable,
|
||||
required GeneratedColumn Function(RT) getReferencedColumn,
|
||||
required B Function(QC) builder,
|
||||
required QC Function(AliasedComposerBuilder<DB, CT, RT> data)
|
||||
getReferencedQueryComposer,
|
||||
required QC Function(DB db, RT table) getReferencedComposer,
|
||||
}) {
|
||||
// Create an alias of the referenced table
|
||||
// We will never use `referencedTable` again, only the alias
|
||||
final aliasedReferencedTable = state.db.alias(referencedTable as TableInfo,
|
||||
state._getRandomAlias(referencedTable)) as RT;
|
||||
|
||||
// We are a function to get the column of the current table,
|
||||
// This is so that if the `table` in `state` is an alias,
|
||||
// The user can't supply a column that does not have an alias
|
||||
// E.G. db.table.id instead of state.table.id
|
||||
// The name of the alias will be created using the following logic:
|
||||
// "currentTableName__currentColumnName__referencedColumnName__referencedTableName"
|
||||
// This is to ensure that the alias is unique
|
||||
final currentColumn = getCurrentColumn(state.table);
|
||||
|
||||
// We are using a function to get the column of the referenced table
|
||||
// This is so that the user cant by mistake use a column of a table that is not aliased
|
||||
final referencedColumn = getReferencedColumn(aliasedReferencedTable);
|
||||
final tempReferencedColumn = getReferencedColumn(referencedTable);
|
||||
final aliasName =
|
||||
'${currentColumn.tableName}__${currentColumn.name}__${tempReferencedColumn.tableName}__${tempReferencedColumn.name}';
|
||||
final aliasedReferencedTable =
|
||||
state.db.alias(referencedTable as TableInfo, aliasName);
|
||||
final aliasedReferencedColumn =
|
||||
getReferencedColumn(aliasedReferencedTable as RT);
|
||||
|
||||
// Create a join builder for the referenced table
|
||||
final joinBuilder = JoinBuilder(
|
||||
currentTable: state.table,
|
||||
referencedTable: aliasedReferencedTable,
|
||||
currentColumn: currentColumn,
|
||||
referencedColumn: referencedColumn,
|
||||
referencedTable: aliasedReferencedTable,
|
||||
referencedColumn: aliasedReferencedColumn,
|
||||
);
|
||||
|
||||
// Add the join builder to the state
|
||||
state.addJoinBuilder(joinBuilder);
|
||||
|
||||
// Get the query composer for the referenced table, passing in the aliased
|
||||
// table and all the join builders
|
||||
final referencedQueryComposer = getReferencedQueryComposer(
|
||||
AliasedComposerBuilder(this.state, aliasedReferencedTable));
|
||||
final referencedComposer =
|
||||
getReferencedComposer(state.db, aliasedReferencedTable);
|
||||
|
||||
// Run the user provided builder with the referencedQueryComposer
|
||||
// This may return a filter or ordering, but we only enforce that it's
|
||||
// a HasJoinBuilders
|
||||
final result = builder(referencedQueryComposer);
|
||||
|
||||
// At this point it is possible that the result has created more joins
|
||||
// that state doesnt have, it is also possible that the result is missing
|
||||
// the `joinBuilder` we create above.
|
||||
// We will combine both sets and set it to `state.joinBuilders` and `result.joinBuilders`
|
||||
for (var joinBuilder in result.joinBuilders.union(state.joinBuilders)) {
|
||||
state.addJoinBuilder(joinBuilder);
|
||||
result.addJoinBuilder(joinBuilder);
|
||||
}
|
||||
final result = builder(referencedComposer);
|
||||
result.addJoinBuilders({joinBuilder});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -117,7 +117,7 @@ extension DateFilters<T extends DateTime> on ColumnFilters<T> {
|
|||
|
||||
/// Defines a class which is used to wrap a column with a type converter to only expose filter functions
|
||||
class ColumnWithTypeConverterFilters<CUSTOM, T extends Object> {
|
||||
/// Similar to [ColumnFilters] but for columns with type converters
|
||||
/// Similar to [ColumnFilters] but for columns with type converters\
|
||||
ColumnWithTypeConverterFilters(this.column);
|
||||
|
||||
/// Column that this [ColumnWithTypeConverterFilters] wraps
|
||||
|
@ -159,8 +159,8 @@ class ComposableFilter implements HasJoinBuilders {
|
|||
@override
|
||||
final Set<JoinBuilder> joinBuilders;
|
||||
@override
|
||||
void addJoinBuilder(JoinBuilder builder) {
|
||||
joinBuilders.add(builder);
|
||||
void addJoinBuilders(Set<JoinBuilder> builders) {
|
||||
joinBuilders.addAll(builders);
|
||||
}
|
||||
|
||||
/// The expression that will be applied to the query
|
||||
|
@ -204,20 +204,11 @@ class ComposableFilter implements HasJoinBuilders {
|
|||
joinBuilders,
|
||||
);
|
||||
}
|
||||
|
||||
/// Returns a copy of this filter with the given joins and usedAliases
|
||||
ComposableFilter copyWithJoins(Set<JoinBuilder> joinBuilders) {
|
||||
return ComposableFilter.withJoin(
|
||||
expression, joinBuilders.union(this.joinBuilders));
|
||||
}
|
||||
}
|
||||
|
||||
/// The class that orchestrates the composition of filtering
|
||||
class FilterComposer<DB extends GeneratedDatabase, T extends Table>
|
||||
extends Composer<DB, T> {
|
||||
/// Create a filter composer with an empty state
|
||||
FilterComposer.empty(super.db, super.table) : super.empty();
|
||||
|
||||
/// Create a filter composer using another composers state
|
||||
FilterComposer.withAliasedTable(super.data) : super.withAliasedTable();
|
||||
FilterComposer(super.db, super.table);
|
||||
}
|
||||
|
|
|
@ -34,12 +34,13 @@ class JoinBuilder {
|
|||
bool operator ==(covariant JoinBuilder other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return other.aliasedName == aliasedName;
|
||||
return other.currentColumn == currentColumn &&
|
||||
other.referencedColumn == referencedColumn;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return aliasedName.hashCode;
|
||||
return currentColumn.hashCode ^ referencedColumn.hashCode;
|
||||
}
|
||||
|
||||
/// Build a join from this join builder
|
||||
|
@ -56,5 +57,5 @@ abstract interface class HasJoinBuilders {
|
|||
Set<JoinBuilder> get joinBuilders;
|
||||
|
||||
/// Add a join builder to this class
|
||||
void addJoinBuilder(JoinBuilder builder);
|
||||
void addJoinBuilders(Set<JoinBuilder> builders);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import 'dart:math';
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
|
@ -53,7 +52,7 @@ class TableManagerState<
|
|||
/// 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
|
||||
/// 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({
|
||||
const TableManagerState({
|
||||
required this.db,
|
||||
required this.table,
|
||||
required this.filteringComposer,
|
||||
|
@ -62,10 +61,9 @@ class TableManagerState<
|
|||
this.distinct,
|
||||
this.limit,
|
||||
this.offset,
|
||||
Set<OrderingBuilder>? orderingTerms,
|
||||
Set<JoinBuilder>? joinBuilders,
|
||||
}) : orderingBuilders = orderingTerms ?? {},
|
||||
joinBuilders = joinBuilders ?? {};
|
||||
this.orderingBuilders = const {},
|
||||
this.joinBuilders = const {},
|
||||
});
|
||||
|
||||
/// Copy this state with the given values
|
||||
TableManagerState<DB, T, DT, FS, OS> copyWith({
|
||||
|
@ -73,7 +71,7 @@ class TableManagerState<
|
|||
int? limit,
|
||||
int? offset,
|
||||
Expression<bool>? filter,
|
||||
Set<OrderingBuilder>? orderingTerms,
|
||||
Set<OrderingBuilder>? orderingBuilders,
|
||||
Set<JoinBuilder>? joinBuilders,
|
||||
}) {
|
||||
return TableManagerState(
|
||||
|
@ -83,7 +81,7 @@ class TableManagerState<
|
|||
orderingComposer: orderingComposer,
|
||||
filter: filter ?? this.filter,
|
||||
joinBuilders: joinBuilders ?? this.joinBuilders,
|
||||
orderingTerms: orderingTerms ?? this.orderingBuilders,
|
||||
orderingBuilders: orderingBuilders ?? this.orderingBuilders,
|
||||
distinct: distinct ?? this.distinct,
|
||||
limit: limit ?? this.limit,
|
||||
offset: offset ?? this.offset,
|
||||
|
@ -186,42 +184,108 @@ abstract class BaseTableManager<
|
|||
final TableManagerState<DB, T, DT, FS, OS> state;
|
||||
|
||||
/// Create a new [BaseTableManager] instance
|
||||
BaseTableManager(this.state);
|
||||
const BaseTableManager(this.state);
|
||||
}
|
||||
|
||||
/// Defines the top level manager for a table
|
||||
abstract class RootTableManager<
|
||||
DB extends GeneratedDatabase,
|
||||
T extends TableInfo,
|
||||
D extends DataClass,
|
||||
FS extends FilterComposer<DB, T>,
|
||||
OS extends OrderingComposer<DB, T>>
|
||||
extends BaseTableManager<DB, T, D, FS, OS> {
|
||||
/// Top level manager for a table.
|
||||
/// This class contains the top level manager functions for the table.
|
||||
RootTableManager(super.state);
|
||||
Future<int> insert(Insertable<D> item) =>
|
||||
state.db.into(state._tableAsTableInfo).insert(item);
|
||||
Future<void> insertAllBatch(List<Insertable<D>> items) => state.db
|
||||
.batch((batch) => batch.insertAll(state._tableAsTableInfo, items));
|
||||
Future<List<D>> getAll() => state.buildSelectStatement().get();
|
||||
Stream<List<D>> watchAll() => state.buildSelectStatement().watch();
|
||||
// Future<int> deleteAll() => state.buildDeleteStatement().go();
|
||||
}
|
||||
|
||||
/// Defines a manager for a table that can be used to build queries
|
||||
abstract class ProcessedTableManager<
|
||||
DB extends GeneratedDatabase,
|
||||
T extends TableInfo,
|
||||
D extends DataClass,
|
||||
FS extends FilterComposer<DB, T>,
|
||||
OS extends OrderingComposer<DB, T>>
|
||||
extends BaseTableManager<DB, T, D, FS, OS> {
|
||||
/// A table manager which uses it's internal state to build queries
|
||||
ProcessedTableManager(super.state);
|
||||
/// Mixin that adds processed functions to a table manager
|
||||
/// Is used to act on a table manager that has filtering/ordering applied
|
||||
mixin ProcessedTableManagerMixin<
|
||||
DB extends GeneratedDatabase,
|
||||
T extends TableInfo,
|
||||
D extends DataClass,
|
||||
FS extends FilterComposer<DB, T>,
|
||||
OS extends OrderingComposer<DB, T>> on BaseTableManager<DB, T, D, FS, OS> {
|
||||
Future<D> getSingle() => state.buildSelectStatement().getSingle();
|
||||
Stream<D> watchSingle() => state.buildSelectStatement().watchSingle();
|
||||
Future<List<D>> get() => state.buildSelectStatement().get();
|
||||
Stream<List<D>> watch() => state.buildSelectStatement().watch();
|
||||
// Future<int> delete() => state.buildDeleteStatement().go();
|
||||
}
|
||||
|
||||
/// A table manager that only has functions to return items based on the state build by parent managers
|
||||
class ProcessedTableManager<
|
||||
DB extends GeneratedDatabase,
|
||||
T extends TableInfo,
|
||||
D extends DataClass,
|
||||
FS extends FilterComposer<DB, T>,
|
||||
OS extends OrderingComposer<DB, T>>
|
||||
extends BaseTableManager<DB, T, D, FS, OS>
|
||||
with ProcessedTableManagerMixin<DB, T, D, FS, OS> {
|
||||
/// A table manager that only has functions to return items based on the state build by parent managers
|
||||
ProcessedTableManager(super.state);
|
||||
}
|
||||
|
||||
/// A table manager that has methods to filter the query
|
||||
class TableManagerWithFiltering<
|
||||
DB extends GeneratedDatabase,
|
||||
T extends TableInfo,
|
||||
D extends DataClass,
|
||||
FS extends FilterComposer<DB, T>,
|
||||
OS extends OrderingComposer<DB, T>,
|
||||
C extends ProcessedTableManager<DB, T, D, FS, OS>>
|
||||
extends BaseTableManager<DB, T, D, FS, OS>
|
||||
with ProcessedTableManagerMixin<DB, T, D, FS, OS> {
|
||||
final C Function(TableManagerState<DB, T, D, FS, OS>) getChildManager;
|
||||
const TableManagerWithFiltering(super.state, {required this.getChildManager});
|
||||
C filter(ComposableFilter Function(FilterComposer f) f) {
|
||||
final filter = f(state.filteringComposer);
|
||||
return getChildManager(state.copyWith(
|
||||
filter: filter.expression,
|
||||
joinBuilders: state.joinBuilders.union(filter.joinBuilders)));
|
||||
}
|
||||
}
|
||||
|
||||
/// A table manager that has methods to order the query
|
||||
class TableManagerWithOrdering<
|
||||
DB extends GeneratedDatabase,
|
||||
T extends TableInfo,
|
||||
D extends DataClass,
|
||||
FS extends FilterComposer<DB, T>,
|
||||
OS extends OrderingComposer<DB, T>,
|
||||
C extends ProcessedTableManager<DB, T, D, FS, OS>>
|
||||
extends BaseTableManager<DB, T, D, FS, OS>
|
||||
with ProcessedTableManagerMixin<DB, T, D, FS, OS> {
|
||||
final C Function(TableManagerState<DB, T, D, FS, OS>) getChildManager;
|
||||
const TableManagerWithOrdering(super.state, {required this.getChildManager});
|
||||
C orderBy(ComposableOrdering Function(OrderingComposer o) o) {
|
||||
final orderings = o(state.orderingComposer);
|
||||
return getChildManager(state.copyWith(
|
||||
orderingBuilders: orderings.orderingBuilders,
|
||||
joinBuilders: state.joinBuilders.union(orderings.joinBuilders)));
|
||||
}
|
||||
}
|
||||
|
||||
/// A table manager with top level function for creating, reading, updating, and deleting items
|
||||
class RootTableManager<
|
||||
DB extends GeneratedDatabase,
|
||||
T extends TableInfo,
|
||||
D extends DataClass,
|
||||
FS extends FilterComposer<DB, T>,
|
||||
OS extends OrderingComposer<DB, T>,
|
||||
C extends ProcessedTableManager<DB, T, D, FS, OS>,
|
||||
CF extends TableManagerWithFiltering<DB, T, D, FS, OS, C>,
|
||||
CO extends TableManagerWithOrdering<DB, T, D, FS, OS, C>>
|
||||
extends BaseTableManager<DB, T, D, FS, OS>
|
||||
with ProcessedTableManagerMixin<DB, T, D, FS, OS> {
|
||||
final CF Function(TableManagerState<DB, T, D, FS, OS>)
|
||||
getChildManagerWithFiltering;
|
||||
final CO Function(TableManagerState<DB, T, D, FS, OS>)
|
||||
getChildManagerWithOrdering;
|
||||
|
||||
const RootTableManager(super.state,
|
||||
{required this.getChildManagerWithFiltering,
|
||||
required this.getChildManagerWithOrdering});
|
||||
CF filter(ComposableFilter Function(FilterComposer f) f) {
|
||||
final filter = f(state.filteringComposer);
|
||||
return getChildManagerWithFiltering(state.copyWith(
|
||||
filter: filter.expression,
|
||||
joinBuilders: state.joinBuilders.union(filter.joinBuilders)));
|
||||
}
|
||||
|
||||
CO orderBy(ComposableOrdering Function(OrderingComposer o) o) {
|
||||
final orderings = o(state.orderingComposer);
|
||||
return getChildManagerWithOrdering(state.copyWith(
|
||||
orderingBuilders: orderings.orderingBuilders,
|
||||
joinBuilders: state.joinBuilders.union(orderings.joinBuilders)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,20 +66,19 @@ class ComposableOrdering implements HasJoinBuilders {
|
|||
@override
|
||||
final Set<JoinBuilder> joinBuilders;
|
||||
@override
|
||||
void addJoinBuilder(JoinBuilder builder) {
|
||||
joinBuilders.add(builder);
|
||||
void addJoinBuilders(Set<JoinBuilder> builders) {
|
||||
joinBuilders.addAll(builders);
|
||||
}
|
||||
|
||||
/// Create a new [ComposableOrdering] for a column without any joins
|
||||
ComposableOrdering.simple(this.orderingBuilders) : joinBuilders = {};
|
||||
|
||||
/// Create a new [ComposableOrdering] for a column with joins
|
||||
ComposableOrdering.withJoin(this.orderingBuilders, this.joinBuilders);
|
||||
ComposableOrdering._(this.orderingBuilders, this.joinBuilders);
|
||||
|
||||
/// Combine two orderings with THEN
|
||||
ComposableOrdering operator &(ComposableOrdering other) {
|
||||
return ComposableOrdering.withJoin(
|
||||
orderingBuilders.union(other.orderingBuilders),
|
||||
return ComposableOrdering._(orderingBuilders.union(other.orderingBuilders),
|
||||
joinBuilders.union(other.joinBuilders));
|
||||
}
|
||||
|
||||
|
@ -90,13 +89,8 @@ class ComposableOrdering implements HasJoinBuilders {
|
|||
}
|
||||
|
||||
/// The class that orchestrates the composition of orderings
|
||||
///
|
||||
///
|
||||
class OrderingComposer<DB extends GeneratedDatabase, T extends Table>
|
||||
extends Composer<DB, T> {
|
||||
/// Create an ordering composer with an empty state
|
||||
OrderingComposer.empty(super.db, super.table) : super.empty();
|
||||
|
||||
/// Create an ordering composer using another composers state
|
||||
OrderingComposer.withAliasedTable(super.data) : super.withAliasedTable();
|
||||
OrderingComposer(super.db, super.table);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,23 @@ extension on DriftColumn {
|
|||
}
|
||||
}
|
||||
|
||||
class Names {
|
||||
final String filterComposer;
|
||||
final String orderingComposer;
|
||||
final String processedTableManager;
|
||||
final String tableManagerWithFiltering;
|
||||
final String tableManagerWithOrdering;
|
||||
final String rootTableManager;
|
||||
|
||||
Names(String name)
|
||||
: filterComposer = '${name}FilterComposer',
|
||||
orderingComposer = '${name}OrderingComposer',
|
||||
processedTableManager = '${name}ProcessedTableManager',
|
||||
tableManagerWithFiltering = '${name}TableManagerWithFiltering',
|
||||
tableManagerWithOrdering = '${name}ProcessedTableManagerWithOrdering',
|
||||
rootTableManager = '${name}TableManager';
|
||||
}
|
||||
|
||||
class ManagerWriter {
|
||||
final Scope _scope;
|
||||
final String _dbClassName;
|
||||
|
@ -28,16 +45,13 @@ class ManagerWriter {
|
|||
|
||||
// The type this column stores
|
||||
final innerColumnType = leaf.dartCode(leaf.innerColumnType(col.sqlType));
|
||||
filters.writeln(
|
||||
"ColumnFilters<$innerColumnType> get $getterName => ColumnFilters(state.table.${col.nameInDart});");
|
||||
|
||||
if (col.typeConverter == null) {
|
||||
filters.writeln(
|
||||
"ColumnFilters<$innerColumnType> get $getterName => ColumnFilters(state.table.${col.nameInDart});");
|
||||
} else {
|
||||
filters.writeln(
|
||||
"ColumnFilters<$innerColumnType> get ${getterName}Value => ColumnFilters(state.table.${col.nameInDart});");
|
||||
if (col.typeConverter != null) {
|
||||
final mappedType = leaf.dartCode(leaf.writer.dartType(col));
|
||||
filters.writeln(
|
||||
"ColumnWithTypeConverterFilters<$mappedType,$innerColumnType> get $getterName => ColumnWithTypeConverterFilters(state.table.${col.nameInDart});");
|
||||
"ColumnWithTypeConverterFilters<$mappedType,$innerColumnType> get ${getterName}Ref => ColumnWithTypeConverterFilters(state.table.${col.nameInDart});");
|
||||
}
|
||||
|
||||
orderings.writeln(
|
||||
|
@ -51,37 +65,32 @@ class ManagerWriter {
|
|||
if (referencedCol != null) {
|
||||
if (referencedCol.owner is DriftTable) {
|
||||
final referencedTableGetter = referencedCol.owner.dbGetterName;
|
||||
final referencedEntityInfoName = referencedCol.owner.entityInfoName;
|
||||
final referencedTableName =
|
||||
Names(referencedCol.owner.entityInfoName);
|
||||
|
||||
if (referencedTableGetter != null) {
|
||||
filters.write('''
|
||||
|
||||
ComposableFilter ${col.nameInDart}Filter(
|
||||
ComposableFilter Function(${referencedEntityInfoName}FilterComposer f) f) {
|
||||
ComposableFilter Function(${referencedTableName.filterComposer} f) f) {
|
||||
return referenced(
|
||||
referencedTable: state.db.$referencedTableGetter,
|
||||
getCurrentColumn: (f) => f.${col.nameInDart},
|
||||
getReferencedColumn: (f) => f.${referencedCol.nameInDart},
|
||||
getReferencedQueryComposer: (data) =>
|
||||
${referencedEntityInfoName}FilterComposer.withAliasedTable(data),
|
||||
getReferencedComposer: (db, table) => ${referencedTableName.filterComposer}(db, table),
|
||||
builder: f);
|
||||
}
|
||||
|
||||
''');
|
||||
|
||||
orderings.write('''
|
||||
|
||||
ComposableOrdering ${col.nameInDart}OrderBy(
|
||||
ComposableOrdering Function(${referencedEntityInfoName}OrderingComposer o) o) {
|
||||
ComposableOrdering Function(${referencedTableName.orderingComposer} o) o) {
|
||||
return referenced(
|
||||
referencedTable: state.db.$referencedTableGetter,
|
||||
getCurrentColumn: (f) => f.${col.nameInDart},
|
||||
getReferencedColumn: (f) => f.${referencedCol.nameInDart},
|
||||
getReferencedQueryComposer: (data) =>
|
||||
${referencedEntityInfoName}OrderingComposer.withAliasedTable(data),
|
||||
getReferencedComposer: (db, table) => ${referencedTableName.orderingComposer}(db, table),
|
||||
builder: o);
|
||||
}
|
||||
|
||||
''');
|
||||
}
|
||||
}
|
||||
|
@ -89,78 +98,96 @@ ComposableOrdering ${col.nameInDart}OrderBy(
|
|||
}
|
||||
}
|
||||
|
||||
final names = Names(table.entityInfoName);
|
||||
|
||||
leaf.write("""
|
||||
|
||||
class ${table.entityInfoName}FilterComposer extends FilterComposer<$_dbClassName, ${table.entityInfoName}> {
|
||||
${table.entityInfoName}FilterComposer.empty(super.db, super.table) : super.empty();
|
||||
${table.entityInfoName}FilterComposer.withAliasedTable(super.data) : super.withAliasedTable();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class ${names.filterComposer}
|
||||
extends FilterComposer<$_dbClassName, ${table.entityInfoName}> {
|
||||
${names.filterComposer}(super.db, super.table);
|
||||
|
||||
$filters
|
||||
|
||||
}
|
||||
|
||||
class ${table.entityInfoName}OrderingComposer extends OrderingComposer<$_dbClassName, ${table.entityInfoName}> {
|
||||
${table.entityInfoName}OrderingComposer.empty(super.db, super.table) : super.empty();
|
||||
${table.entityInfoName}OrderingComposer.withAliasedTable(super.data) : super.withAliasedTable();
|
||||
class ${names.orderingComposer}
|
||||
extends OrderingComposer<$_dbClassName, ${table.entityInfoName}> {
|
||||
${names.orderingComposer}(super.db, super.table);
|
||||
|
||||
$orderings
|
||||
|
||||
|
||||
}
|
||||
|
||||
class ${table.entityInfoName}ProcessedTableManager extends ProcessedTableManager<$_dbClassName,
|
||||
${table.entityInfoName}, ${table.nameOfRowClass}, ${table.entityInfoName}FilterComposer, ${table.entityInfoName}OrderingComposer> {
|
||||
${table.entityInfoName}ProcessedTableManager(super.data);
|
||||
class ${names.processedTableManager} extends ProcessedTableManager<
|
||||
$_dbClassName,
|
||||
${table.entityInfoName},
|
||||
${table.nameOfRowClass},
|
||||
${names.filterComposer},
|
||||
${names.orderingComposer}> {
|
||||
${names.processedTableManager}(super.data);
|
||||
}
|
||||
|
||||
class ${table.entityInfoName}ProcessedTableManagerWithFiltering extends ProcessedTableManager<$_dbClassName,
|
||||
${table.entityInfoName}, ${table.nameOfRowClass}, ${table.entityInfoName}FilterComposer, ${table.entityInfoName}OrderingComposer> {
|
||||
${table.entityInfoName}ProcessedTableManagerWithFiltering(super.data);
|
||||
|
||||
${table.entityInfoName}ProcessedTableManager filter(
|
||||
ComposableFilter Function(${table.entityInfoName}FilterComposer f) f) {
|
||||
final filter = f(state.filteringComposer);
|
||||
return ${table.entityInfoName}ProcessedTableManager(state.copyWith(
|
||||
filter: filter.expression,
|
||||
joinBuilders: state.joinBuilders.union(filter.joinBuilders)));
|
||||
}
|
||||
class ${names.tableManagerWithFiltering}
|
||||
extends TableManagerWithFiltering<
|
||||
$_dbClassName,
|
||||
${table.entityInfoName},
|
||||
${table.nameOfRowClass},
|
||||
${names.filterComposer},
|
||||
${names.orderingComposer},
|
||||
${names.processedTableManager}> {
|
||||
${names.tableManagerWithFiltering}(super.state,
|
||||
{required super.getChildManager});
|
||||
}
|
||||
|
||||
class ${table.entityInfoName}ProcessedTableManagerWithOrdering extends ProcessedTableManager<$_dbClassName,
|
||||
${table.entityInfoName}, ${table.nameOfRowClass}, ${table.entityInfoName}FilterComposer, ${table.entityInfoName}OrderingComposer> {
|
||||
${table.entityInfoName}ProcessedTableManagerWithOrdering(super.data);
|
||||
|
||||
${table.entityInfoName}ProcessedTableManager orderBy(
|
||||
ComposableOrdering Function(${table.entityInfoName}OrderingComposer o) o) {
|
||||
final ordering = o(state.orderingComposer);
|
||||
return ${table.entityInfoName}ProcessedTableManager(state.copyWith(
|
||||
orderingTerms: state.orderingBuilders.union(ordering.orderingBuilders),
|
||||
joinBuilders: state.joinBuilders.union(ordering.joinBuilders)));
|
||||
}
|
||||
class ${names.tableManagerWithOrdering}
|
||||
extends TableManagerWithOrdering<
|
||||
$_dbClassName,
|
||||
${table.entityInfoName},
|
||||
${table.nameOfRowClass},
|
||||
${names.filterComposer},
|
||||
${names.orderingComposer},
|
||||
${names.processedTableManager}> {
|
||||
${names.tableManagerWithOrdering}(super.state,
|
||||
{required super.getChildManager});
|
||||
}
|
||||
|
||||
class ${table.entityInfoName}TableManager extends RootTableManager<$_dbClassName,
|
||||
${table.entityInfoName}, ${table.nameOfRowClass}, ${table.entityInfoName}FilterComposer, ${table.entityInfoName}OrderingComposer> {
|
||||
${table.entityInfoName}TableManager($_dbClassName db, ${table.entityInfoName} table)
|
||||
: super(TableManagerState(
|
||||
db: db,
|
||||
table: table,
|
||||
filteringComposer: ${table.entityInfoName}FilterComposer.empty(db, table),
|
||||
orderingComposer: ${table.entityInfoName}OrderingComposer.empty(db, table)));
|
||||
|
||||
${table.entityInfoName}ProcessedTableManagerWithOrdering filter(
|
||||
ComposableFilter Function(${table.entityInfoName}FilterComposer f) f) {
|
||||
final filter = f(state.filteringComposer);
|
||||
return ${table.entityInfoName}ProcessedTableManagerWithOrdering(state.copyWith(
|
||||
filter: filter.expression,
|
||||
joinBuilders: state.joinBuilders.union(filter.joinBuilders)));
|
||||
}
|
||||
|
||||
${table.entityInfoName}ProcessedTableManagerWithFiltering orderBy(
|
||||
ComposableOrdering Function(${table.entityInfoName}OrderingComposer o) o) {
|
||||
final ordering = o(state.orderingComposer);
|
||||
return ${table.entityInfoName}ProcessedTableManagerWithFiltering(state.copyWith(
|
||||
orderingTerms: state.orderingBuilders.union(ordering.orderingBuilders),
|
||||
joinBuilders: state.joinBuilders.union(ordering.joinBuilders)));
|
||||
}
|
||||
class ${names.rootTableManager} extends RootTableManager<
|
||||
$_dbClassName,
|
||||
${table.entityInfoName},
|
||||
${table.nameOfRowClass},
|
||||
${names.filterComposer},
|
||||
${names.orderingComposer},
|
||||
${names.processedTableManager},
|
||||
${names.tableManagerWithFiltering},
|
||||
${names.tableManagerWithOrdering}> {
|
||||
${names.rootTableManager}($_dbClassName db, ${table.entityInfoName} table)
|
||||
: super(
|
||||
TableManagerState(
|
||||
db: db,
|
||||
table: table,
|
||||
filteringComposer:
|
||||
${names.filterComposer}(db, table),
|
||||
orderingComposer:
|
||||
${names.orderingComposer}(db, table)),
|
||||
getChildManagerWithFiltering: (f) =>
|
||||
${names.tableManagerWithFiltering}(
|
||||
f,
|
||||
getChildManager: (f) =>
|
||||
${names.processedTableManager}(f),
|
||||
),
|
||||
getChildManagerWithOrdering: (f) =>
|
||||
${names.tableManagerWithOrdering}(f,
|
||||
getChildManager: (f) =>
|
||||
${names.processedTableManager}(f)));
|
||||
}
|
||||
|
||||
""");
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue