import 'package:moor/moor.dart'; part 'example.g.dart'; // Define tables that can model a database of recipes. @DataClassName('Category') class Categories extends Table { IntColumn get id => integer().autoIncrement()(); TextColumn get description => text().nullable()(); } class Recipes extends Table { IntColumn get id => integer().autoIncrement()(); TextColumn get title => text().withLength(max: 16)(); TextColumn get instructions => text()(); IntColumn get category => integer().nullable()(); } class Ingredients extends Table { IntColumn get id => integer().autoIncrement()(); TextColumn get name => text()(); IntColumn get caloriesPer100g => integer().named('calories')(); } class IngredientInRecipes extends Table { @override String get tableName => 'recipe_ingredients'; // We can also specify custom primary keys @override Set get primaryKey => {recipe, ingredient}; IntColumn get recipe => integer()(); IntColumn get ingredient => integer()(); IntColumn get amountInGrams => integer().named('amount')(); } @UseMoor( tables: [Categories, Recipes, Ingredients, IngredientInRecipes], queries: { // query to load the total weight for each recipe by loading all ingredients // and taking the sum of their amountInGrams. '_totalWeight': ''' SELECT r.title, SUM(ir.amount) AS total_weight FROM recipes r INNER JOIN recipe_ingredients ir ON ir.recipe = r.id GROUP BY r.id ''' }, ) class Database extends _$Database { Database(QueryExecutor e) : super(e); @override int get schemaVersion => 1; @override MigrationStrategy get migration { return MigrationStrategy( beforeOpen: (details) async { // populate data await into(categories) .insert(const CategoriesCompanion(description: Value('Sweets'))); }, ); } }