diff --git a/drift/lib/src/runtime/manager/manager.dart b/drift/lib/src/runtime/manager/manager.dart index b6405b98..d5c610a5 100644 --- a/drift/lib/src/runtime/manager/manager.dart +++ b/drift/lib/src/runtime/manager/manager.dart @@ -30,10 +30,10 @@ class TableManagerState< DT extends DataClass, FS extends FilterComposer, OS extends OrderingComposer> { - /// The database that the query will be executed on + /// The database that the query will be exeCCted on final DB db; - /// The table that the query will be executed on + /// The table that the query will be exeCCted on final T table; /// The expression that will be applied to the query @@ -234,17 +234,18 @@ abstract class BaseTableManager< } /// Mixin for adding select functionality to a table manager -mixin ProcessedTableManagerMixin< +abstract class ProcessedTableManager< DB extends GeneratedDatabase, T extends TableInfo, D extends DataClass, FS extends FilterComposer, OS extends OrderingComposer> - on BaseTableManager + extends BaseTableManager implements MultiSelectable, SingleSelectable, SingleOrNullSelectable { + const ProcessedTableManager(super.state); @override Future getSingle() => state.buildSelectStatement().getSingle(); @override @@ -259,33 +260,19 @@ mixin ProcessedTableManagerMixin< @override Stream watchSingleOrNull() => state.buildSelectStatement().watchSingleOrNull(); + Future 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, - OS extends OrderingComposer> - extends BaseTableManager - with ProcessedTableManagerMixin { - /// A table manager that only has functions to return items based on the state build by parent managers - const ProcessedTableManager(super.state); -} - /// A table manager that has methods to filter the query -class TableManagerWithFiltering< +abstract class TableManagerWithFiltering< DB extends GeneratedDatabase, T extends TableInfo, D extends DataClass, FS extends FilterComposer, OS extends OrderingComposer, C extends ProcessedTableManager> - extends BaseTableManager - with ProcessedTableManagerMixin { - /// Callback for + extends ProcessedTableManager { final C Function(TableManagerState) _getChildManager; const TableManagerWithFiltering(super.state, {required C Function(TableManagerState) @@ -300,15 +287,14 @@ class TableManagerWithFiltering< } /// A table manager that has methods to order the query -class TableManagerWithOrdering< +abstract class TableManagerWithOrdering< DB extends GeneratedDatabase, T extends TableInfo, D extends DataClass, FS extends FilterComposer, OS extends OrderingComposer, C extends ProcessedTableManager> - extends BaseTableManager - with ProcessedTableManagerMixin { + extends ProcessedTableManager { final C Function(TableManagerState) _getChildManager; const TableManagerWithOrdering(super.state, {required C Function(TableManagerState) @@ -338,7 +324,6 @@ abstract class RootTableManager< final CO Function(TableManagerState) _getChildManagerWithOrdering; final CI _createInsertable; - RootTableManager(super.state, {required CF Function(TableManagerState) getChildManagerWithFiltering, @@ -369,6 +354,15 @@ abstract class RootTableManager< .insert(f(_createInsertable), mode: mode, onConflict: onConflict); } + Future createReturning( + Insertable Function(CI o) f, + InsertMode? mode, + UpsertClause? onConflict, + ) { + return state.db.into(state.table).insertReturning(f(_createInsertable), + mode: mode, onConflict: onConflict) as Future; + } + Future bulkCreate( Iterable> Function(CI o) f, InsertMode? mode, @@ -378,6 +372,10 @@ abstract class RootTableManager< mode: mode, onConflict: onConflict)); } + Future replace(Insertable entry) { + return state.db.update(state.table).replace(entry); + } + CF orderBy(ComposableOrdering Function(OS o) o) { final orderings = o(state.orderingComposer); return _getChildManagerWithFiltering(state.copyWith( diff --git a/drift_dev/lib/src/writer/manager.dart b/drift_dev/lib/src/writer/manager.dart index 4fc4b486..0722013b 100644 --- a/drift_dev/lib/src/writer/manager.dart +++ b/drift_dev/lib/src/writer/manager.dart @@ -3,12 +3,6 @@ import 'package:drift_dev/src/analysis/results/results.dart'; import 'package:drift_dev/src/writer/writer.dart'; import 'package:recase/recase.dart'; -extension on DriftColumn { - bool get isForeignKey { - return constraints.whereType().isNotEmpty; - } -} - abstract class _Filter { final String filterName; _Filter( @@ -190,6 +184,7 @@ class _TableNames { /// Columns with their names, filters and orderings final List<_ColumnNames> columns; + /// Filters for back references final List<_ReferencedFilter> backRefFilters; _TableNames(this.table) @@ -207,7 +202,7 @@ class _TableNames { backRefFilters = [], columns = []; - void writeManager(TextEmitter leaf, String dbClassName) { + void _writeFilterComposer(TextEmitter leaf, String dbClassName) { // Write the FilterComposer leaf ..write('class $filterComposer extends ') @@ -223,7 +218,9 @@ class _TableNames { f.writeFilter(leaf); } leaf.writeln('}'); + } + void _writeOrderingComposer(TextEmitter leaf, String dbClassName) { // Write the OrderingComposer leaf ..write('class $orderingComposer extends ') @@ -236,8 +233,9 @@ class _TableNames { } } leaf.writeln('}'); + } - // Write the ProcessedTableManager + void _writeProcessedTableManager(TextEmitter leaf, String dbClassName) { leaf ..write('class $processedTableManager extends ') ..writeDriftRef('ProcessedTableManager') @@ -245,8 +243,9 @@ class _TableNames { '<$dbClassName,$tableClassName,$rowClassName,$filterComposer,$orderingComposer> {') ..writeln('const $processedTableManager(super.state);') ..writeln('}'); + } - // Write the TableManagerWithFiltering + void _writeTableManagerWithFiltering(TextEmitter leaf, String dbClassName) { leaf ..write('class $tableManagerWithFiltering extends ') ..writeDriftRef('TableManagerWithFiltering') @@ -255,33 +254,42 @@ class _TableNames { ..writeln( 'const $tableManagerWithFiltering(super.state,{required super.getChildManager});') ..writeln('}'); + } - // Write the TableManagerWithOrdering + void _writeTableManagerWithOrdering(TextEmitter leaf, String dbClassName) { leaf ..write('class $tableManagerWithOrdering extends ') ..writeDriftRef('TableManagerWithOrdering') ..writeln( - '<$dbClassName,$tableClassName,$rowClassName,$filterComposer,$orderingComposer,$processedTableManager> {') + '<$dbClassName,$tableClassName,$rowClassName,$filterComposer,$orderingComposer,$processedTableManager>{') ..writeln( 'const $tableManagerWithOrdering(super.state,{required super.getChildManager});') ..writeln('}'); - // Write the Root Table Manager - - // We need to build a function type which will create insertable items - // We then need to create the actual function + } + void _writeRootTable(TextEmitter leaf, String dbClassName) { final companionClassName = leaf.dartCode(leaf.companionType(table)); + // final updateCompanionTypedef = StringBuffer( + // 'typedef $updateCompanionTypedefName = $companionClassName Function({'); final createInsertableFunctionTypeDef = - StringBuffer("$companionClassName Function({"); - final createInsertableFunctionArgs = StringBuffer("({"); + StringBuffer('$companionClassName Function({'); + // final updateCompanionArguments = StringBuffer('({'); + final createInsertableFunctionArgs = StringBuffer('({'); + // final updateCompanionBody = StringBuffer('=> $companionClassName('); final createInsertableFunctionBody = - StringBuffer("=> $companionClassName.insert("); - + StringBuffer('=> $companionClassName.insert('); for (final column in table.columns) { final value = leaf.drift('Value'); final param = column.nameInDart; final typeName = leaf.dartCode(leaf.dartType(column)); - createInsertableFunctionBody.write('$param: $param,'); + + // The update companion has no required fields, they are all defaulted to absent + // updateCompanionTypedef.write('$value<$typeName> $param,'); + // updateCompanionArguments + // .write('$value<$typeName> $param = const $value.absent(),'); + // updateCompanionBody.write('$param: $param,'); + + // The insert compantion has some required arguments and some that are defaulted to absent if (!column.isImplicitRowId && table.isColumnRequiredForInsert(column)) { createInsertableFunctionTypeDef.write('required $typeName $param,'); createInsertableFunctionArgs.write('required $typeName $param,'); @@ -290,16 +298,28 @@ class _TableNames { createInsertableFunctionArgs .write('$value<$typeName> $param = const $value.absent(),'); } + createInsertableFunctionBody.write('$param: $param,'); } + + // Close + // updateCompanionTypedef.write('})'); createInsertableFunctionTypeDef.write('})'); createInsertableFunctionArgs.write('})'); createInsertableFunctionBody.write(")"); + // leaf.writeln(updateCompanionTypedef); + // leaf.writeln(insertCompanionTypedef); + + // updateCompanionArguments.write('})'); + // insertCompanionArguments.write('})'); + // updateCompanionBody.write(")"); + // insertCompanionBody.write(")"); + leaf ..write('class $rootTableManager extends ') ..writeDriftRef('RootTableManager') ..writeln( - '<$dbClassName,$tableClassName,$rowClassName,$filterComposer,$orderingComposer,$processedTableManager,$tableManagerWithFiltering,$tableManagerWithOrdering, $createInsertableFunctionTypeDef> {') + '<$dbClassName,$tableClassName,$rowClassName,$filterComposer,$orderingComposer,$processedTableManager,$tableManagerWithFiltering,$tableManagerWithOrdering,$createInsertableFunctionTypeDef> {') ..writeln('$rootTableManager($dbClassName db, $tableClassName table)') ..writeln(": super(") ..writeDriftRef("TableManagerState") @@ -311,6 +331,15 @@ class _TableNames { ..writeln('}'); } + void writeManager(TextEmitter leaf, String dbClassName) { + _writeFilterComposer(leaf, dbClassName); + _writeOrderingComposer(leaf, dbClassName); + _writeProcessedTableManager(leaf, dbClassName); + _writeTableManagerWithFiltering(leaf, dbClassName); + _writeTableManagerWithOrdering(leaf, dbClassName); + _writeRootTable(leaf, dbClassName); + } + void addFiltersAndOrderings(List tables, TextEmitter leaf) { /// First add the filters and orderings for the columns /// of the current table