diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 633ee5142..ccb306e39 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -273,6 +273,7 @@ jobs: dart pub upgrade dart run build_runner build --delete-conflicting-outputs dart run bin/example.dart + dart test - name: Integration test for migrations example working-directory: examples/migrations_example run: | diff --git a/docs/lib/snippets/_shared/todo_tables.drift.dart b/docs/lib/snippets/_shared/todo_tables.drift.dart index 52ae385db..f7476d349 100644 --- a/docs/lib/snippets/_shared/todo_tables.drift.dart +++ b/docs/lib/snippets/_shared/todo_tables.drift.dart @@ -22,6 +22,36 @@ typedef $$TodoItemsTableUpdateCompanionBuilder = i1.TodoItemsCompanion i0.Value dueDate, }); +final class $$TodoItemsTableReferences extends i0 + .BaseReferences { + $$TodoItemsTableReferences(super.$_db, super.$_table, super.$_typedResult); + + static i1.$CategoriesTable _categoryTable(i0.GeneratedDatabase db) => + i3.ReadDatabaseContainer(db) + .resultSet('categories') + .createAlias(i0.$_aliasNameGenerator( + i3.ReadDatabaseContainer(db) + .resultSet('todo_items') + .category, + i3.ReadDatabaseContainer(db) + .resultSet('categories') + .id)); + + i1.$$CategoriesTableProcessedTableManager? get category { + if ($_item.category == null) return null; + final manager = i1 + .$$CategoriesTableTableManager( + $_db, + i3.ReadDatabaseContainer($_db) + .resultSet('categories')) + .filter((f) => f.id($_item.category!)); + final item = $_typedResult.readTableOrNull(_categoryTable($_db)); + if (item == null) return manager; + return i0.ProcessedTableManager( + manager.$state.copyWith(prefetchedData: [item])); + } +} + class $$TodoItemsTableFilterComposer extends i0.Composer { $$TodoItemsTableFilterComposer({ @@ -163,10 +193,7 @@ class $$TodoItemsTableTableManager extends i0.RootTableManager< i1.$$TodoItemsTableAnnotationComposer, $$TodoItemsTableCreateCompanionBuilder, $$TodoItemsTableUpdateCompanionBuilder, - ( - i1.TodoItem, - i0.BaseReferences - ), + (i1.TodoItem, i1.$$TodoItemsTableReferences), i1.TodoItem, i0.PrefetchHooks Function({bool category})> { $$TodoItemsTableTableManager( @@ -209,7 +236,10 @@ class $$TodoItemsTableTableManager extends i0.RootTableManager< dueDate: dueDate, ), withReferenceMapper: (p0) => p0 - .map((e) => (e.readTable(table), i0.BaseReferences(db, table, e))) + .map((e) => ( + e.readTable(table), + i1.$$TodoItemsTableReferences(db, table, e) + )) .toList(), prefetchHooksCallback: null, )); @@ -224,10 +254,7 @@ typedef $$TodoItemsTableProcessedTableManager = i0.ProcessedTableManager< i1.$$TodoItemsTableAnnotationComposer, $$TodoItemsTableCreateCompanionBuilder, $$TodoItemsTableUpdateCompanionBuilder, - ( - i1.TodoItem, - i0.BaseReferences - ), + (i1.TodoItem, i1.$$TodoItemsTableReferences), i1.TodoItem, i0.PrefetchHooks Function({bool category})>; typedef $$CategoriesTableCreateCompanionBuilder = i1.CategoriesCompanion @@ -241,6 +268,37 @@ typedef $$CategoriesTableUpdateCompanionBuilder = i1.CategoriesCompanion i0.Value name, }); +final class $$CategoriesTableReferences extends i0 + .BaseReferences { + $$CategoriesTableReferences(super.$_db, super.$_table, super.$_typedResult); + + static i0.MultiTypedResultKey> + _todoItemsRefsTable(i0.GeneratedDatabase db) => + i0.MultiTypedResultKey.fromTable( + i3.ReadDatabaseContainer(db) + .resultSet('todo_items'), + aliasName: i0.$_aliasNameGenerator( + i3.ReadDatabaseContainer(db) + .resultSet('categories') + .id, + i3.ReadDatabaseContainer(db) + .resultSet('todo_items') + .category)); + + i1.$$TodoItemsTableProcessedTableManager get todoItemsRefs { + final manager = i1 + .$$TodoItemsTableTableManager( + $_db, + i3.ReadDatabaseContainer($_db) + .resultSet('todo_items')) + .filter((f) => f.category.id($_item.id)); + + final cache = $_typedResult.readTableOrNull(_todoItemsRefsTable($_db)); + return i0.ProcessedTableManager( + manager.$state.copyWith(prefetchedData: cache)); + } +} + class $$CategoriesTableFilterComposer extends i0.Composer { $$CategoriesTableFilterComposer({ @@ -344,10 +402,7 @@ class $$CategoriesTableTableManager extends i0.RootTableManager< i1.$$CategoriesTableAnnotationComposer, $$CategoriesTableCreateCompanionBuilder, $$CategoriesTableUpdateCompanionBuilder, - ( - i1.Category, - i0.BaseReferences - ), + (i1.Category, i1.$$CategoriesTableReferences), i1.Category, i0.PrefetchHooks Function({bool todoItemsRefs})> { $$CategoriesTableTableManager( @@ -378,7 +433,10 @@ class $$CategoriesTableTableManager extends i0.RootTableManager< name: name, ), withReferenceMapper: (p0) => p0 - .map((e) => (e.readTable(table), i0.BaseReferences(db, table, e))) + .map((e) => ( + e.readTable(table), + i1.$$CategoriesTableReferences(db, table, e) + )) .toList(), prefetchHooksCallback: null, )); @@ -393,10 +451,7 @@ typedef $$CategoriesTableProcessedTableManager = i0.ProcessedTableManager< i1.$$CategoriesTableAnnotationComposer, $$CategoriesTableCreateCompanionBuilder, $$CategoriesTableUpdateCompanionBuilder, - ( - i1.Category, - i0.BaseReferences - ), + (i1.Category, i1.$$CategoriesTableReferences), i1.Category, i0.PrefetchHooks Function({bool todoItemsRefs})>; typedef $$UsersTableCreateCompanionBuilder = i1.UsersCompanion Function({ diff --git a/docs/lib/snippets/modular/drift/example.drift.dart b/docs/lib/snippets/modular/drift/example.drift.dart index 0c9e7a692..1c361ba09 100644 --- a/docs/lib/snippets/modular/drift/example.drift.dart +++ b/docs/lib/snippets/modular/drift/example.drift.dart @@ -17,6 +17,36 @@ typedef $TodosUpdateCompanionBuilder = i1.TodosCompanion Function({ i0.Value category, }); +final class $TodosReferences + extends i0.BaseReferences { + $TodosReferences(super.$_db, super.$_table, super.$_typedResult); + + static i1.Categories _categoryTable(i0.GeneratedDatabase db) => + i2.ReadDatabaseContainer(db) + .resultSet('categories') + .createAlias(i0.$_aliasNameGenerator( + i2.ReadDatabaseContainer(db) + .resultSet('todos') + .category, + i2.ReadDatabaseContainer(db) + .resultSet('categories') + .id)); + + i1.$CategoriesProcessedTableManager? get category { + if ($_item.category == null) return null; + final manager = i1 + .$CategoriesTableManager( + $_db, + i2.ReadDatabaseContainer($_db) + .resultSet('categories')) + .filter((f) => f.id($_item.category!)); + final item = $_typedResult.readTableOrNull(_categoryTable($_db)); + if (item == null) return manager; + return i0.ProcessedTableManager( + manager.$state.copyWith(prefetchedData: [item])); + } +} + class $TodosFilterComposer extends i0.Composer { $TodosFilterComposer({ required super.$db, @@ -148,7 +178,7 @@ class $TodosTableManager extends i0.RootTableManager< i1.$TodosAnnotationComposer, $TodosCreateCompanionBuilder, $TodosUpdateCompanionBuilder, - (i1.Todo, i0.BaseReferences), + (i1.Todo, i1.$TodosReferences), i1.Todo, i0.PrefetchHooks Function({bool category})> { $TodosTableManager(i0.GeneratedDatabase db, i1.Todos table) @@ -186,7 +216,8 @@ class $TodosTableManager extends i0.RootTableManager< category: category, ), withReferenceMapper: (p0) => p0 - .map((e) => (e.readTable(table), i0.BaseReferences(db, table, e))) + .map((e) => + (e.readTable(table), i1.$TodosReferences(db, table, e))) .toList(), prefetchHooksCallback: null, )); @@ -201,7 +232,7 @@ typedef $TodosProcessedTableManager = i0.ProcessedTableManager< i1.$TodosAnnotationComposer, $TodosCreateCompanionBuilder, $TodosUpdateCompanionBuilder, - (i1.Todo, i0.BaseReferences), + (i1.Todo, i1.$TodosReferences), i1.Todo, i0.PrefetchHooks Function({bool category})>; typedef $CategoriesCreateCompanionBuilder = i1.CategoriesCompanion Function({ @@ -213,6 +244,34 @@ typedef $CategoriesUpdateCompanionBuilder = i1.CategoriesCompanion Function({ i0.Value description, }); +final class $CategoriesReferences extends i0 + .BaseReferences { + $CategoriesReferences(super.$_db, super.$_table, super.$_typedResult); + + static i0.MultiTypedResultKey> _todosRefsTable( + i0.GeneratedDatabase db) => + i0.MultiTypedResultKey.fromTable( + i2.ReadDatabaseContainer(db).resultSet('todos'), + aliasName: i0.$_aliasNameGenerator( + i2.ReadDatabaseContainer(db) + .resultSet('categories') + .id, + i2.ReadDatabaseContainer(db) + .resultSet('todos') + .category)); + + i1.$TodosProcessedTableManager get todosRefs { + final manager = i1 + .$TodosTableManager( + $_db, i2.ReadDatabaseContainer($_db).resultSet('todos')) + .filter((f) => f.category.id($_item.id)); + + final cache = $_typedResult.readTableOrNull(_todosRefsTable($_db)); + return i0.ProcessedTableManager( + manager.$state.copyWith(prefetchedData: cache)); + } +} + class $CategoriesFilterComposer extends i0.Composer { $CategoriesFilterComposer({ @@ -318,10 +377,7 @@ class $CategoriesTableManager extends i0.RootTableManager< i1.$CategoriesAnnotationComposer, $CategoriesCreateCompanionBuilder, $CategoriesUpdateCompanionBuilder, - ( - i1.Category, - i0.BaseReferences - ), + (i1.Category, i1.$CategoriesReferences), i1.Category, i0.PrefetchHooks Function({bool todosRefs})> { $CategoriesTableManager(i0.GeneratedDatabase db, i1.Categories table) @@ -351,7 +407,8 @@ class $CategoriesTableManager extends i0.RootTableManager< description: description, ), withReferenceMapper: (p0) => p0 - .map((e) => (e.readTable(table), i0.BaseReferences(db, table, e))) + .map((e) => + (e.readTable(table), i1.$CategoriesReferences(db, table, e))) .toList(), prefetchHooksCallback: null, )); @@ -366,10 +423,7 @@ typedef $CategoriesProcessedTableManager = i0.ProcessedTableManager< i1.$CategoriesAnnotationComposer, $CategoriesCreateCompanionBuilder, $CategoriesUpdateCompanionBuilder, - ( - i1.Category, - i0.BaseReferences - ), + (i1.Category, i1.$CategoriesReferences), i1.Category, i0.PrefetchHooks Function({bool todosRefs})>; diff --git a/docs/lib/snippets/modular/drift/with_existing.drift.dart b/docs/lib/snippets/modular/drift/with_existing.drift.dart index e3b9ec15e..25a3f3bd9 100644 --- a/docs/lib/snippets/modular/drift/with_existing.drift.dart +++ b/docs/lib/snippets/modular/drift/with_existing.drift.dart @@ -130,6 +130,49 @@ typedef $FriendsUpdateCompanionBuilder = i2.FriendsCompanion Function({ i0.Value rowid, }); +final class $FriendsReferences + extends i0.BaseReferences { + $FriendsReferences(super.$_db, super.$_table, super.$_typedResult); + + static i2.Users _userATable(i0.GeneratedDatabase db) => + i3.ReadDatabaseContainer(db).resultSet('users').createAlias( + i0.$_aliasNameGenerator( + i3.ReadDatabaseContainer(db) + .resultSet('friends') + .userA, + i3.ReadDatabaseContainer(db).resultSet('users').id)); + + i2.$UsersProcessedTableManager get userA { + final manager = i2 + .$UsersTableManager( + $_db, i3.ReadDatabaseContainer($_db).resultSet('users')) + .filter((f) => f.id($_item.userA)); + final item = $_typedResult.readTableOrNull(_userATable($_db)); + if (item == null) return manager; + return i0.ProcessedTableManager( + manager.$state.copyWith(prefetchedData: [item])); + } + + static i2.Users _userBTable(i0.GeneratedDatabase db) => + i3.ReadDatabaseContainer(db).resultSet('users').createAlias( + i0.$_aliasNameGenerator( + i3.ReadDatabaseContainer(db) + .resultSet('friends') + .userB, + i3.ReadDatabaseContainer(db).resultSet('users').id)); + + i2.$UsersProcessedTableManager get userB { + final manager = i2 + .$UsersTableManager( + $_db, i3.ReadDatabaseContainer($_db).resultSet('users')) + .filter((f) => f.id($_item.userB)); + final item = $_typedResult.readTableOrNull(_userBTable($_db)); + if (item == null) return manager; + return i0.ProcessedTableManager( + manager.$state.copyWith(prefetchedData: [item])); + } +} + class $FriendsFilterComposer extends i0.Composer { $FriendsFilterComposer({ @@ -301,7 +344,7 @@ class $FriendsTableManager extends i0.RootTableManager< i2.$FriendsAnnotationComposer, $FriendsCreateCompanionBuilder, $FriendsUpdateCompanionBuilder, - (i2.Friend, i0.BaseReferences), + (i2.Friend, i2.$FriendsReferences), i2.Friend, i0.PrefetchHooks Function({bool userA, bool userB})> { $FriendsTableManager(i0.GeneratedDatabase db, i2.Friends table) @@ -335,7 +378,8 @@ class $FriendsTableManager extends i0.RootTableManager< rowid: rowid, ), withReferenceMapper: (p0) => p0 - .map((e) => (e.readTable(table), i0.BaseReferences(db, table, e))) + .map((e) => + (e.readTable(table), i2.$FriendsReferences(db, table, e))) .toList(), prefetchHooksCallback: null, )); @@ -350,7 +394,7 @@ typedef $FriendsProcessedTableManager = i0.ProcessedTableManager< i2.$FriendsAnnotationComposer, $FriendsCreateCompanionBuilder, $FriendsUpdateCompanionBuilder, - (i2.Friend, i0.BaseReferences), + (i2.Friend, i2.$FriendsReferences), i2.Friend, i0.PrefetchHooks Function({bool userA, bool userB})>; diff --git a/docs/lib/snippets/modular/many_to_many/relational.drift.dart b/docs/lib/snippets/modular/many_to_many/relational.drift.dart index 812d100f2..91b98ca42 100644 --- a/docs/lib/snippets/modular/many_to_many/relational.drift.dart +++ b/docs/lib/snippets/modular/many_to_many/relational.drift.dart @@ -17,6 +17,42 @@ typedef $$ShoppingCartsTableUpdateCompanionBuilder = i2.ShoppingCartsCompanion i0.Value id, }); +final class $$ShoppingCartsTableReferences extends i0.BaseReferences< + i0.GeneratedDatabase, i2.$ShoppingCartsTable, i2.ShoppingCart> { + $$ShoppingCartsTableReferences( + super.$_db, super.$_table, super.$_typedResult); + + static i0 + .MultiTypedResultKey> + _shoppingCartEntriesRefsTable(i0.GeneratedDatabase db) => + i0.MultiTypedResultKey.fromTable( + i4.ReadDatabaseContainer(db).resultSet( + 'shopping_cart_entries'), + aliasName: i0.$_aliasNameGenerator( + i4.ReadDatabaseContainer(db) + .resultSet('shopping_carts') + .id, + i4.ReadDatabaseContainer(db) + .resultSet('shopping_cart_entries') + .shoppingCart)); + + i2.$$ShoppingCartEntriesTableProcessedTableManager + get shoppingCartEntriesRefs { + final manager = i2 + .$$ShoppingCartEntriesTableTableManager( + $_db, + i4.ReadDatabaseContainer($_db) + .resultSet( + 'shopping_cart_entries')) + .filter((f) => f.shoppingCart.id($_item.id)); + + final cache = + $_typedResult.readTableOrNull(_shoppingCartEntriesRefsTable($_db)); + return i0.ProcessedTableManager( + manager.$state.copyWith(prefetchedData: cache)); + } +} + class $$ShoppingCartsTableFilterComposer extends i0.Composer { $$ShoppingCartsTableFilterComposer({ @@ -121,11 +157,7 @@ class $$ShoppingCartsTableTableManager extends i0.RootTableManager< i2.$$ShoppingCartsTableAnnotationComposer, $$ShoppingCartsTableCreateCompanionBuilder, $$ShoppingCartsTableUpdateCompanionBuilder, - ( - i2.ShoppingCart, - i0.BaseReferences - ), + (i2.ShoppingCart, i2.$$ShoppingCartsTableReferences), i2.ShoppingCart, i0.PrefetchHooks Function({bool shoppingCartEntriesRefs})> { $$ShoppingCartsTableTableManager( @@ -152,7 +184,10 @@ class $$ShoppingCartsTableTableManager extends i0.RootTableManager< id: id, ), withReferenceMapper: (p0) => p0 - .map((e) => (e.readTable(table), i0.BaseReferences(db, table, e))) + .map((e) => ( + e.readTable(table), + i2.$$ShoppingCartsTableReferences(db, table, e) + )) .toList(), prefetchHooksCallback: null, )); @@ -167,11 +202,7 @@ typedef $$ShoppingCartsTableProcessedTableManager = i0.ProcessedTableManager< i2.$$ShoppingCartsTableAnnotationComposer, $$ShoppingCartsTableCreateCompanionBuilder, $$ShoppingCartsTableUpdateCompanionBuilder, - ( - i2.ShoppingCart, - i0.BaseReferences - ), + (i2.ShoppingCart, i2.$$ShoppingCartsTableReferences), i2.ShoppingCart, i0.PrefetchHooks Function({bool shoppingCartEntriesRefs})>; typedef $$ShoppingCartEntriesTableCreateCompanionBuilder @@ -187,6 +218,62 @@ typedef $$ShoppingCartEntriesTableUpdateCompanionBuilder i0.Value rowid, }); +final class $$ShoppingCartEntriesTableReferences extends i0.BaseReferences< + i0.GeneratedDatabase, i2.$ShoppingCartEntriesTable, i2.ShoppingCartEntry> { + $$ShoppingCartEntriesTableReferences( + super.$_db, super.$_table, super.$_typedResult); + + static i2.$ShoppingCartsTable _shoppingCartTable(i0.GeneratedDatabase db) => + i4.ReadDatabaseContainer(db) + .resultSet('shopping_carts') + .createAlias(i0.$_aliasNameGenerator( + i4.ReadDatabaseContainer(db) + .resultSet( + 'shopping_cart_entries') + .shoppingCart, + i4.ReadDatabaseContainer(db) + .resultSet('shopping_carts') + .id)); + + i2.$$ShoppingCartsTableProcessedTableManager get shoppingCart { + final manager = i2 + .$$ShoppingCartsTableTableManager( + $_db, + i4.ReadDatabaseContainer($_db) + .resultSet('shopping_carts')) + .filter((f) => f.id($_item.shoppingCart)); + final item = $_typedResult.readTableOrNull(_shoppingCartTable($_db)); + if (item == null) return manager; + return i0.ProcessedTableManager( + manager.$state.copyWith(prefetchedData: [item])); + } + + static i1.$BuyableItemsTable _itemTable(i0.GeneratedDatabase db) => + i4.ReadDatabaseContainer(db) + .resultSet('buyable_items') + .createAlias(i0.$_aliasNameGenerator( + i4.ReadDatabaseContainer(db) + .resultSet( + 'shopping_cart_entries') + .item, + i4.ReadDatabaseContainer(db) + .resultSet('buyable_items') + .id)); + + i1.$$BuyableItemsTableProcessedTableManager get item { + final manager = i1 + .$$BuyableItemsTableTableManager( + $_db, + i4.ReadDatabaseContainer($_db) + .resultSet('buyable_items')) + .filter((f) => f.id($_item.item)); + final item = $_typedResult.readTableOrNull(_itemTable($_db)); + if (item == null) return manager; + return i0.ProcessedTableManager( + manager.$state.copyWith(prefetchedData: [item])); + } +} + class $$ShoppingCartEntriesTableFilterComposer extends i0.Composer { $$ShoppingCartEntriesTableFilterComposer({ @@ -358,11 +445,7 @@ class $$ShoppingCartEntriesTableTableManager extends i0.RootTableManager< i2.$$ShoppingCartEntriesTableAnnotationComposer, $$ShoppingCartEntriesTableCreateCompanionBuilder, $$ShoppingCartEntriesTableUpdateCompanionBuilder, - ( - i2.ShoppingCartEntry, - i0.BaseReferences - ), + (i2.ShoppingCartEntry, i2.$$ShoppingCartEntriesTableReferences), i2.ShoppingCartEntry, i0.PrefetchHooks Function({bool shoppingCart, bool item})> { $$ShoppingCartEntriesTableTableManager( @@ -399,7 +482,10 @@ class $$ShoppingCartEntriesTableTableManager extends i0.RootTableManager< rowid: rowid, ), withReferenceMapper: (p0) => p0 - .map((e) => (e.readTable(table), i0.BaseReferences(db, table, e))) + .map((e) => ( + e.readTable(table), + i2.$$ShoppingCartEntriesTableReferences(db, table, e) + )) .toList(), prefetchHooksCallback: null, )); @@ -415,11 +501,7 @@ typedef $$ShoppingCartEntriesTableProcessedTableManager i2.$$ShoppingCartEntriesTableAnnotationComposer, $$ShoppingCartEntriesTableCreateCompanionBuilder, $$ShoppingCartEntriesTableUpdateCompanionBuilder, - ( - i2.ShoppingCartEntry, - i0.BaseReferences - ), + (i2.ShoppingCartEntry, i2.$$ShoppingCartEntriesTableReferences), i2.ShoppingCartEntry, i0.PrefetchHooks Function({bool shoppingCart, bool item})>; diff --git a/drift/example/main.g.dart b/drift/example/main.g.dart index d8150a0e1..d38b72c65 100644 --- a/drift/example/main.g.dart +++ b/drift/example/main.g.dart @@ -941,7 +941,7 @@ final class $$TodoItemsTableReferences $$TodoCategoriesTableProcessedTableManager get categoryId { final manager = $$TodoCategoriesTableTableManager($_db, $_db.todoCategories) - .filter((f) => f.id($_item.categoryId!)); + .filter((f) => f.id($_item.categoryId)); final item = $_typedResult.readTableOrNull(_categoryIdTable($_db)); if (item == null) return manager; return ProcessedTableManager( diff --git a/drift/test/generated/todos.g.dart b/drift/test/generated/todos.g.dart index 6751a0820..0459b4219 100644 --- a/drift/test/generated/todos.g.dart +++ b/drift/test/generated/todos.g.dart @@ -5607,7 +5607,7 @@ final class $$ListingTableReferences $$ProductTableProcessedTableManager get product { final manager = $$ProductTableTableManager($_db, $_db.product) - .filter((f) => f.sku($_item.product!)); + .filter((f) => f.sku($_item.product)); final item = $_typedResult.readTableOrNull(_productTable($_db)); if (item == null) return manager; return ProcessedTableManager( diff --git a/drift_dev/CHANGELOG.md b/drift_dev/CHANGELOG.md index 0c0793947..9f0bd9edd 100644 --- a/drift_dev/CHANGELOG.md +++ b/drift_dev/CHANGELOG.md @@ -1,3 +1,9 @@ +## 2.23.1-dev + +- Generate typed reference-resolving queries through the manager API when + modular code-generation is enabled. Previously, this feature was only enabled + for monolithic generation modes. + ## 2.23.0 - Fix custom companion names on `@DataClassName` not being recognized. diff --git a/drift_dev/lib/src/writer/manager/manager_templates.dart b/drift_dev/lib/src/writer/manager/manager_templates.dart index cfab7c7b6..fd1a01a26 100644 --- a/drift_dev/lib/src/writer/manager/manager_templates.dart +++ b/drift_dev/lib/src/writer/manager/manager_templates.dart @@ -243,7 +243,7 @@ class _ManagerCodeTemplates { (e.readTable(table), ${rowReferencesClassName(table: table, relations: relations, dbClassName: dbClassName, leaf: leaf, withTypeArgs: false)}(db, table, e)) ) .toList(), - prefetchHooksCallback: ${relations.isEmpty || _scope.generationOptions.isModular ? 'null' : """ + prefetchHooksCallback: ${relations.isEmpty ? 'null' : """ (${"{${relations.map( (e) => "${e.fieldName} = false", ).join(",")}}"}){ @@ -251,11 +251,13 @@ class _ManagerCodeTemplates { db: db, explicitlyWatchedTables: [ ${reverseRelations.map((relation) { - return "if (${relation.fieldName}) db.${relation.referencedTable.dbGetterName}"; + final table = + leaf.referenceElement(relation.referencedTable, 'db'); + return "if (${relation.fieldName}) ${leaf.dartCode(table)}"; }).join(',')} ], addJoins: ${forwardRelations.isEmpty ? 'null' : """ ->(state) { +>(state) { ${forwardRelations.map((relation) { final referencesClassName = rowReferencesClassName( @@ -436,7 +438,7 @@ class _ManagerCodeTemplates { return """${leaf.drift("ColumnFilters")}<$type> get $filterName => \$composableBuilder( column: \$table.$columnGetter, - builder: (column) => + builder: (column) => ${leaf.drift("ColumnFilters")}(column)); """; } @@ -453,7 +455,7 @@ class _ManagerCodeTemplates { return """ ${leaf.drift("ColumnWithTypeConverterFilters")}<$converterType,$nonNullableConverterType,$type> get $filterName => \$composableBuilder( column: \$table.$columnGetter, - builder: (column) => + builder: (column) => ${leaf.drift("ColumnWithTypeConverterFilters")}(column)); """; } @@ -489,7 +491,7 @@ class _ManagerCodeTemplates { return """${leaf.drift("ColumnOrderings")}<$type> get $filterName => \$composableBuilder( column: \$table.$columnGetter, - builder: (column) => + builder: (column) => ${leaf.drift("ColumnOrderings")}(column)); """; } @@ -517,7 +519,7 @@ class _ManagerCodeTemplates { getCurrentColumn: (t) => t.${relation.currentColumn.nameInDart}, referencedTable: ${_referenceTableFromComposer(relation.referencedTable, leaf)}, getReferencedColumn: (t) => t.${relation.referencedColumn.nameInDart}, - builder: (joinBuilder,{\$addJoinBuilderToRootComposer,\$removeJoinBuilderFromRootComposer }) => + builder: (joinBuilder,{\$addJoinBuilderToRootComposer,\$removeJoinBuilderFromRootComposer }) => $composerName( \$db: \$db, \$table: ${_referenceTableFromComposer(relation.referencedTable, leaf)}, @@ -534,8 +536,12 @@ class _ManagerCodeTemplates { /// as the table manager and is not used outside of the file /// /// E.g. `$UserTableProcessedTableManager` - String processedTableManagerTypedefName(DriftTable table) { - return '\$${table.entityInfoName}ProcessedTableManager'; + String processedTableManagerTypedefName(DriftTable table, TextEmitter leaf, + {bool forDefinition = false}) { + final name = '\$${table.entityInfoName}ProcessedTableManager'; + return forDefinition + ? name + : leaf.dartCode(leaf.generatedElement(table, name)); } /// Code for a processed table manager typedef @@ -545,20 +551,28 @@ class _ManagerCodeTemplates { required TextEmitter leaf, required List<_Relation> relations, }) { - return """typedef ${processedTableManagerTypedefName(table)} = ${leaf.drift("ProcessedTableManager")}${_tableManagerTypeArguments(table, dbClassName, leaf, relations)};"""; + return """typedef ${processedTableManagerTypedefName(table, leaf, forDefinition: true)} = ${leaf.drift("ProcessedTableManager")}${_tableManagerTypeArguments(table, dbClassName, leaf, relations)};"""; } /// Name of the class which is used to represent a rows references /// /// If there are no relations, or if generation is modular, we will generate a base class instead. - String rowReferencesClassName( - {required DriftTable table, - required List<_Relation> relations, - required String dbClassName, - required TextEmitter leaf, - required bool withTypeArgs}) { - if (!_scope.generationOptions.isModular && relations.isNotEmpty) { - return '\$${table.entityInfoName}References'; + String rowReferencesClassName({ + required DriftTable table, + required List<_Relation> relations, + required String dbClassName, + required TextEmitter leaf, + required bool withTypeArgs, + bool forDefinition = false, + }) { + if (relations.isNotEmpty) { + final basename = '\$${table.entityInfoName}References'; + + if (forDefinition) { + return basename; + } else { + return leaf.dartCode(leaf.generatedElement(table, basename)); + } } else { if (withTypeArgs) { return "${leaf.drift('BaseReferences')}<${databaseType(leaf, dbClassName)},${tableClassWithPrefix(table, leaf)},${rowClassWithPrefix(table, leaf)}>"; @@ -590,11 +604,16 @@ class _ManagerCodeTemplates { relations: relations, dbClassName: dbClassName, leaf: leaf, - withTypeArgs: false); + withTypeArgs: false, + forDefinition: true); final body = relations.map( (relation) { final dbName = databaseType(leaf, dbClassName); + final referencedTable = leaf + .dartCode(leaf.referenceElement(relation.referencedTable, 'db')); + final currentTable = + leaf.dartCode(leaf.referenceElement(relation.currentTable, 'db')); if (relation.isReverse) { final aliasedTableMethod = """ @@ -603,19 +622,18 @@ class _ManagerCodeTemplates { List<${rowClassWithPrefix(relation.referencedTable, leaf)}> > _${relation.fieldName}Table($dbName db) => ${leaf.drift("MultiTypedResultKey")}.fromTable( - db.${relation.referencedTable.dbGetterName}, + $referencedTable, aliasName: ${leaf.drift("\$_aliasNameGenerator")}( - db.${relation.currentTable.dbGetterName}.${relation.currentColumn.nameInDart}, - db.${relation.referencedTable.dbGetterName}.${relation.referencedColumn.nameInDart}) + $currentTable.${relation.currentColumn.nameInDart}, + $referencedTable.${relation.referencedColumn.nameInDart}) );"""; return """ - $aliasedTableMethod - ${processedTableManagerTypedefName(relation.referencedTable)} get ${relation.fieldName} { + ${processedTableManagerTypedefName(relation.referencedTable, leaf)} get ${relation.fieldName} { final manager = ${rootTableManagerWithPrefix(relation.referencedTable, leaf)}( - \$_db, \$_db.${relation.referencedTable.dbGetterName} + \$_db, ${leaf.dartCode(leaf.referenceElement(relation.referencedTable, r'$_db'))} ).filter( (f) => f.${relation.referencedColumn.nameInDart}.${relation.currentColumn.nameInDart}( \$_item.${relation.currentColumn.nameInDart} @@ -623,9 +641,7 @@ class _ManagerCodeTemplates { ); final cache = \$_typedResult.readTableOrNull(_${relation.fieldName}Table(\$_db)); - return ProcessedTableManager(manager.\$state.copyWith(prefetchedData: cache)); - - + return ${leaf.drift("ProcessedTableManager")}(manager.\$state.copyWith(prefetchedData: cache)); } """; } else { @@ -633,21 +649,27 @@ class _ManagerCodeTemplates { tableClassWithPrefix(relation.referencedTable, leaf); final aliasedTableMethod = """ - static $referenceTableType _${relation.fieldName}Table($dbName db) => - db.${relation.referencedTable.dbGetterName}.createAlias(${leaf.drift("\$_aliasNameGenerator")}( - db.${relation.currentTable.dbGetterName}.${relation.currentColumn.nameInDart}, - db.${relation.referencedTable.dbGetterName}.${relation.referencedColumn.nameInDart})); + static $referenceTableType _${relation.fieldName}Table($dbName db) => + $referencedTable.createAlias(${leaf.drift("\$_aliasNameGenerator")}( + $currentTable.${relation.currentColumn.nameInDart}, + $referencedTable.${relation.referencedColumn.nameInDart})); """; + var currentColumnOnItem = + '\$_item.${relation.currentColumn.nameInDart}'; + if (relation.currentColumn.nullableInDart) { + currentColumnOnItem += '!'; + } + return """ $aliasedTableMethod - ${processedTableManagerTypedefName(relation.referencedTable)}${relation.currentColumn.nullable ? "?" : ""} get ${relation.fieldName} { + ${processedTableManagerTypedefName(relation.referencedTable, leaf)}${relation.currentColumn.nullable ? "?" : ""} get ${relation.fieldName} { ${relation.currentColumn.nullable ? "if (\$_item.${relation.currentColumn.nameInDart} == null) return null;" : ""} - final manager = ${rootTableManagerWithPrefix(relation.referencedTable, leaf)}(\$_db, \$_db.${relation.referencedTable.dbGetterName}).filter((f) => f.${relation.referencedColumn.nameInDart}(\$_item.${relation.currentColumn.nameInDart}!)); + final manager = ${rootTableManagerWithPrefix(relation.referencedTable, leaf)}(\$_db, ${leaf.dartCode(leaf.referenceElement(relation.referencedTable, r'$_db'))}).filter((f) => f.${relation.referencedColumn.nameInDart}($currentColumnOnItem)); final item = \$_typedResult.readTableOrNull(_${relation.fieldName}Table(\$_db)); if (item == null) return manager; - return ProcessedTableManager(manager.\$state.copyWith(prefetchedData: [item])); + return ${leaf.drift("ProcessedTableManager")}(manager.\$state.copyWith(prefetchedData: [item])); } """; } @@ -660,7 +682,7 @@ class _ManagerCodeTemplates { ${tableClassWithPrefix(table, leaf)}, ${rowClassWithPrefix(table, leaf)}> { $rowClassWithReferencesName(super.\$_db, super.\$_table, super.\$_typedResult); - + $body }"""; diff --git a/drift_dev/lib/src/writer/manager/table_manager_writer.dart b/drift_dev/lib/src/writer/manager/table_manager_writer.dart index 2b68ff57f..181b6914f 100644 --- a/drift_dev/lib/src/writer/manager/table_manager_writer.dart +++ b/drift_dev/lib/src/writer/manager/table_manager_writer.dart @@ -88,11 +88,14 @@ class _TableManagerWriter { .where((fieldName) => fieldName == relation.fieldName) .length; if (fieldNameCount != 1) { - print( - "Duplicate orderings/filters detected for field \"${relation.fieldName}\" on table \"${table.entityInfoName}\"." - " Filter and orderings for this field wont be generated." - " Use the @ReferenceName() annotation to resolve this issue." - " See https://drift.simonbinder.eu/docs/manager/#name-clashes for more information"); + if (table.id.isDefinedInDart) { + print( + "Duplicate orderings/filters detected for field \"${relation.fieldName}\" on table \"${table.entityInfoName}\"." + " Filter and orderings for this field wont be generated." + " Use the @ReferenceName() annotation to resolve this issue." + " See https://drift.simonbinder.eu/docs/manager/#name-clashes for more information"); + } + return false; } return true; @@ -170,7 +173,7 @@ class _TableManagerWriter { .add(_templates.relatedAnnotations(leaf: leaf, relation: relation)); } - if (!scope.generationOptions.isModular && relations.isNotEmpty) { + if (relations.isNotEmpty) { leaf.write(_templates.rowReferencesClass( table: table, relations: relations, diff --git a/drift_dev/pubspec.yaml b/drift_dev/pubspec.yaml index de9e7f15e..3e7d9e255 100644 --- a/drift_dev/pubspec.yaml +++ b/drift_dev/pubspec.yaml @@ -1,6 +1,6 @@ name: drift_dev description: Dev-dependency for users of drift. Contains the generator and development tools. -version: 2.23.0 +version: 2.23.1-dev repository: https://github.com/simolus3/drift homepage: https://drift.simonbinder.eu/ issue_tracker: https://github.com/simolus3/drift/issues diff --git a/examples/migrations_example/lib/database.g.dart b/examples/migrations_example/lib/database.g.dart index c0d767d0a..3028fb9a4 100644 --- a/examples/migrations_example/lib/database.g.dart +++ b/examples/migrations_example/lib/database.g.dart @@ -1266,7 +1266,7 @@ final class $GroupsReferences $$UsersTableProcessedTableManager get owner { final manager = $$UsersTableTableManager($_db, $_db.users) - .filter((f) => f.id($_item.owner!)); + .filter((f) => f.id($_item.owner)); final item = $_typedResult.readTableOrNull(_ownerTable($_db)); if (item == null) return manager; return ProcessedTableManager( diff --git a/examples/modular/lib/src/posts.drift.dart b/examples/modular/lib/src/posts.drift.dart index bf15130a2..2eb4e5589 100644 --- a/examples/modular/lib/src/posts.drift.dart +++ b/examples/modular/lib/src/posts.drift.dart @@ -16,6 +16,47 @@ typedef $PostsUpdateCompanionBuilder = i1.PostsCompanion Function({ i0.Value content, }); +final class $PostsReferences + extends i0.BaseReferences { + $PostsReferences(super.$_db, super.$_table, super.$_typedResult); + + static i2.Users _authorTable(i0.GeneratedDatabase db) => + i3.ReadDatabaseContainer(db).resultSet('users').createAlias( + i0.$_aliasNameGenerator( + i3.ReadDatabaseContainer(db).resultSet('posts').author, + i3.ReadDatabaseContainer(db).resultSet('users').id)); + + i2.$UsersProcessedTableManager get author { + final manager = i2 + .$UsersTableManager( + $_db, i3.ReadDatabaseContainer($_db).resultSet('users')) + .filter((f) => f.id($_item.author)); + final item = $_typedResult.readTableOrNull(_authorTable($_db)); + if (item == null) return manager; + return i0.ProcessedTableManager( + manager.$state.copyWith(prefetchedData: [item])); + } + + static i0.MultiTypedResultKey> _likesRefsTable( + i0.GeneratedDatabase db) => + i0.MultiTypedResultKey.fromTable( + i3.ReadDatabaseContainer(db).resultSet('likes'), + aliasName: i0.$_aliasNameGenerator( + i3.ReadDatabaseContainer(db).resultSet('posts').id, + i3.ReadDatabaseContainer(db).resultSet('likes').post)); + + i1.$LikesProcessedTableManager get likesRefs { + final manager = i1 + .$LikesTableManager( + $_db, i3.ReadDatabaseContainer($_db).resultSet('likes')) + .filter((f) => f.post.id($_item.id)); + + final cache = $_typedResult.readTableOrNull(_likesRefsTable($_db)); + return i0.ProcessedTableManager( + manager.$state.copyWith(prefetchedData: cache)); + } +} + class $PostsFilterComposer extends i0.Composer { $PostsFilterComposer({ required super.$db, @@ -184,7 +225,7 @@ class $PostsTableManager extends i0.RootTableManager< i1.$PostsAnnotationComposer, $PostsCreateCompanionBuilder, $PostsUpdateCompanionBuilder, - (i1.Post, i0.BaseReferences), + (i1.Post, i1.$PostsReferences), i1.Post, i0.PrefetchHooks Function({bool author, bool likesRefs})> { $PostsTableManager(i0.GeneratedDatabase db, i1.Posts table) @@ -218,9 +259,57 @@ class $PostsTableManager extends i0.RootTableManager< content: content, ), withReferenceMapper: (p0) => p0 - .map((e) => (e.readTable(table), i0.BaseReferences(db, table, e))) + .map((e) => + (e.readTable(table), i1.$PostsReferences(db, table, e))) .toList(), - prefetchHooksCallback: null, + prefetchHooksCallback: ({author = false, likesRefs = false}) { + return i0.PrefetchHooks( + db: db, + explicitlyWatchedTables: [ + if (likesRefs) + i3.ReadDatabaseContainer(db).resultSet('likes') + ], + addJoins: < + T extends i0.TableManagerState< + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic>>(state) { + if (author) { + state = state.withJoin( + currentTable: table, + currentColumn: table.author, + referencedTable: i1.$PostsReferences._authorTable(db), + referencedColumn: i1.$PostsReferences._authorTable(db).id, + ) as T; + } + + return state; + }, + getPrefetchedDataCallback: (items) async { + return [ + if (likesRefs) + await i0.$_getPrefetchedData( + currentTable: table, + referencedTable: + i1.$PostsReferences._likesRefsTable(db), + managerFromTypedResult: (p0) => + i1.$PostsReferences(db, table, p0).likesRefs, + referencedItemsForCurrentItem: + (item, referencedItems) => + referencedItems.where((e) => e.post == item.id), + typedResults: items) + ]; + }, + ); + }, )); } @@ -233,7 +322,7 @@ typedef $PostsProcessedTableManager = i0.ProcessedTableManager< i1.$PostsAnnotationComposer, $PostsCreateCompanionBuilder, $PostsUpdateCompanionBuilder, - (i1.Post, i0.BaseReferences), + (i1.Post, i1.$PostsReferences), i1.Post, i0.PrefetchHooks Function({bool author, bool likesRefs})>; typedef $LikesCreateCompanionBuilder = i1.LikesCompanion Function({ @@ -247,6 +336,45 @@ typedef $LikesUpdateCompanionBuilder = i1.LikesCompanion Function({ i0.Value rowid, }); +final class $LikesReferences + extends i0.BaseReferences { + $LikesReferences(super.$_db, super.$_table, super.$_typedResult); + + static i1.Posts _postTable(i0.GeneratedDatabase db) => + i3.ReadDatabaseContainer(db).resultSet('posts').createAlias( + i0.$_aliasNameGenerator( + i3.ReadDatabaseContainer(db).resultSet('likes').post, + i3.ReadDatabaseContainer(db).resultSet('posts').id)); + + i1.$PostsProcessedTableManager get post { + final manager = i1 + .$PostsTableManager( + $_db, i3.ReadDatabaseContainer($_db).resultSet('posts')) + .filter((f) => f.id($_item.post)); + final item = $_typedResult.readTableOrNull(_postTable($_db)); + if (item == null) return manager; + return i0.ProcessedTableManager( + manager.$state.copyWith(prefetchedData: [item])); + } + + static i2.Users _likedByTable(i0.GeneratedDatabase db) => + i3.ReadDatabaseContainer(db).resultSet('users').createAlias( + i0.$_aliasNameGenerator( + i3.ReadDatabaseContainer(db).resultSet('likes').likedBy, + i3.ReadDatabaseContainer(db).resultSet('users').id)); + + i2.$UsersProcessedTableManager get likedBy { + final manager = i2 + .$UsersTableManager( + $_db, i3.ReadDatabaseContainer($_db).resultSet('users')) + .filter((f) => f.id($_item.likedBy)); + final item = $_typedResult.readTableOrNull(_likedByTable($_db)); + if (item == null) return manager; + return i0.ProcessedTableManager( + manager.$state.copyWith(prefetchedData: [item])); + } +} + class $LikesFilterComposer extends i0.Composer { $LikesFilterComposer({ required super.$db, @@ -417,7 +545,7 @@ class $LikesTableManager extends i0.RootTableManager< i1.$LikesAnnotationComposer, $LikesCreateCompanionBuilder, $LikesUpdateCompanionBuilder, - (i1.Like, i0.BaseReferences), + (i1.Like, i1.$LikesReferences), i1.Like, i0.PrefetchHooks Function({bool post, bool likedBy})> { $LikesTableManager(i0.GeneratedDatabase db, i1.Likes table) @@ -451,9 +579,50 @@ class $LikesTableManager extends i0.RootTableManager< rowid: rowid, ), withReferenceMapper: (p0) => p0 - .map((e) => (e.readTable(table), i0.BaseReferences(db, table, e))) + .map((e) => + (e.readTable(table), i1.$LikesReferences(db, table, e))) .toList(), - prefetchHooksCallback: null, + prefetchHooksCallback: ({post = false, likedBy = false}) { + return i0.PrefetchHooks( + db: db, + explicitlyWatchedTables: [], + addJoins: < + T extends i0.TableManagerState< + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic>>(state) { + if (post) { + state = state.withJoin( + currentTable: table, + currentColumn: table.post, + referencedTable: i1.$LikesReferences._postTable(db), + referencedColumn: i1.$LikesReferences._postTable(db).id, + ) as T; + } + if (likedBy) { + state = state.withJoin( + currentTable: table, + currentColumn: table.likedBy, + referencedTable: i1.$LikesReferences._likedByTable(db), + referencedColumn: i1.$LikesReferences._likedByTable(db).id, + ) as T; + } + + return state; + }, + getPrefetchedDataCallback: (items) async { + return []; + }, + ); + }, )); } @@ -466,7 +635,7 @@ typedef $LikesProcessedTableManager = i0.ProcessedTableManager< i1.$LikesAnnotationComposer, $LikesCreateCompanionBuilder, $LikesUpdateCompanionBuilder, - (i1.Like, i0.BaseReferences), + (i1.Like, i1.$LikesReferences), i1.Like, i0.PrefetchHooks Function({bool post, bool likedBy})>; diff --git a/examples/modular/lib/src/users.drift.dart b/examples/modular/lib/src/users.drift.dart index 7851adb8b..0be2692af 100644 --- a/examples/modular/lib/src/users.drift.dart +++ b/examples/modular/lib/src/users.drift.dart @@ -182,6 +182,49 @@ typedef $FollowsUpdateCompanionBuilder = i1.FollowsCompanion Function({ i0.Value rowid, }); +final class $FollowsReferences + extends i0.BaseReferences { + $FollowsReferences(super.$_db, super.$_table, super.$_typedResult); + + static i1.Users _followedTable(i0.GeneratedDatabase db) => + i4.ReadDatabaseContainer(db).resultSet('users').createAlias( + i0.$_aliasNameGenerator( + i4.ReadDatabaseContainer(db) + .resultSet('follows') + .followed, + i4.ReadDatabaseContainer(db).resultSet('users').id)); + + i1.$UsersProcessedTableManager get followed { + final manager = i1 + .$UsersTableManager( + $_db, i4.ReadDatabaseContainer($_db).resultSet('users')) + .filter((f) => f.id($_item.followed)); + final item = $_typedResult.readTableOrNull(_followedTable($_db)); + if (item == null) return manager; + return i0.ProcessedTableManager( + manager.$state.copyWith(prefetchedData: [item])); + } + + static i1.Users _followerTable(i0.GeneratedDatabase db) => + i4.ReadDatabaseContainer(db).resultSet('users').createAlias( + i0.$_aliasNameGenerator( + i4.ReadDatabaseContainer(db) + .resultSet('follows') + .follower, + i4.ReadDatabaseContainer(db).resultSet('users').id)); + + i1.$UsersProcessedTableManager get follower { + final manager = i1 + .$UsersTableManager( + $_db, i4.ReadDatabaseContainer($_db).resultSet('users')) + .filter((f) => f.id($_item.follower)); + final item = $_typedResult.readTableOrNull(_followerTable($_db)); + if (item == null) return manager; + return i0.ProcessedTableManager( + manager.$state.copyWith(prefetchedData: [item])); + } +} + class $FollowsFilterComposer extends i0.Composer { $FollowsFilterComposer({ @@ -353,7 +396,7 @@ class $FollowsTableManager extends i0.RootTableManager< i1.$FollowsAnnotationComposer, $FollowsCreateCompanionBuilder, $FollowsUpdateCompanionBuilder, - (i1.Follow, i0.BaseReferences), + (i1.Follow, i1.$FollowsReferences), i1.Follow, i0.PrefetchHooks Function({bool followed, bool follower})> { $FollowsTableManager(i0.GeneratedDatabase db, i1.Follows table) @@ -387,9 +430,52 @@ class $FollowsTableManager extends i0.RootTableManager< rowid: rowid, ), withReferenceMapper: (p0) => p0 - .map((e) => (e.readTable(table), i0.BaseReferences(db, table, e))) + .map((e) => + (e.readTable(table), i1.$FollowsReferences(db, table, e))) .toList(), - prefetchHooksCallback: null, + prefetchHooksCallback: ({followed = false, follower = false}) { + return i0.PrefetchHooks( + db: db, + explicitlyWatchedTables: [], + addJoins: < + T extends i0.TableManagerState< + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic, + dynamic>>(state) { + if (followed) { + state = state.withJoin( + currentTable: table, + currentColumn: table.followed, + referencedTable: i1.$FollowsReferences._followedTable(db), + referencedColumn: + i1.$FollowsReferences._followedTable(db).id, + ) as T; + } + if (follower) { + state = state.withJoin( + currentTable: table, + currentColumn: table.follower, + referencedTable: i1.$FollowsReferences._followerTable(db), + referencedColumn: + i1.$FollowsReferences._followerTable(db).id, + ) as T; + } + + return state; + }, + getPrefetchedDataCallback: (items) async { + return []; + }, + ); + }, )); } @@ -402,7 +488,7 @@ typedef $FollowsProcessedTableManager = i0.ProcessedTableManager< i1.$FollowsAnnotationComposer, $FollowsCreateCompanionBuilder, $FollowsUpdateCompanionBuilder, - (i1.Follow, i0.BaseReferences), + (i1.Follow, i1.$FollowsReferences), i1.Follow, i0.PrefetchHooks Function({bool followed, bool follower})>; diff --git a/examples/modular/pubspec.yaml b/examples/modular/pubspec.yaml index 93f3b983b..b4e16a769 100644 --- a/examples/modular/pubspec.yaml +++ b/examples/modular/pubspec.yaml @@ -12,4 +12,4 @@ dev_dependencies: build_runner: ^2.3.2 drift_dev: lints: ^4.0.0 - test: ^1.16.0 + test: ^1.25.14 diff --git a/examples/modular/test/database_test.dart b/examples/modular/test/database_test.dart new file mode 100644 index 000000000..5fb702415 --- /dev/null +++ b/examples/modular/test/database_test.dart @@ -0,0 +1,36 @@ +import 'package:drift/drift.dart'; +import 'package:drift/native.dart'; +import 'package:modular/database.dart'; +import 'package:modular/src/posts.drift.dart'; +import 'package:modular/src/users.drift.dart'; +import 'package:test/test.dart'; + +void main() { + // These tests aren't really part of the example, we use them to make sure + // the modular code is working as intended. + late Database database; + + setUp(() { + database = Database(NativeDatabase.memory()); + }); + + tearDown(() => database.close()); + + test('can query posts', () async { + await database.batch((b) { + b.insertAll(database.users, [ + UsersCompanion.insert(name: 'a'), + UsersCompanion.insert(name: 'b'), + ]); + b.insert(database.posts, + PostsCompanion.insert(author: 1, content: Value('hello world'))); + }); + + final (post, refs) = await database.managers.posts + .withReferences((p) => p(author: true)) + .getSingle(); + + expect(post.content, 'hello world'); + expect(refs.author.prefetchedData, hasLength(1)); + }); +} diff --git a/examples/multi_package/server/lib/database.drift.dart b/examples/multi_package/server/lib/database.drift.dart index 87501c729..9aca6a295 100644 --- a/examples/multi_package/server/lib/database.drift.dart +++ b/examples/multi_package/server/lib/database.drift.dart @@ -21,6 +21,34 @@ typedef $$ActiveSessionsTableUpdateCompanionBuilder = i3.ActiveSessionsCompanion i0.Value rowid, }); +final class $$ActiveSessionsTableReferences extends i0.BaseReferences< + i0.GeneratedDatabase, i3.$ActiveSessionsTable, i3.ActiveSession> { + $$ActiveSessionsTableReferences( + super.$_db, super.$_table, super.$_typedResult); + + static i1.$UsersTable _userTable(i0.GeneratedDatabase db) => + i5.ReadDatabaseContainer(db) + .resultSet('users') + .createAlias(i0.$_aliasNameGenerator( + i5.ReadDatabaseContainer(db) + .resultSet('active_sessions') + .user, + i5.ReadDatabaseContainer(db) + .resultSet('users') + .id)); + + i1.$$UsersTableProcessedTableManager get user { + final manager = i1 + .$$UsersTableTableManager($_db, + i5.ReadDatabaseContainer($_db).resultSet('users')) + .filter((f) => f.id($_item.user)); + final item = $_typedResult.readTableOrNull(_userTable($_db)); + if (item == null) return manager; + return i0.ProcessedTableManager( + manager.$state.copyWith(prefetchedData: [item])); + } +} + class $$ActiveSessionsTableFilterComposer extends i0.Composer { $$ActiveSessionsTableFilterComposer({ @@ -137,11 +165,7 @@ class $$ActiveSessionsTableTableManager extends i0.RootTableManager< i3.$$ActiveSessionsTableAnnotationComposer, $$ActiveSessionsTableCreateCompanionBuilder, $$ActiveSessionsTableUpdateCompanionBuilder, - ( - i3.ActiveSession, - i0.BaseReferences - ), + (i3.ActiveSession, i3.$$ActiveSessionsTableReferences), i3.ActiveSession, i0.PrefetchHooks Function({bool user})> { $$ActiveSessionsTableTableManager( @@ -176,7 +200,10 @@ class $$ActiveSessionsTableTableManager extends i0.RootTableManager< rowid: rowid, ), withReferenceMapper: (p0) => p0 - .map((e) => (e.readTable(table), i0.BaseReferences(db, table, e))) + .map((e) => ( + e.readTable(table), + i3.$$ActiveSessionsTableReferences(db, table, e) + )) .toList(), prefetchHooksCallback: null, )); @@ -191,11 +218,7 @@ typedef $$ActiveSessionsTableProcessedTableManager = i0.ProcessedTableManager< i3.$$ActiveSessionsTableAnnotationComposer, $$ActiveSessionsTableCreateCompanionBuilder, $$ActiveSessionsTableUpdateCompanionBuilder, - ( - i3.ActiveSession, - i0.BaseReferences - ), + (i3.ActiveSession, i3.$$ActiveSessionsTableReferences), i3.ActiveSession, i0.PrefetchHooks Function({bool user})>; diff --git a/examples/multi_package/shared/lib/src/posts.drift.dart b/examples/multi_package/shared/lib/src/posts.drift.dart index 484c4360b..7ff72341f 100644 --- a/examples/multi_package/shared/lib/src/posts.drift.dart +++ b/examples/multi_package/shared/lib/src/posts.drift.dart @@ -16,6 +16,31 @@ typedef $PostsUpdateCompanionBuilder = i1.PostsCompanion Function({ i0.Value rowid, }); +final class $PostsReferences + extends i0.BaseReferences { + $PostsReferences(super.$_db, super.$_table, super.$_typedResult); + + static i2.$UsersTable _authorTable(i0.GeneratedDatabase db) => + i3.ReadDatabaseContainer(db) + .resultSet('users') + .createAlias(i0.$_aliasNameGenerator( + i3.ReadDatabaseContainer(db).resultSet('posts').author, + i3.ReadDatabaseContainer(db) + .resultSet('users') + .id)); + + i2.$$UsersTableProcessedTableManager get author { + final manager = i2 + .$$UsersTableTableManager($_db, + i3.ReadDatabaseContainer($_db).resultSet('users')) + .filter((f) => f.id($_item.author)); + final item = $_typedResult.readTableOrNull(_authorTable($_db)); + if (item == null) return manager; + return i0.ProcessedTableManager( + manager.$state.copyWith(prefetchedData: [item])); + } +} + class $PostsFilterComposer extends i0.Composer { $PostsFilterComposer({ required super.$db, @@ -129,7 +154,7 @@ class $PostsTableManager extends i0.RootTableManager< i1.$PostsAnnotationComposer, $PostsCreateCompanionBuilder, $PostsUpdateCompanionBuilder, - (i1.Post, i0.BaseReferences), + (i1.Post, i1.$PostsReferences), i1.Post, i0.PrefetchHooks Function({bool author})> { $PostsTableManager(i0.GeneratedDatabase db, i1.Posts table) @@ -163,7 +188,8 @@ class $PostsTableManager extends i0.RootTableManager< rowid: rowid, ), withReferenceMapper: (p0) => p0 - .map((e) => (e.readTable(table), i0.BaseReferences(db, table, e))) + .map((e) => + (e.readTable(table), i1.$PostsReferences(db, table, e))) .toList(), prefetchHooksCallback: null, )); @@ -178,7 +204,7 @@ typedef $PostsProcessedTableManager = i0.ProcessedTableManager< i1.$PostsAnnotationComposer, $PostsCreateCompanionBuilder, $PostsUpdateCompanionBuilder, - (i1.Post, i0.BaseReferences), + (i1.Post, i1.$PostsReferences), i1.Post, i0.PrefetchHooks Function({bool author})>;