mymuseum-visitapp/lib/Helpers/DatabaseHelper.dart

433 lines
15 KiB
Dart

import 'dart:convert';
import 'package:manager_api/api.dart';
import 'package:mymuseum_visitapp/Models/articleRead.dart';
import 'package:mymuseum_visitapp/Models/beaconSection.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,
articleRead,
beaconSection
}
class DatabaseHelper {
static const _databaseName = "visit_database.db";
static const _databaseVersion = 1;
static const mainTable = 'visitAppContext';
static const columnLanguage = 'language';
static const columnLabel = 'label';
static const columnId = 'id';
static const columnInstanceId = 'instanceId';
static const columnData = 'data';
static const columnType = 'type';
static const columnDateCreation = 'dateCreation';
static const columnIsMobile = 'isMobile';
static const columnIsTablet = 'isTablet';
static const columnIsOffline = 'isOffline';
static const configurationsTable = 'configurations';
static const columnLanguages = 'languages';
static const columnPrimaryColor = 'primaryColor';
static const columnSecondaryColor = 'secondaryColor';
static const sectionsTable = 'sections';
static const columnTitle = 'title';
static const columnDescription = 'description';
static const columnImageId = 'imageId';
static const columnImageSource = 'imageSource';
static const columnConfigurationId = 'configurationId';
static const columnIsSubSection = 'isSubSection';
static const columnParentId = 'parentId';
static const columnOrderOfElement = 'orderOfElement';
static const resourcesTable = 'resources';
static const columnSource = 'source';
static const articleReadTable = 'articleRead';
static const columnLastTimeOpen = 'readTime';
static const beaconSectionTable = 'beaconSection';
static const columnMinorBeaconId = 'minorBeaconId';
static const columnOrderInConfig = 'orderInConfig';
static const columnSectionId = 'sectionId';
static const columnSectionType = 'sectionType';
static const columnIsAdmin = 'isAdmin';
static const columnIsAllLanguages = 'isAllLanguages';
DatabaseHelper._privateConstructor();
static final DatabaseHelper instance = DatabaseHelper._privateConstructor();
static Database? _database;
Future<Database> get database async =>
_database ??= await _initDatabase();
Future<Database> _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 createTable(db, DatabaseTableType.main);
await createTable(db, DatabaseTableType.configurations);
await createTable(db, DatabaseTableType.sections);
await createTable(db, DatabaseTableType.resources);
await createTable(db, DatabaseTableType.articleRead);
await createTable(db, DatabaseTableType.beaconSection);
}
Future<int> insert(DatabaseTableType type, Map<String, Object?> 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);
// Test if table exist
var isExistResult = await isExist(type);
if(!isExistResult) {
print("TABLE DOESNT EXIST");
await createTable(db, type);
}
var test = await DatabaseHelper.instance.queryWithColumnId(type, info[columnId].toString());
if((type == DatabaseTableType.main && test.isNotEmpty) || (type != DatabaseTableType.main && test.isNotEmpty)) { //test!.where((t) => info[columnId] == t.id).isNotEmpty
if(type != DatabaseTableType.main) {
//print("UPDATE $type - length before ${test.length}");
print("UPDATE $type");
} 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}");
print("INSERT $type");
} else {
print("INSERT $type - main table");
}
var res = await db.insert(_getTableName(type), info);
return res;
}
}
Future<void> update(DatabaseTableType type, Map<String, Object?> 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<void> createTable(Database db, DatabaseTableType type) async {
print("CREATE TABLE $type");
switch(type) {
case DatabaseTableType.main :
db.execute('''
CREATE TABLE $mainTable (
$columnId TEXT NOT NULL PRIMARY KEY,
$columnLanguage TEXT NOT NULL,
$columnInstanceId TEXT NOT NULL,
$columnIsAdmin BOOLEAN NOT NULL CHECK ($columnIsAdmin IN (0,1)),
$columnIsAllLanguages BOOLEAN CHECK ($columnIsAllLanguages IN (0,1))
)
''');
break;
case DatabaseTableType.configurations :
db.execute('''
CREATE TABLE $configurationsTable (
$columnId TEXT NOT NULL PRIMARY KEY,
$columnInstanceId TEXT NOT NULL,
$columnLabel TEXT NOT NULL,
$columnTitle TEXT NOT NULL,
$columnImageId TEXT,
$columnImageSource TEXT,
$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))
)
''');
break;
case DatabaseTableType.sections :
db.execute('''
CREATE TABLE $sectionsTable (
$columnId TEXT NOT NULL PRIMARY KEY,
$columnInstanceId TEXT NOT NULL,
$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
)
''');
break;
case DatabaseTableType.resources:
db.execute('''
CREATE TABLE $resourcesTable (
$columnId TEXT NOT NULL PRIMARY KEY,
$columnData TEXT NOT NULL,
$columnSource TEXT NOT NULL,
$columnType INT NOT NULL
)
''');
break;
case DatabaseTableType.articleRead:
db.execute('''
CREATE TABLE $articleReadTable (
$columnId TEXT NOT NULL PRIMARY KEY,
$columnLastTimeOpen INT NOT NULL
)
''');
break;
case DatabaseTableType.beaconSection:
db.execute('''
CREATE TABLE $beaconSectionTable (
$columnId TEXT NOT NULL PRIMARY KEY,
$columnMinorBeaconId INT NOT NULL,
$columnOrderInConfig INT NOT NULL,
$columnConfigurationId TEXT NOT NULL,
$columnSectionId TEXT NOT NULL,
$columnSectionType INT NOT NULL
)
''');
break;
}
}
void updateTableMain(DatabaseTableType type, VisitAppContext visitAppContext) async {
try {
Database db = await instance.database;
var nameOfTable = _getTableName(type);
// CHECK IF EXIST
String checkQuery = "PRAGMA table_info($nameOfTable)";
var test = await db.rawQuery(checkQuery);
if(test.where((e) => e.toString().contains(columnIsAdmin)).isEmpty) {
print("update .. columnIsAdmin");
await db.rawQuery("ALTER TABLE $nameOfTable Add $columnIsAdmin BOOLEAN CHECK ($columnIsAdmin IN (0,1))");
} else {
print("IN columnIsAdmin");
}
if(test.where((e) => e.toString().contains(columnIsAllLanguages)).isEmpty) {
print("update .. columnIsAllLanguages");
await db.rawQuery("ALTER TABLE $nameOfTable Add $columnIsAllLanguages BOOLEAN CHECK ($columnIsAllLanguages IN (0,1))");
} else {
print("IN columnIsAllLanguages");
}
DatabaseHelper.instance.insert(DatabaseTableType.main, visitAppContext.toMap());
} catch (e) {
print("ERROR IN updateTableMain");
print(e);
}
}
Future<bool> isExist(DatabaseTableType type) async {
Database db = await instance.database;
var nameOfTable = _getTableName(type);
var test = await db.rawQuery("SELECT name FROM sqlite_master WHERE type='table' AND name='$nameOfTable'");
return test.isNotEmpty;
}
Future<List<Map<String, dynamic>>> queryAllRows(DatabaseTableType type) async {
Database db = await instance.database;
var res = await db.query(_getTableName(type), orderBy: "$columnId DESC");
return res;
}
Future<List<Map<String, dynamic>>> 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<List<SectionDTO>> queryWithConfigurationId(DatabaseTableType type, String id) async {
List<SectionDTO> 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<int> delete(String id, DatabaseTableType type) async {
Database db = await instance.database;
return await db.delete(_getTableName(type), where: '$columnId = ?', whereArgs: [id]);
}
Future<List<Map<String, Object?>>> clearTable(DatabaseTableType type) async {
Database db = await instance.database;
String tableName = _getTableName(type);
return await db.rawQuery("DELETE FROM $tableName");
}
Future<dynamic> getData(DatabaseTableType type) async {
dynamic dataToReturn;
if(type != DatabaseTableType.main)
{
dataToReturn = <dynamic>[];
}
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"],
instanceId: element["instanceId"],
language: element["language"],
isAdmin: element["isAdmin"] == 1 ? true : false,
isAllLanguages: element["isAllLanguages"] == 1 ? true : false,
);
break;
case DatabaseTableType.configurations:
dataToReturn.add(getConfigurationFromDB(element));
//print("DB - dataToReturn --- $test --> ");
break;
case DatabaseTableType.sections:
dataToReturn.add(getSectionFromDB(element));
//print("DB - dataToReturn --- $test --> ");
break;
case DatabaseTableType.resources:
dataToReturn.add(getResourceFromDB(element));
//print("DB - dataToReturn --- $test --> ");
break;
case DatabaseTableType.articleRead:
dataToReturn.add(getArticleReadFromDB(element));
//print("DB - dataToReturn --- $test --> ");
break;
case DatabaseTableType.beaconSection:
dataToReturn.add(getBeaconSectionFromDB(element));
//print("DB - dataToReturn --- $test --> ");
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;
case DatabaseTableType.articleRead:
return articleReadTable;
case DatabaseTableType.beaconSection:
return beaconSectionTable;
}
}
ConfigurationDTO getConfigurationFromDB(dynamic element) {
var titles = List<TranslationDTO>.from(json.decode(element['title']).map<dynamic>((q) => TranslationDTO.fromJson(q)).toList());
return ConfigurationDTO(
id: element["id"],
instanceId: element["instanceId"],
label: element["label"],
title: titles,
imageId: element["imageId"],
imageSource: element["imageSource"],
primaryColor: element["primaryColor"],
secondaryColor: element["secondaryColor"],
languages: List<String>.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<TranslationDTO>.from(json.decode(element['title']).map<dynamic>((q) => TranslationDTO.fromJson(q)).toList());
var descriptions = List<TranslationDTO>.from(json.decode(element['description']).map<dynamic>((q) => TranslationDTO.fromJson(q)).toList());
return SectionDTO(
id: element["id"],
instanceId: element["instanceId"],
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"],
source: element["source"],
type: ResourceType.values[element["type"]]
);
}
SectionRead getArticleReadFromDB(dynamic element) {
return SectionRead(
id: element["id"],
readTime: element["readTime"]
);
}
BeaconSection getBeaconSectionFromDB(dynamic element) {
return BeaconSection(
minorBeaconId: element["minorBeaconId"],
orderInConfig: element["orderInConfig"],
configurationId: element["configurationId"],
sectionId: element["sectionId"],
sectionType: SectionType.values[element["sectionType"]]
);
}
}