Skip to content

Commit

Permalink
Merge pull request #11 from owenbean400/constraints
Browse files Browse the repository at this point in the history
Added Constraints
  • Loading branch information
owenbean400 authored Dec 6, 2023
2 parents 4315ea8 + 109cafe commit 6ed7dd8
Show file tree
Hide file tree
Showing 9 changed files with 164 additions and 49 deletions.
2 changes: 1 addition & 1 deletion ios/fastlane/Fastfile
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ platform :ios do

flutter_versioncode_bump({
pubspec_location: "../pubspec.yaml",
version_code_increment: buildNumber + 1
version_code_increment: buildNumber
})
end

Expand Down
123 changes: 97 additions & 26 deletions lib/dao/recipe_roots_dao.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@ class RecipeRootsDAO {
final String databaseName = "recipeRoots.db";

Future<Database> getDatabase() async {
Database database = await openDatabase(databaseName, version: 5,
Database database = await openDatabase(databaseName, version: 6,
onCreate: (Database db, int version) async {
await db.execute(
"CREATE TABLE Recipe (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, description TEXT, image TEXT)");
"CREATE TABLE Recipe (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL CHECK(name <> ''), description TEXT, image TEXT)");
await db.execute(
"CREATE TABLE Cooking_Steps (id INTEGER PRIMARY KEY AUTOINCREMENT, recipe_id INT NOT NULL, step_order INT, instruction TEXT, FOREIGN KEY (recipe_id) REFERENCES Recipe(id) ON DELETE CASCADE, FOREIGN KEY (step_order) REFERENCES Cooking_Steps(id))");
"CREATE TABLE Cooking_Steps (id INTEGER PRIMARY KEY AUTOINCREMENT, recipe_id INT NOT NULL, step_order INT, instruction TEXT CHECK(instruction <> ''), FOREIGN KEY (recipe_id) REFERENCES Recipe(id) ON DELETE CASCADE, FOREIGN KEY (step_order) REFERENCES Cooking_Steps(id))");
await db.execute(
"CREATE TABLE Ingredient (id INTEGER PRIMARY KEY AUTOINCREMENT, recipe_id INT NOT NULL, amount TEXT, unit TEXT, ingredient TEXT, prep_method TEXT, FOREIGN KEY (recipe_id) REFERENCES Recipe(id) ON DELETE CASCADE)");
"CREATE TABLE Ingredient (id INTEGER PRIMARY KEY AUTOINCREMENT, recipe_id INT NOT NULL, amount TEXT, unit TEXT, ingredient TEXT CHECK(ingredient <> ''), prep_method TEXT, FOREIGN KEY (recipe_id) REFERENCES Recipe(id) ON DELETE CASCADE)");
await db.execute(
"CREATE TABLE Person (id INTEGER PRIMARY KEY AUTOINCREMENT, first_name TEXT, middle_name TEXT, last_name TEXT)");
"CREATE TABLE Person (id INTEGER PRIMARY KEY AUTOINCREMENT, first_name TEXT, middle_name TEXT, last_name TEXT, CHECK (first_name <> '' OR middle_name <> '' OR last_name <> ''))");
await db.execute(
"CREATE TABLE Family_Relation (id INTEGER PRIMARY KEY AUTOINCREMENT, from_person_id INTEGER, to_person_id INTEGER, relationship TEXT, FOREIGN KEY (from_person_id) REFERENCES Person (id) ON DELETE CASCADE, FOREIGN KEY (to_person_id) REFERENCES Person (id) ON DELETE CASCADE)");
await db.execute(
Expand All @@ -44,6 +44,43 @@ class RecipeRootsDAO {
"CREATE TABLE Position (id INTEGER PRIMARY KEY AUTOINCREMENT, person_id INTEGER, x REAL, y REAL, FOREIGN KEY (person_id) REFERENCES Person(id) ON DELETE CASCADE)");
}
}
if (oldVersion < 6) {
await db.execute(
"CREATE TABLE Recipe_new (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL CHECK(name <> ''), description TEXT, image TEXT)");
await db.execute(
"INSERT INTO Recipe_new (id, name, description, image) SELECT id, name, description, image FROM Recipe WHERE name <> ''");
await db.execute(
"DROP TABLE Recipe");
await db.execute(
"ALTER TABLE Recipe_new RENAME TO Recipe");

await db.execute(
"CREATE TABLE Person_new (id INTEGER PRIMARY KEY AUTOINCREMENT, first_name TEXT, middle_name TEXT, last_name TEXT, CHECK (first_name <> '' OR middle_name <> '' OR last_name <> ''))");
await db.execute(
"INSERT INTO Person_new (id, first_name, middle_name, last_name) SELECT id, first_name, middle_name, last_name FROM Person WHERE first_name <> '' OR middle_name <> '' OR last_name <> ''");
await db.execute(
"DROP TABLE Person");
await db.execute(
"ALTER TABLE Person_new RENAME TO Person");

await db.execute(
"CREATE TABLE Cooking_Steps_new (id INTEGER PRIMARY KEY AUTOINCREMENT, recipe_id INT NOT NULL, step_order INT, instruction TEXT CHECK(instruction <> ''), FOREIGN KEY (recipe_id) REFERENCES Recipe(id) ON DELETE CASCADE, FOREIGN KEY (step_order) REFERENCES Cooking_Steps(id))");
await db.execute(
"INSERT INTO Cooking_Steps_new (id, recipe_id, step_order, instruction) SELECT id, recipe_id, step_order, instruction FROM Cooking_Steps WHERE instruction <> ''");
await db.execute(
"DROP TABLE Cooking_Steps");
await db.execute(
"ALTER TABLE Cooking_Steps_new RENAME TO Cooking_Steps");

await db.execute(
"CREATE TABLE Ingredient_new (id INTEGER PRIMARY KEY AUTOINCREMENT, recipe_id INT NOT NULL, amount TEXT, unit TEXT, ingredient TEXT CHECK(ingredient <> ''), prep_method TEXT, FOREIGN KEY (recipe_id) REFERENCES Recipe(id) ON DELETE CASCADE)");
await db.execute(
"INSERT INTO Ingredient_new (id, recipe_id, amount, unit, ingredient, prep_method) SELECT id, recipe_id, amount, unit, ingredient, prep_method FROM Ingredient WHERE ingredient <> ''");
await db.execute(
"DROP TABLE Ingredient");
await db.execute(
"ALTER TABLE Ingredient_new RENAME TO Ingredient");
}
},
);

