Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Added meals column to the RESTAURANTS table #1380

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,59 +1,45 @@
import 'package:intl/intl.dart';
import 'dart:async';
import 'dart:convert';
import 'package:sqflite/sqflite.dart';
import 'package:uni/controller/local_storage/database/app_database.dart';
import 'package:uni/model/entities/meal.dart';
import 'package:uni/model/entities/restaurant.dart';
import 'package:uni/model/utils/day_of_week.dart';

class RestaurantDatabase extends AppDatabase<List<Restaurant>> {
RestaurantDatabase()
: super(
'restaurant.db',
[
'''
[createScript],
onUpgrade: migrate,
version: 2,
);

static const createScript = '''
CREATE TABLE RESTAURANTS(
id INTEGER PRIMARY KEY,
ref TEXT,
name TEXT)
''',
'''
CREATE TABLE MEALS(
id INTEGER PRIMARY KEY AUTOINCREMENT,
day TEXT,
type TEXT,
date TEXT,
name TEXT,
id_restaurant INTEGER,
FOREIGN KEY (id_restaurant) REFERENCES RESTAURANTS(id))
'''
],
);
meals TEXT)
''';

/// Get all restaurants and meals, if day is null, all meals are returned
Future<List<Restaurant>> restaurants({DayOfWeek? day}) async {
final db = await getDatabase();
var restaurants = <Restaurant>[];
final restaurants = <Restaurant>[];

await db.transaction((txn) async {
final List<Map<String, dynamic>> restaurantMaps =
await db.query('restaurants');

restaurants = await Future.wait(
restaurantMaps.map((map) async {
final restaurantId = map['id'] as int;
final meals = await getRestaurantMeals(txn, restaurantId, day: day);

return Restaurant(
restaurantId,
map['name'] as String,
map['ref'] as String,
meals: meals,
);
}).toList(),
);
for (final map in restaurantMaps) {
final restaurant = Restaurant.fromJson(map);
if (day != null) {
restaurant.meals = {day: restaurant.getMealsOfDay(day)};
}
restaurants.add(restaurant);
}
});

return restaurants;
return filterPastMeals(restaurants);
}

Future<List<Restaurant>> getRestaurants() async {
Expand All @@ -63,61 +49,40 @@ class RestaurantDatabase extends AppDatabase<List<Restaurant>> {
final List<Map<String, dynamic>> restaurantsFromDB =
await txn.query('RESTAURANTS');
for (final restaurantMap in restaurantsFromDB) {
final id = restaurantMap['id'] as int;
final meals = await getRestaurantMeals(txn, id);
final restaurant = Restaurant.fromMap(restaurantMap, meals);
final restaurant = Restaurant.fromJson(restaurantMap);
restaurants.add(restaurant);
}
});

return filterPastMeals(restaurants);
}

Future<List<Meal>> getRestaurantMeals(
Transaction txn,
int restaurantId, {
DayOfWeek? day,
}) async {
final whereArgs = <dynamic>[restaurantId];
var whereQuery = 'id_restaurant = ? ';
if (day != null) {
whereQuery += ' and day = ?';
whereArgs.add(toString(day));
}

// Get restaurant meals
final List<Map<String, dynamic>> mealsMaps =
await txn.query('meals', where: whereQuery, whereArgs: whereArgs);

// Retrieve data from query
final meals = mealsMaps.map((map) {
final day = parseDayOfWeek(map['day'] as String);
final type = map['type'] as String;
final name = map['name'] as String;
final format = DateFormat('d-M-y');
final date = format.parseUtc(map['date'] as String);
return Meal(type, name, day!, date);
}).toList();

return meals;
}

/// Insert restaurant and meals in database
Future<void> insertRestaurant(Transaction txn, Restaurant restaurant) async {
final id = await txn.insert('RESTAURANTS', restaurant.toJson());
restaurant.meals.forEach((dayOfWeak, meals) async {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you see the sentry catch (ask permission to enter), the problem originates here because Restaurants table has different attributes than resturant.toJson(). Look at the Restaurant Model, you easily see the meals property, which is defined as @JsonKey.

This problem could be easily fixed if you just remove meals key from restaurant.toJson() returned object and insert the filtered restaurant to database. As you can see, there is another table called meals which will deal with the meals as a one-to-many relationship.

However, since you already started to add meals to restaurants table and we recently implement serialization, we can go further with your solution!

Delete dead code:

  • meals table
  • getRestaurantMeals method
  • Restaurant.fromMap(), whereRestaurant.fromJson() already done the job

Make all the adjustments you need to make it work!

Feel free to send me a message on Slack for help

for (final meal in meals) {
await txn.insert('MEALS', meal.toMap(id));
}
});
final mealsJson = jsonEncode(restaurant.meals);
final restaurantMap = restaurant.toJson();
thePeras marked this conversation as resolved.
Show resolved Hide resolved
restaurantMap['meals'] = mealsJson;


await txn.insert('RESTAURANTS', restaurantMap);
}

/// Deletes all restaurants and meals
Future<void> deleteAll(Transaction txn) async {
await txn.delete('meals');
await txn.delete('restaurants');
}

static FutureOr<void> migrate(
Database db,
int oldVersion,
int newVersion,
) async {
final batch = db.batch()
..execute('DROP TABLE IF EXISTS RESTAURANTS')
..execute(createScript);
await batch.commit();
}

@override
Future<void> saveToDatabase(List<Restaurant> data) async {
final db = await getDatabase();
Expand Down
7 changes: 1 addition & 6 deletions packages/uni_app/lib/model/entities/restaurant.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,6 @@ class Restaurant {
Restaurant(this.id, this.name, this.reference, {required List<Meal> meals})
: meals = groupBy(meals, (meal) => meal.dayOfWeek);

factory Restaurant.fromMap(Map<String, dynamic> map, List<Meal> meals) {
final object = Restaurant.fromJson(map);
object.meals = object.groupMealsByDayOfWeek(meals);
return object;
}

factory Restaurant.fromJson(Map<String, dynamic> json) =>
_$RestaurantFromJson(json);
Expand All @@ -24,7 +19,7 @@ class Restaurant {
final String name;
@JsonKey(name: 'ref')
final String reference; // Used only in html parser
@JsonKey(includeToJson: true)
@JsonKey(name: 'meals', includeToJson: true)
late final Map<DayOfWeek, List<Meal>> meals;

bool get isNotEmpty {
Expand Down
Loading