Init database, insert and get configuration working, section wip (insert ok but not get)

This commit is contained in:
Fransolet Thomas 2022-08-25 18:09:24 +02:00
parent 5ce0ec4f80
commit 357fa2f235
7 changed files with 362 additions and 44 deletions

View File

@ -1 +1 @@
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"qr_code_scanner","path":"C:\\\\Users\\\\thoma\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\qr_code_scanner-1.0.0\\\\","native_build":true,"dependencies":[]},{"name":"sqflite","path":"C:\\\\Users\\\\thoma\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-2.0.3+1\\\\","native_build":true,"dependencies":[]}],"android":[{"name":"qr_code_scanner","path":"C:\\\\Users\\\\thoma\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\qr_code_scanner-1.0.0\\\\","native_build":true,"dependencies":[]},{"name":"sqflite","path":"C:\\\\Users\\\\thoma\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-2.0.3+1\\\\","native_build":true,"dependencies":[]}],"macos":[{"name":"sqflite","path":"C:\\\\Users\\\\thoma\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-2.0.3+1\\\\","native_build":true,"dependencies":[]}],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"qr_code_scanner","dependencies":[]},{"name":"sqflite","dependencies":[]}],"date_created":"2022-08-18 17:59:37.167796","version":"3.0.3"} {"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"qr_code_scanner","path":"C:\\\\Users\\\\thoma\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\qr_code_scanner-1.0.0\\\\","native_build":true,"dependencies":[]},{"name":"sqflite","path":"C:\\\\Users\\\\thoma\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-2.0.3+1\\\\","native_build":true,"dependencies":[]}],"android":[{"name":"qr_code_scanner","path":"C:\\\\Users\\\\thoma\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\qr_code_scanner-1.0.0\\\\","native_build":true,"dependencies":[]},{"name":"sqflite","path":"C:\\\\Users\\\\thoma\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-2.0.3+1\\\\","native_build":true,"dependencies":[]}],"macos":[{"name":"sqflite","path":"C:\\\\Users\\\\thoma\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-2.0.3+1\\\\","native_build":true,"dependencies":[]}],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"qr_code_scanner","dependencies":[]},{"name":"sqflite","dependencies":[]}],"date_created":"2022-08-25 17:55:14.179888","version":"3.0.3"}

View File

@ -0,0 +1,240 @@
import 'dart:convert';
import 'package:manager_api/api.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<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 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,
$columnLabel TEXT NOT NULL,
$columnData TEXT NOT NULL,
$columnType INT NOT NULL
)
''');
}
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);
if((type == DatabaseTableType.main && test != null) || (type != DatabaseTableType.main && test!.where((t) => info[columnId] == t.id).isNotEmpty)) {
var res = await db.update(_getTableName(type), info);
return res;
} else {
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<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<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("value -----");
print(value);
value.forEach((element) {
print("DB - CONTEXT --- ");
switch(type) {
case DatabaseTableType.main:
dataToReturn = VisitAppContext(
id: element["id"],
language: element["language"]
);
break;
case DatabaseTableType.configurations:
dataToReturn.add(ConfigurationDTO(
id: element["id"],
label: element["label"],
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
));
break;
case DatabaseTableType.sections:
print("RESUUUUUUUULT");
print(element['title']);
print(json.decode(element['title']));
print(List<TranslationDTO>.from(element["title"]));
dataToReturn.add(SectionDTO(
id: element["id"],
label: element["label"],
title: element['title'].map<TranslationDTO>((q) => TranslationDTO.fromJson(q)).toList(),
description: json.decode(element['description']).map<TranslationDTO>((q) => TranslationDTO.fromJson(q)).toList(),
imageId: element["imageId"],
imageSource: element["imageSource"],
configurationId: element["configurationId"],
type: element["type"], // TODO
data: element["data"], // TODO
dateCreation: DateTime.tryParse(element["dateCreation"]),
order: element["orderOfElement"],
));
print("RESUUUUUUUULT");
break;
case DatabaseTableType.resources:
dataToReturn.add(ResourceDTO(
id: element["id"],
label: element["label"],
data: element["data"], // TODO
type: element["type"] // TODO
));
break;
}
});
}).catchError((error) {
print(error);
});
print(dataToReturn);
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;
}
}
}

View File

@ -1,34 +1,36 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:manager_api/api.dart';
class VisitAppContext with ChangeNotifier{ class VisitAppContext with ChangeNotifier{
String? userId = ""; String? id = "";
String? token = ""; //String? token = "";
String? host = ""; //String? host = "";
String? language = ""; String? language = "";
List<ConfigurationDTO>? configurations;
VisitAppContext({this.userId, this.token, this.host, this.language}); VisitAppContext({this.language, this.id});
Map<String, dynamic> toMap() { Map<String, dynamic> toMap() {
return { return {
'userId': userId, 'id': id,
'host': host, //'host': host,
'language': language, 'language': language,
'token': token //'token': token
}; };
} }
factory VisitAppContext.fromJson(Map<String, dynamic> json) { factory VisitAppContext.fromJson(Map<String, dynamic> json) {
return VisitAppContext( return VisitAppContext(
userId: json['userId'] as String, id: json['id'] as String,
host: json['host'] as String, /*host: json['host'] as String,*/
language: json['language'] as String, language: json['language'] as String,
token: json['token'] as String, //token: json['token'] as String,
); );
} }
// Implement toString to make it easier to see information about // Implement toString to make it easier to see information about
@override @override
String toString() { String toString() {
return 'VisitAppContext{userId: $userId, language: $language, host: $host}'; return 'VisitAppContext{id: $id, language: $language}';
} }
} }

View File

@ -1,4 +1,5 @@
import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:auto_size_text/auto_size_text.dart'; import 'package:auto_size_text/auto_size_text.dart';
@ -7,6 +8,7 @@ import 'package:manager_api/api.dart';
import 'package:mymuseum_visitapp/Components/CustomAppBar.dart'; import 'package:mymuseum_visitapp/Components/CustomAppBar.dart';
import 'package:mymuseum_visitapp/Components/Loading.dart'; import 'package:mymuseum_visitapp/Components/Loading.dart';
import 'package:mymuseum_visitapp/Components/ScannerBouton.dart'; import 'package:mymuseum_visitapp/Components/ScannerBouton.dart';
import 'package:mymuseum_visitapp/Helpers/DatabaseHelper.dart';
import 'package:mymuseum_visitapp/Helpers/networkCheck.dart'; import 'package:mymuseum_visitapp/Helpers/networkCheck.dart';
import 'package:mymuseum_visitapp/Screens/Visit/visit.dart'; import 'package:mymuseum_visitapp/Screens/Visit/visit.dart';
import 'package:mymuseum_visitapp/app_context.dart'; import 'package:mymuseum_visitapp/app_context.dart';
@ -39,7 +41,7 @@ class _HomePageState extends State<HomePage> {
width: size.width, width: size.width,
height: size.height, height: size.height,
child: FutureBuilder( child: FutureBuilder(
future: getConfiguration(appContext.clientAPI), future: getConfigurations(appContext.clientAPI),
builder: (context, AsyncSnapshot<dynamic> snapshot) { builder: (context, AsyncSnapshot<dynamic> snapshot) {
if (snapshot.connectionState == ConnectionState.done) { if (snapshot.connectionState == ConnectionState.done) {
configurations = List<ConfigurationDTO>.from(snapshot.data).where((configuration) => configuration.isMobile!).toList(); configurations = List<ConfigurationDTO>.from(snapshot.data).where((configuration) => configuration.isMobile!).toList();
@ -95,9 +97,9 @@ class _HomePageState extends State<HomePage> {
margin: const EdgeInsets.all(8), margin: const EdgeInsets.all(8),
child: InkWell( child: InkWell(
onTap: () async { onTap: () async {
print("TODO download"); downloadClicked(appContext, configurations[index]);
}, },
child: Icon(Icons.download_outlined, color: Colors.white), child: const Icon(Icons.download_outlined, color: Colors.white),
), ),
/*AutoSizeText( /*AutoSizeText(
configurations[index].isOffline.toString(), configurations[index].isOffline.toString(),
@ -133,22 +135,95 @@ class _HomePageState extends State<HomePage> {
); );
} }
Future<List<ConfigurationDTO>?> getConfiguration(Client client) async { Future<List<ConfigurationDTO>?> getConfigurations(Client client) async {
try { try {
List<ConfigurationDTO>? configurations;
bool isOnline = await hasNetwork(); bool isOnline = await hasNetwork();
if(isOnline) { if(isOnline) {
//var client = new Client("http://192.168.31.140:8089"); // TODO REMOVE //var client = new Client("http://192.168.31.140:8089"); // TODO REMOVE
List<ConfigurationDTO>? configurations = await client.configurationApi!.configurationGet(); configurations = await client.configurationApi!.configurationGet();
print(configurations);
return configurations; return configurations ?? [];
} else {
print("Search in local DB as we don't have internet connection");
configurations = List<ConfigurationDTO>.from(await DatabaseHelper.instance.getData(DatabaseTableType.configurations));
print("RESULT AAH");
return configurations ?? []; // TODO return local list..
}
} catch (e) {
print(e);
print("IN CATCH");
return [];
}
}
Future<List<SectionDTO>?> getAllSections(Client client, String configurationId) async {
try {
bool isOnline = await hasNetwork();
if(isOnline) {
List<SectionDTO>? sections = await client.sectionApi!.sectionGetFromConfiguration(configurationId);
print(sections);
return sections;
} else { } else {
return []; // TODO return local list.. return []; // TODO return local list..
} }
} catch (e) { } catch (e) {
print(e); print(e);
print("IN CATCH"); print("IN CATCH");
return [];
} }
} }
Future<void> downloadClicked(AppContext appContext, ConfigurationDTO configuration) async {
// Display config only downloaded - TODO
// Update local DB - Configuration
await DatabaseHelper.instance.insert(DatabaseTableType.configurations, configuration.toJson());
var teeest = await DatabaseHelper.instance.getData(DatabaseTableType.configurations);
print("RESULT new or update config");
print(teeest);
print("TODO download");
List<SectionDTO>? sections = await getAllSections(appContext.clientAPI, configuration.id!);
if(sections!.isNotEmpty) {
// Update local DB - Sections
for(var section in sections) {
print("Section to store == ");
print(section.toJson());
print(section.type == SectionType.Quizz);
var test = sectionToMap(section);
print("SECTION TOOOOO MAAAAAAAAAAAAAAAAAAAAP");
print(test);
await DatabaseHelper.instance.insert(DatabaseTableType.sections, sectionToMap(section));
}
}
}
Map<String, dynamic> sectionToMap(SectionDTO section) {
return {
'id': section.id,
'label': section.label,
'title': jsonEncode(section.title),
'description': jsonEncode(section.description),
'imageId': section.imageId,
'imageSource': section.imageSource,
'configurationId': section.configurationId,
'isSubSection': section.isSubSection,
'parentId': section.parentId,
'type': section.type!.toJson(),
'data': section.data,
'dateCreation': section.dateCreation!.toUtc().toIso8601String(),
'orderOfElement': section.order,
//'token': token
};
}
} }
boxDecoration(ConfigurationDTO configuration, bool isSelected) { // TODO to change boxDecoration(ConfigurationDTO configuration, bool isSelected) { // TODO to change

View File

@ -6,7 +6,7 @@ import 'Models/visitContext.dart';
class AppContext with ChangeNotifier { class AppContext with ChangeNotifier {
VisitAppContext _visitContext; VisitAppContext _visitContext;
Client clientAPI = Client("http://192.168.31.140:8089"); Client clientAPI = Client("http://192.168.31.140:8089"); // Replace by https://api.mymuseum.be
AppContext(this._visitContext); AppContext(this._visitContext);

View File

@ -3,6 +3,7 @@ import 'package:mymuseum_visitapp/Screens/Article/article.dart';
import 'package:mymuseum_visitapp/Screens/Home/home.dart'; import 'package:mymuseum_visitapp/Screens/Home/home.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'Helpers/DatabaseHelper.dart';
import 'Models/visitContext.dart'; import 'Models/visitContext.dart';
import 'Screens/Scanner/scanner_old.dart'; import 'Screens/Scanner/scanner_old.dart';
import 'app_context.dart'; import 'app_context.dart';
@ -11,14 +12,14 @@ import 'constants.dart';
void main() async { void main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
String initialRoute; String initialRoute;
VisitAppContext localContext = VisitAppContext(language: "FR", host: "http://192.168.31.140:8089"); VisitAppContext? localContext = await DatabaseHelper.instance.getData(DatabaseTableType.main);
//localContext = await DatabaseHelper.instance.getData();
if(localContext != null) { if(localContext != null) {
print("we've got an local db !"); print("we've got an local db !");
print(localContext); print(localContext);
} else { } else {
localContext = VisitAppContext(language: "FR", id: "UserId_Init");
DatabaseHelper.instance.insert(DatabaseTableType.main, localContext.toMap());
print("NO LOCAL DB !"); print("NO LOCAL DB !");
} }

View File

@ -23,23 +23,23 @@ class SectionType {
int toJson() => value; int toJson() => value;
static const number0 = SectionType._(0); static const Map = SectionType._(0);
static const number1 = SectionType._(1); static const Slider = SectionType._(1);
static const number2 = SectionType._(2); static const Video = SectionType._(2);
static const number3 = SectionType._(3); static const Web = SectionType._(3);
static const number4 = SectionType._(4); static const Menu = SectionType._(4);
static const number5 = SectionType._(5); static const Quizz = SectionType._(5);
static const number6 = SectionType._(6); static const Article = SectionType._(6);
/// List of all possible values in this [enum][SectionType]. /// List of all possible values in this [enum][SectionType].
static const values = <SectionType>[ static const values = <SectionType>[
number0, Map,
number1, Slider,
number2, Video,
number3, Web,
number4, Menu,
number5, Quizz,
number6, Article
]; ];
static SectionType? fromJson(dynamic value) => SectionTypeTypeTransformer().decode(value); static SectionType? fromJson(dynamic value) => SectionTypeTypeTransformer().decode(value);
@ -78,13 +78,13 @@ class SectionTypeTypeTransformer {
SectionType? decode(dynamic data, {bool allowNull = true}) { SectionType? decode(dynamic data, {bool allowNull = true}) {
if (data != null) { if (data != null) {
switch (data) { switch (data) {
case 0: return SectionType.number0; case 'Map': return SectionType.Map;
case 1: return SectionType.number1; case 'Slider': return SectionType.Slider;
case 2: return SectionType.number2; case 'Video': return SectionType.Video;
case 3: return SectionType.number3; case 'Web': return SectionType.Web;
case 4: return SectionType.number4; case 'Menu': return SectionType.Menu;
case 5: return SectionType.number5; case 'Quizz': return SectionType.Quizz;
case 6: return SectionType.number6; case 'Article': return SectionType.Article;
default: default:
if (!allowNull) { if (!allowNull) {
throw ArgumentError('Unknown enum value to decode: $data'); throw ArgumentError('Unknown enum value to decode: $data');