Expand Down Expand Up @@ -317,12 +354,9 @@ class RecipeRootsDAO {

Future<int> addPerson(Person add) async {
Database db = await getDatabase();

int id = await db.rawInsert(
return await db.rawInsert(
"INSERT INTO Person(first_name, middle_name, last_name) VALUES(?, ?, ?)",
[add.firstName, add.middleName, add.lastName]);

return id;
}

Future<int> addFamilyRelation(
Expand All @@ -338,9 +372,8 @@ class RecipeRootsDAO {
]);
}

Future<int> addRecipe(Recipe recipe) async {
Database db = await getDatabase();

Future<int> addRecipe(Recipe recipe, [DatabaseExecutor? txn]) async {
DatabaseExecutor db = txn ?? await getDatabase();
return await db.rawInsert(
"INSERT INTO Recipe (name, description) VALUES (?, ?)",
[recipe.title, recipe.desc]);
Expand All @@ -350,15 +383,15 @@ class RecipeRootsDAO {
List<CookingStep> cookingSteps, int recipeId, [DatabaseExecutor? txn]) async {
final db = txn ?? await getDatabase();
int priorId = -1;

for (CookingStep cookingStep in cookingSteps) {
priorId = await db.rawInsert(
"INSERT INTO Cooking_Steps (recipe_id, step_order, instruction) VALUES (?, ?, ?)",
[
recipeId,
(priorId == -1) ? "NULL" : priorId,
cookingStep.instruction
]);
priorId = await db.rawInsert(
"INSERT INTO Cooking_Steps (recipe_id, step_order, instruction) VALUES (?, ?, ?)",
[
recipeId,
(priorId == -1) ? "NULL" : priorId,
cookingStep.instruction
]);
}
}

Expand Down Expand Up @@ -387,9 +420,16 @@ class RecipeRootsDAO {
Future<void> addChildToParent(ChildToParent childToParent) async {
Database db = await getDatabase();

await db.rawInsert(
"INSERT INTO Child_To_Parent (child_id, parent_id) VALUEs (?, ?)",
[childToParent.child.id, childToParent.parent.id]);
List<Map> result = await db.query(
'Child_To_Parent',
where: 'child_id = ? AND parent_id = ?',
whereArgs: [childToParent.parent.id, childToParent.child.id]
);
if (result.isEmpty) {
await db.rawInsert(
"INSERT INTO Child_To_Parent (child_id, parent_id) VALUEs (?, ?)",
[childToParent.child.id, childToParent.parent.id]);
}
}

Future<int> updatePerson(Person person) async {
Expand Down Expand Up @@ -497,9 +537,23 @@ class RecipeRootsDAO {
Future<int> updateChildToPerson(ChildToParent childToParent) async {
Database db = await getDatabase();

return await db.rawUpdate(
"UPDATE Child_To_Parent SET child_id = ?, parent_id = ? WHERE id = ?",
[childToParent.child.id, childToParent.parent.id, childToParent.id]);
List<Map> result1 = await db.query(
'Child_To_Parent',
where: 'child_id = ? AND parent_id = ?',
whereArgs: [childToParent.parent.id, childToParent.child.id]
);
List<Map> result2 = await db.query(
'Child_To_Parent',
where: 'child_id = ? AND parent_id = ?',
whereArgs: [childToParent.child.id, childToParent.parent.id]
);
if (result1.isEmpty && result2.isEmpty) {
return await db.rawUpdate(
"UPDATE Child_To_Parent SET child_id = ?, parent_id = ? WHERE id = ?",
[childToParent.child.id, childToParent.parent.id, childToParent.id]);
} else {
return -1;
}
}

Future<int> deletePerson(Person person) async {
Expand Down Expand Up @@ -550,6 +604,23 @@ class RecipeRootsDAO {
"DELETE FROM Child_To_Parent WHERE id = ?", [childToParent.id ?? -1]);
}

Future<void> performRecipeAdd(EntireRecipe entireRecipe) async {
Database db = await getDatabase();
await db.transaction((txn) async {
int recipeId = await RecipeRootsDAO().addRecipe(entireRecipe.recipe, txn);

await addCookingSteps(entireRecipe.cookingSteps, recipeId, txn);

for (Ingredient ingredient in entireRecipe.ingredients) {
await addIngredients(ingredient, recipeId, txn);
}

for (Person person in entireRecipe.authors) {
await addPersonToRecipe(recipeId, person, txn);
}
});
}

Future<void> performRecipeEdit(EntireRecipe entireRecipe, int id) async {
Database db = await getDatabase();
await db.transaction((txn) async {
Expand Down
14 changes: 2 additions & 12 deletions lib/service/recipe_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -75,23 +75,13 @@ class RecipeService {
}

Future<void> addRecipe(EntireRecipe entireRecipe) async {
int recipeId = await RecipeRootsDAO().addRecipe(entireRecipe.recipe);

await RecipeRootsDAO().addCookingSteps(entireRecipe.cookingSteps, recipeId);

for (Ingredient ingredient in entireRecipe.ingredients) {
await RecipeRootsDAO().addIngredients(ingredient, recipeId);
}

for (Person person in entireRecipe.authors) {
await RecipeRootsDAO().addPersonToRecipe(recipeId, person);
}
await RecipeRootsDAO().performRecipeAdd(entireRecipe);
}

Future<void> editRecipe(EntireRecipe entireRecipe) async {
if (entireRecipe.recipe.id != null) {
int id = entireRecipe.recipe.id!;

await RecipeRootsDAO().performRecipeEdit(entireRecipe, id);
} else {
await addRecipe(entireRecipe);
Expand Down
18 changes: 18 additions & 0 deletions lib/view/widget/snackbar_error.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import 'package:flutter/material.dart';

SnackBar getErrorSnackbar(String text, BuildContext context) {
return SnackBar(
backgroundColor: Theme.of(context).hintColor,
content: Text(text,
style: TextStyle(
color: Colors.red.shade900,
fontSize: 12,
)),
duration: const Duration(milliseconds: 4000),
action: SnackBarAction(
backgroundColor: Theme.of(context).primaryColor,
textColor: Theme.of(context).primaryColorDark,
label: "OK",
onPressed: () {},
));
}
13 changes: 11 additions & 2 deletions lib/view/window/family_tree/family_tree_add.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:recipe_roots/domain/person.dart';
import 'package:recipe_roots/service/family_service.dart';
import 'package:recipe_roots/service/person_service.dart';
import 'package:recipe_roots/view/widget/header_backspace.dart';
import 'package:recipe_roots/view/widget/snackbar_error.dart';
import 'package:recipe_roots/view/window/recipe/widgets/person_drop_menu.dart';

class ChildToParentAdd extends StatefulWidget {
Expand All @@ -25,13 +26,21 @@ class ChildToParentAddState extends State<ChildToParentAdd> {
void update(ChildToParent updatedRecord) {
FamilyService()
.updateChildToParent(updatedRecord)
.then((value) => {widget.goToViewFamilyTree()});
.then((value) => {widget.goToViewFamilyTree()})
.catchError((e) => {
ScaffoldMessenger.of(context)
.showSnackBar(getErrorSnackbar(e.toString(), context))
});
}

void delete(ChildToParent deletedRecord) {
FamilyService()
.deleteChildToParent(deletedRecord)
.then((value) => {widget.goToViewFamilyTree()});
.then((value) => {widget.goToViewFamilyTree()})
.catchError((e) => {
ScaffoldMessenger.of(context)
.showSnackBar(getErrorSnackbar(e.toString(), context))
});
}

@override
Expand Down
13 changes: 11 additions & 2 deletions lib/view/window/people/people_add.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:recipe_roots/domain/person.dart';
import 'package:recipe_roots/helper/the_person.dart';
import 'package:recipe_roots/service/person_service.dart';
import 'package:recipe_roots/view/widget/header_backspace.dart';
import 'package:recipe_roots/view/widget/snackbar_error.dart';
import 'package:recipe_roots/view/window/people/widgets/people_field.dart';
import 'package:recipe_roots/view/window/people/widgets/people_text_field.dart';

Expand Down Expand Up @@ -42,7 +43,11 @@ class PeopleAddState extends State<PeopleAdd> {

PersonService()
.addFamilyRelation(ThePersonSingleton().user!, familyRelation)
.then((value) => {widget.setPeopleNavViewFunction()});
.then((value) => {widget.setPeopleNavViewFunction()})
.catchError((e) => {
ScaffoldMessenger.of(context)
.showSnackBar(getErrorSnackbar(e.toString(), context))
});
}

updatePerson() {
Expand All @@ -57,7 +62,11 @@ class PeopleAddState extends State<PeopleAdd> {

PersonService()
.updateFamilyRelation(familyRelation)
.then((value) => {widget.setPeopleNavViewFunction()});
.then((value) => {widget.setPeopleNavViewFunction()})
.catchError((e) => {
ScaffoldMessenger.of(context)
.showSnackBar(getErrorSnackbar(e.toString(), context))
});
}

deletePerson() {
Expand Down
7 changes: 6 additions & 1 deletion lib/view/window/recipe/recipe_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:recipe_roots/domain/entire_recipe.dart';
import 'package:recipe_roots/service/recipe_service.dart';
import 'package:recipe_roots/view/widget/header_backspace.dart';
import 'package:recipe_roots/view/widget/snackbar_error.dart';
import 'package:recipe_roots/view/window/recipe/widgets/cooking_steps_view.dart';
import 'package:recipe_roots/view/window/recipe/widgets/ingredients_view.dart';

Expand Down Expand Up @@ -73,7 +74,11 @@ class RecipeView extends StatelessWidget {
onPressed: () {
RecipeService()
.deleteRecipe(recipe)
.then((value) => goToRecipeViews());
.then((value) => goToRecipeViews())
.catchError((e) => {
ScaffoldMessenger.of(context).showSnackBar(
getErrorSnackbar(e.toString(), context))
});
},
child: Text("Delete",
style: Theme.of(context).textTheme.bodyMedium)),
Expand Down
21 changes: 17 additions & 4 deletions lib/view/window/recipe/widgets/submit_recipe_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,30 @@ import 'package:provider/provider.dart';
import 'package:recipe_roots/domain/entire_recipe.dart';
import 'package:recipe_roots/domain/entire_recipe_form.dart';
import 'package:recipe_roots/service/recipe_service.dart';
import 'package:recipe_roots/view/widget/snackbar_error.dart';

class SubmitRecipeFormButton extends StatelessWidget {
final Function goToRecipeViews;

const SubmitRecipeFormButton({super.key, required this.goToRecipeViews});

saveRecipe(EntireRecipe recipe) {
saveRecipe(EntireRecipe recipe, BuildContext context) {
if (recipe.recipe.id == null) {
RecipeService().addRecipe(recipe).then((value) => goToRecipeViews());
RecipeService()
.addRecipe(recipe)
.then((value) => goToRecipeViews())
.catchError((e) => {
ScaffoldMessenger.of(context)
.showSnackBar(getErrorSnackbar(e.toString(), context))
});
} else {
RecipeService().editRecipe(recipe).then((value) => goToRecipeViews());
RecipeService()
.editRecipe(recipe)
.then((value) => goToRecipeViews())
.catchError((e) => {
ScaffoldMessenger.of(context)
.showSnackBar(getErrorSnackbar(e.toString(), context))
});
}
}

Expand All @@ -22,7 +35,7 @@ class SubmitRecipeFormButton extends StatelessWidget {
return Consumer<EntireRecipeForm>(builder: ((context, recipeForm, child) {
return ElevatedButton(
onPressed: () {
saveRecipe(recipeForm.getRecipe());
saveRecipe(recipeForm.getRecipe(), context);
},
style: Theme.of(context).elevatedButtonTheme.style,
child: Padding(
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: recipe_roots
description: Pocket Sized Family Cook Book.
publish_to: 'none'
version: 1.0.4+5
version: 1.0.7+1

environment:
sdk: '>=2.19.6 <3.0.0'
Expand Down

0 comments on commit 6ed7dd8

Please sign in to comment.