import 'dart:convert'; import 'package:manager_api/api.dart'; import 'package:mymuseum_visitapp/Models/resourceModel.dart'; import 'package:mymuseum_visitapp/Models/visitContext.dart'; import 'package:path/path.dart'; import 'package:sqflite/sqflite.dart'; enum DatabaseTableType { main, configurations, sections, resources } class DatabaseHelper { static final _databaseName = "visit_database.db"; static final _databaseVersion = 1; static final mainTable = 'visitAppContext'; static final columnLanguage = 'language'; static final columnLabel = 'label'; static final columnId = 'id'; static final columnData = 'data'; static final columnType = 'type'; static final columnDateCreation = 'dateCreation'; static final columnIsMobile = 'isMobile'; static final columnIsTablet = 'isTablet'; static final columnIsOffline = 'isOffline'; static final configurationsTable = 'configurations'; static final columnLanguages = 'languages'; static final columnPrimaryColor = 'primaryColor'; static final columnSecondaryColor = 'secondaryColor'; static final sectionsTable = 'sections'; static final columnTitle = 'title'; static final columnDescription = 'description'; static final columnImageId = 'imageId'; static final columnImageSource = 'imageSource'; static final columnConfigurationId = 'configurationId'; static final columnIsSubSection = 'isSubSection'; static final columnParentId = 'parentId'; static final columnOrderOfElement = 'orderOfElement'; static final resourcesTable = 'resources'; DatabaseHelper._privateConstructor(); static final DatabaseHelper instance = DatabaseHelper._privateConstructor(); static Database? _database; Future get database async => _database ??= await _initDatabase(); Future _initDatabase() async { String path = join(await getDatabasesPath(), _databaseName); return await openDatabase(path, version: _databaseVersion, onCreate: _onCreate); } // SQL code to create the database table Future _onCreate(Database db, int version) async { await db.execute(''' CREATE TABLE $mainTable ( $columnId TEXT NOT NULL PRIMARY KEY, $columnLanguage TEXT NOT NULL ) '''); await db.execute(''' CREATE TABLE $configurationsTable ( $columnId TEXT NOT NULL PRIMARY KEY, $columnLabel TEXT NOT NULL, $columnLanguages TEXT NOT NULL, $columnDateCreation TEXT NOT NULL, $columnPrimaryColor TEXT, $columnSecondaryColor TEXT, $columnIsMobile BOOLEAN NOT NULL CHECK ($columnIsMobile IN (0,1)), $columnIsTablet BOOLEAN NOT NULL CHECK ($columnIsTablet IN (0,1)), $columnIsOffline BOOLEAN NOT NULL CHECK ($columnIsOffline IN (0,1)) ) '''); await db.execute(''' CREATE TABLE $sectionsTable ( $columnId TEXT NOT NULL PRIMARY KEY, $columnLabel TEXT NOT NULL, $columnTitle TEXT NOT NULL, $columnDescription TEXT, $columnImageId TEXT, $columnImageSource TEXT, $columnConfigurationId TEXT NOT NULL, $columnIsSubSection BOOLEAN NOT NULL CHECK ($columnIsSubSection IN (0,1)), $columnParentId TEXT, $columnType INT NOT NULL, $columnData TEXT NOT NULL, $columnDateCreation TEXT NOT NULL, $columnOrderOfElement TEXT NOT NULL ) '''); await db.execute(''' CREATE TABLE $resourcesTable ( $columnId TEXT NOT NULL PRIMARY KEY, $columnData TEXT NOT NULL, $columnType INT NOT NULL ) '''); } Future insert(DatabaseTableType type, Map info) async { Database db = await instance.database; if(info.containsKey("languages")) { info.update("languages", (value) => jsonEncode(value)); //print("languages BEFORE"); //print(info["languages"]); } var test = await instance.getData(type); if((type == DatabaseTableType.main && test != null) || (type != DatabaseTableType.main && test!.where((t) => info[columnId] == t.id).isNotEmpty)) { if(type != DatabaseTableType.main) { print("UPDATE $type - length before ${test.length}"); } else { print("UPDATE $type - main table"); } var res = await db.update( _getTableName(type), info, where: "$columnId = ?", whereArgs: [info[columnId]], ); return res; } else { if(type != DatabaseTableType.main) { print("INSERT $type - length before ${test.length}"); } else { print("INSERT $type - main table"); } var res = await db.insert(_getTableName(type), info); return res; } } Future update(DatabaseTableType type, Map info, String id) async { // Get a reference to the database. final db = await instance.database; await db.update( _getTableName(type), info, where: "$columnId = ?", whereArgs: [id], ); } Future>> queryAllRows(DatabaseTableType type) async { Database db = await instance.database; var res = await db.query(_getTableName(type), orderBy: "$columnId DESC"); return res; } Future>> queryWithColumnId(DatabaseTableType type, String id) async { Database db = await instance.database; var res = await db.query(_getTableName(type), where: '$columnId = ?', whereArgs: [id]); return res; } Future> queryWithConfigurationId(DatabaseTableType type, String id) async { List sections = []; Database db = await instance.database; var res = await db.query(_getTableName(type), where: '$columnConfigurationId = ?', whereArgs: [id]); res.forEach((element) { sections.add(getSectionFromDB(element)); }); return sections; } Future delete(String id, DatabaseTableType type) async { Database db = await instance.database; return await db.delete(_getTableName(type), where: '$columnId = ?', whereArgs: [id]); } Future>> clearTable(DatabaseTableType type) async { Database db = await instance.database; String tableName = _getTableName(type); return await db.rawQuery("DELETE FROM $tableName"); } Future getData(DatabaseTableType type) async { dynamic dataToReturn; if(type != DatabaseTableType.main) { dataToReturn = []; } await DatabaseHelper.instance.queryAllRows(type).then((value) { print("DB - getData - CONTEXT --- $type --> "); value.forEach((element) { switch(type) { case DatabaseTableType.main: dataToReturn = VisitAppContext( id: element["id"], language: element["language"] ); break; case DatabaseTableType.configurations: dataToReturn.add(getConfigurationFromDB(element)); break; case DatabaseTableType.sections: dataToReturn.add(getSectionFromDB(element)); break; case DatabaseTableType.resources: dataToReturn.add(getResourceFromDB(element)); break; } }); }).catchError((error) { print(error); }); return dataToReturn; } String _getTableName(DatabaseTableType type) { switch(type) { case DatabaseTableType.main: return mainTable; case DatabaseTableType.configurations: return configurationsTable; case DatabaseTableType.sections: return sectionsTable; case DatabaseTableType.resources: return resourcesTable; } } ConfigurationDTO getConfigurationFromDB(dynamic element) { return ConfigurationDTO( id: element["id"], label: element["label"], primaryColor: element["primaryColor"], secondaryColor: element["secondaryColor"], languages: List.from(jsonDecode(element["languages"])), dateCreation: DateTime.tryParse(element["dateCreation"]), isMobile: element["isMobile"] == 1 ? true : false, isTablet: element["isTablet"] == 1 ? true : false, isOffline: element["isOffline"] == 1 ? true : false ); } SectionDTO getSectionFromDB(dynamic element) { var titles = List.from(json.decode(element['title']).map((q) => TranslationDTO.fromJson(q)).toList()); var descriptions = List.from(json.decode(element['description']).map((q) => TranslationDTO.fromJson(q)).toList()); return SectionDTO( id: element["id"], label: element["label"], title: titles, description: descriptions, imageId: element["imageId"], imageSource: element["imageSource"], configurationId: element["configurationId"], type: SectionType.values[element["type"]], data: element["data"], dateCreation: DateTime.tryParse(element["dateCreation"]), order: int.parse(element["orderOfElement"]), ); } ResourceModel getResourceFromDB(dynamic element) { return ResourceModel( id: element["id"], data: element["data"], type: ResourceType.values[element["type"]] ); } }