init
This commit is contained in:
72
filcnaplo/lib/database/init.dart
Normal file
72
filcnaplo/lib/database/init.dart
Normal file
@@ -0,0 +1,72 @@
|
||||
import 'package:filcnaplo/database/struct.dart';
|
||||
import 'package:filcnaplo/models/settings.dart';
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
|
||||
Future<Database> initDB() async {
|
||||
// await deleteDatabase('app.db'); // for debugging
|
||||
var db = await openDatabase('app.db');
|
||||
|
||||
var settingsDB = await createSettingsTable(db);
|
||||
|
||||
// Create table Users
|
||||
await db.execute("CREATE TABLE IF NOT EXISTS users (id TEXT NOT NULL, name TEXT, username TEXT, password TEXT, institute_code TEXT, student TEXT)");
|
||||
await db.execute("CREATE TABLE IF NOT EXISTS user_data ("
|
||||
"id TEXT NOT NULL, grades TEXT, timetable TEXT, exams TEXT, homework TEXT, messages TEXT, notes TEXT, events TEXT, absences TEXT)");
|
||||
|
||||
if ((await db.rawQuery("SELECT COUNT(*) FROM settings"))[0].values.first == 0) {
|
||||
// Set default values for table Settings
|
||||
await db.insert("settings", SettingsProvider.defaultSettings().toMap());
|
||||
}
|
||||
|
||||
await migrateDB(db, settingsDB.struct.keys);
|
||||
|
||||
return db;
|
||||
}
|
||||
|
||||
Future<DatabaseStruct> createSettingsTable(Database db) async {
|
||||
var settingsDB = DatabaseStruct({
|
||||
"language": String, "start_page": int, "rounding": int, "theme": int, "accent_color": int, "news": int, "news_state": int, "developer_mode": int,
|
||||
"update_channel": int, "config": String, // general
|
||||
"grade_color1": int, "grade_color2": int, "grade_color3": int, "grade_color4": int, "grade_color5": int, // grade colors
|
||||
"vibrate": int, "vibration_strength": int, "ab_weeks": int, "swap_ab_weeks": int,
|
||||
"notifications": int, "notifications_bitfield": int, "notification_poll_interval": int, // notifications
|
||||
});
|
||||
|
||||
// Create table Settings
|
||||
await db.execute("CREATE TABLE IF NOT EXISTS settings ($settingsDB)");
|
||||
|
||||
return settingsDB;
|
||||
}
|
||||
|
||||
Future<void> migrateDB(Database db, Iterable<String> keys) async {
|
||||
var settings = (await db.query("settings"))[0];
|
||||
|
||||
bool migrationRequired = keys.any((key) => !settings.containsKey(key) || settings[key] == null);
|
||||
|
||||
if (migrationRequired) {
|
||||
var defaultSettings = SettingsProvider.defaultSettings();
|
||||
var settingsCopy = Map<String, dynamic>.from(settings);
|
||||
|
||||
// Delete settings
|
||||
await db.execute("drop table settings");
|
||||
|
||||
// Fill missing columns
|
||||
keys.forEach((key) {
|
||||
if (!keys.contains(key)) {
|
||||
print("debug: dropping $key");
|
||||
settingsCopy.remove(key);
|
||||
}
|
||||
|
||||
if (!settings.containsKey(key) || settings[key] == null) {
|
||||
print("DEBUG: migrating $key");
|
||||
settingsCopy[key] = defaultSettings.toMap()[key];
|
||||
}
|
||||
});
|
||||
|
||||
// Recreate settings
|
||||
await createSettingsTable(db);
|
||||
await db.insert("settings", settingsCopy);
|
||||
|
||||
print("INFO: Database migrated");
|
||||
}
|
||||
}
|
||||
114
filcnaplo/lib/database/query.dart
Normal file
114
filcnaplo/lib/database/query.dart
Normal file
@@ -0,0 +1,114 @@
|
||||
import 'dart:convert';
|
||||
import 'package:filcnaplo/models/user.dart';
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
|
||||
// Models
|
||||
import 'package:filcnaplo/models/settings.dart';
|
||||
import 'package:filcnaplo/api/providers/user_provider.dart';
|
||||
import 'package:filcnaplo_kreta_api/models/grade.dart';
|
||||
import 'package:filcnaplo_kreta_api/models/lesson.dart';
|
||||
import 'package:filcnaplo_kreta_api/models/exam.dart';
|
||||
import 'package:filcnaplo_kreta_api/models/homework.dart';
|
||||
import 'package:filcnaplo_kreta_api/models/message.dart';
|
||||
import 'package:filcnaplo_kreta_api/models/note.dart';
|
||||
import 'package:filcnaplo_kreta_api/models/event.dart';
|
||||
import 'package:filcnaplo_kreta_api/models/absence.dart';
|
||||
|
||||
class DatabaseQuery {
|
||||
DatabaseQuery({required this.db});
|
||||
|
||||
final Database db;
|
||||
|
||||
Future<SettingsProvider> getSettings() async {
|
||||
Map settingsMap = (await db.query("settings")).elementAt(0);
|
||||
SettingsProvider settings = SettingsProvider.fromMap(settingsMap);
|
||||
return settings;
|
||||
}
|
||||
|
||||
Future<UserProvider> getUsers() async {
|
||||
var userProvider = UserProvider();
|
||||
List<Map> usersMap = await db.query("users");
|
||||
usersMap.forEach((user) {
|
||||
userProvider.addUser(User.fromMap(user));
|
||||
});
|
||||
return userProvider;
|
||||
}
|
||||
}
|
||||
|
||||
class UserDatabaseQuery {
|
||||
UserDatabaseQuery({required this.db});
|
||||
|
||||
final Database db;
|
||||
|
||||
Future<List<Grade>> getGrades({required String userId}) async {
|
||||
List<Map> userData = await db.query("user_data", where: "id = ?", whereArgs: [userId]);
|
||||
if (userData.length == 0) return [];
|
||||
String? gradesJson = userData.elementAt(0)["grades"] as String?;
|
||||
if (gradesJson == null) return [];
|
||||
List<Grade> grades = (jsonDecode(gradesJson) as List).map((e) => Grade.fromJson(e)).toList();
|
||||
return grades;
|
||||
}
|
||||
|
||||
Future<List<Lesson>> getLessons({required String userId}) async {
|
||||
List<Map> userData = await db.query("user_data", where: "id = ?", whereArgs: [userId]);
|
||||
if (userData.length == 0) return [];
|
||||
String? lessonsJson = userData.elementAt(0)["timetable"] as String?;
|
||||
if (lessonsJson == null) return [];
|
||||
List<Lesson> lessons = (jsonDecode(lessonsJson) as List).map((e) => Lesson.fromJson(e)).toList();
|
||||
return lessons;
|
||||
}
|
||||
|
||||
Future<List<Exam>> getExams({required String userId}) async {
|
||||
List<Map> userData = await db.query("user_data", where: "id = ?", whereArgs: [userId]);
|
||||
if (userData.length == 0) return [];
|
||||
String? examsJson = userData.elementAt(0)["exams"] as String?;
|
||||
if (examsJson == null) return [];
|
||||
List<Exam> exams = (jsonDecode(examsJson) as List).map((e) => Exam.fromJson(e)).toList();
|
||||
return exams;
|
||||
}
|
||||
|
||||
Future<List<Homework>> getHomework({required String userId}) async {
|
||||
List<Map> userData = await db.query("user_data", where: "id = ?", whereArgs: [userId]);
|
||||
if (userData.length == 0) return [];
|
||||
String? homeworkJson = userData.elementAt(0)["homework"] as String?;
|
||||
if (homeworkJson == null) return [];
|
||||
List<Homework> homework = (jsonDecode(homeworkJson) as List).map((e) => Homework.fromJson(e)).toList();
|
||||
return homework;
|
||||
}
|
||||
|
||||
Future<List<Message>> getMessages({required String userId}) async {
|
||||
List<Map> userData = await db.query("user_data", where: "id = ?", whereArgs: [userId]);
|
||||
if (userData.length == 0) return [];
|
||||
String? messagesJson = userData.elementAt(0)["messages"] as String?;
|
||||
if (messagesJson == null) return [];
|
||||
List<Message> messages = (jsonDecode(messagesJson) as List).map((e) => Message.fromJson(e)).toList();
|
||||
return messages;
|
||||
}
|
||||
|
||||
Future<List<Note>> getNotes({required String userId}) async {
|
||||
List<Map> userData = await db.query("user_data", where: "id = ?", whereArgs: [userId]);
|
||||
if (userData.length == 0) return [];
|
||||
String? notesJson = userData.elementAt(0)["notes"] as String?;
|
||||
if (notesJson == null) return [];
|
||||
List<Note> notes = (jsonDecode(notesJson) as List).map((e) => Note.fromJson(e)).toList();
|
||||
return notes;
|
||||
}
|
||||
|
||||
Future<List<Event>> getEvents({required String userId}) async {
|
||||
List<Map> userData = await db.query("user_data", where: "id = ?", whereArgs: [userId]);
|
||||
if (userData.length == 0) return [];
|
||||
String? eventsJson = userData.elementAt(0)["events"] as String?;
|
||||
if (eventsJson == null) return [];
|
||||
List<Event> events = (jsonDecode(eventsJson) as List).map((e) => Event.fromJson(e)).toList();
|
||||
return events;
|
||||
}
|
||||
|
||||
Future<List<Absence>> getAbsences({required String userId}) async {
|
||||
List<Map> userData = await db.query("user_data", where: "id = ?", whereArgs: [userId]);
|
||||
if (userData.length == 0) return [];
|
||||
String? absebcesJson = userData.elementAt(0)["absences"] as String?;
|
||||
if (absebcesJson == null) return [];
|
||||
List<Absence> absebces = (jsonDecode(absebcesJson) as List).map((e) => Absence.fromJson(e)).toList();
|
||||
return absebces;
|
||||
}
|
||||
}
|
||||
85
filcnaplo/lib/database/store.dart
Normal file
85
filcnaplo/lib/database/store.dart
Normal file
@@ -0,0 +1,85 @@
|
||||
import 'dart:convert';
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
|
||||
// Models
|
||||
import 'package:filcnaplo/models/settings.dart';
|
||||
import 'package:filcnaplo/models/user.dart';
|
||||
import 'package:filcnaplo_kreta_api/models/grade.dart';
|
||||
import 'package:filcnaplo_kreta_api/models/lesson.dart';
|
||||
import 'package:filcnaplo_kreta_api/models/exam.dart';
|
||||
import 'package:filcnaplo_kreta_api/models/homework.dart';
|
||||
import 'package:filcnaplo_kreta_api/models/message.dart';
|
||||
import 'package:filcnaplo_kreta_api/models/note.dart';
|
||||
import 'package:filcnaplo_kreta_api/models/event.dart';
|
||||
import 'package:filcnaplo_kreta_api/models/absence.dart';
|
||||
|
||||
class DatabaseStore {
|
||||
DatabaseStore({required this.db});
|
||||
|
||||
final Database db;
|
||||
|
||||
Future<void> storeSettings(SettingsProvider settings) async {
|
||||
await db.update("settings", settings.toMap());
|
||||
}
|
||||
|
||||
Future<void> storeUser(User user) async {
|
||||
List userRes = await db.query("users", where: "id = ?", whereArgs: [user.id]);
|
||||
if (userRes.length > 0) {
|
||||
await db.update("users", user.toMap(), where: "id = ?", whereArgs: [user.id]);
|
||||
} else {
|
||||
await db.insert("users", user.toMap());
|
||||
await db.insert("user_data", {"id": user.id});
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> removeUser(String userId) async {
|
||||
await db.delete("users", where: "id = ?", whereArgs: [userId]);
|
||||
await db.delete("user_data", where: "id = ?", whereArgs: [userId]);
|
||||
}
|
||||
}
|
||||
|
||||
class UserDatabaseStore {
|
||||
UserDatabaseStore({required this.db});
|
||||
|
||||
final Database db;
|
||||
|
||||
Future storeGrades(List<Grade> grades, {required String userId}) async {
|
||||
String gradesJson = jsonEncode(grades.map((e) => e.json).toList());
|
||||
await db.update("user_data", {"grades": gradesJson}, where: "id = ?", whereArgs: [userId]);
|
||||
}
|
||||
|
||||
Future storeLessons(List<Lesson> lessons, {required String userId}) async {
|
||||
String lessonsJson = jsonEncode(lessons.map((e) => e.json).toList());
|
||||
await db.update("user_data", {"timetable": lessonsJson}, where: "id = ?", whereArgs: [userId]);
|
||||
}
|
||||
|
||||
Future storeExams(List<Exam> exams, {required String userId}) async {
|
||||
String examsJson = jsonEncode(exams.map((e) => e.json).toList());
|
||||
await db.update("user_data", {"exams": examsJson}, where: "id = ?", whereArgs: [userId]);
|
||||
}
|
||||
|
||||
Future storeHomework(List<Homework> homework, {required String userId}) async {
|
||||
String homeworkJson = jsonEncode(homework.map((e) => e.json).toList());
|
||||
await db.update("user_data", {"homework": homeworkJson}, where: "id = ?", whereArgs: [userId]);
|
||||
}
|
||||
|
||||
Future storeMessages(List<Message> messages, {required String userId}) async {
|
||||
String messagesJson = jsonEncode(messages.map((e) => e.json).toList());
|
||||
await db.update("user_data", {"messages": messagesJson}, where: "id = ?", whereArgs: [userId]);
|
||||
}
|
||||
|
||||
Future storeNotes(List<Note> notes, {required String userId}) async {
|
||||
String notesJson = jsonEncode(notes.map((e) => e.json).toList());
|
||||
await db.update("user_data", {"notes": notesJson}, where: "id = ?", whereArgs: [userId]);
|
||||
}
|
||||
|
||||
Future storeEvents(List<Event> events, {required String userId}) async {
|
||||
String eventsJson = jsonEncode(events.map((e) => e.json).toList());
|
||||
await db.update("user_data", {"events": eventsJson}, where: "id = ?", whereArgs: [userId]);
|
||||
}
|
||||
|
||||
Future storeAbsences(List<Absence> absences, {required String userId}) async {
|
||||
String absencesJson = jsonEncode(absences.map((e) => e.json).toList());
|
||||
await db.update("user_data", {"absences": absencesJson}, where: "id = ?", whereArgs: [userId]);
|
||||
}
|
||||
}
|
||||
29
filcnaplo/lib/database/struct.dart
Normal file
29
filcnaplo/lib/database/struct.dart
Normal file
@@ -0,0 +1,29 @@
|
||||
class DatabaseStruct {
|
||||
final Map<String, dynamic> struct;
|
||||
|
||||
DatabaseStruct(this.struct);
|
||||
|
||||
String _toDBfield(String name, dynamic type) {
|
||||
String typeName = "";
|
||||
|
||||
switch (type.runtimeType) {
|
||||
case int:
|
||||
typeName = "integer";
|
||||
break;
|
||||
case String:
|
||||
typeName = "text";
|
||||
break;
|
||||
}
|
||||
|
||||
return "${name} ${typeName.toUpperCase()}";
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
List<String> columns = [];
|
||||
struct.forEach((key, value) {
|
||||
columns.add(_toDBfield(key, value));
|
||||
});
|
||||
return columns.join(",");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user