From 2d826d5248b8ebfd60a9ecbc78b2361c3d7b815b Mon Sep 17 00:00:00 2001 From: Yan Maniez Date: Sun, 22 Mar 2020 20:36:08 +0100 Subject: [PATCH] =?UTF-8?q?D=C3=A9but=20ajout=20sembast?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../player_character_bloc.dart | 13 +- aidedejeu_flutter/lib/database.dart | 143 ---------------- aidedejeu_flutter/lib/databases/database.dart | 18 ++ .../lib/databases/database_sembast.dart | 75 ++++++++ .../lib/databases/database_sqflite.dart | 160 ++++++++++++++++++ aidedejeu_flutter/lib/widgets/library.dart | 13 +- aidedejeu_flutter/pubspec.lock | 38 ++++- aidedejeu_flutter/pubspec.yaml | 4 +- 8 files changed, 305 insertions(+), 159 deletions(-) delete mode 100644 aidedejeu_flutter/lib/database.dart create mode 100644 aidedejeu_flutter/lib/databases/database.dart create mode 100644 aidedejeu_flutter/lib/databases/database_sembast.dart create mode 100644 aidedejeu_flutter/lib/databases/database_sqflite.dart diff --git a/aidedejeu_flutter/lib/blocs/player_character/player_character_bloc.dart b/aidedejeu_flutter/lib/blocs/player_character/player_character_bloc.dart index dc39c0d6..0bdeb793 100644 --- a/aidedejeu_flutter/lib/blocs/player_character/player_character_bloc.dart +++ b/aidedejeu_flutter/lib/blocs/player_character/player_character_bloc.dart @@ -1,11 +1,14 @@ import 'package:aidedejeu_flutter/blocs/player_character/player_character_event.dart'; import 'package:aidedejeu_flutter/blocs/player_character/player_character_state.dart'; -import 'package:aidedejeu_flutter/database.dart'; +import 'package:aidedejeu_flutter/databases/database.dart'; +import 'package:aidedejeu_flutter/databases/database_sqflite.dart'; import 'package:bloc/bloc.dart'; class PlayerCharacterBloc extends Bloc { + BaseDB _db = SqfliteDB.instance; + @override PlayerCharacterState get initialState => PlayerCharacterState(); @@ -27,7 +30,7 @@ class PlayerCharacterBloc } Stream _mapRaceEventToState( RaceEvent event) async* { - var subRaces = await loadSubRaces(event.item); + var subRaces = await _db.loadSubRaces(event.item); yield state.copyWithClean(race: event.item, subRaces: subRaces); } @@ -37,7 +40,7 @@ class PlayerCharacterBloc } Stream _mapBackgroundEventToState( BackgroundEvent event) async* { - var subBackgrounds = await loadSubBackgrounds(event.item); + var subBackgrounds = await _db.loadSubBackgrounds(event.item); yield state.copyWithClean(background: event.item,subBackgrounds: subBackgrounds); } Stream _mapSubBackgroundEventToState( @@ -46,8 +49,8 @@ class PlayerCharacterBloc } Stream _mapLoadEventToState( LoadEvent event) async* { - var races = await loadRaces(); - var backgrounds = await loadBackgrounds(); + var races = await _db.loadRaces(); + var backgrounds = await _db.loadBackgrounds(); yield state.copyWith(races: races, backgrounds: backgrounds); // state; } } diff --git a/aidedejeu_flutter/lib/database.dart b/aidedejeu_flutter/lib/database.dart deleted file mode 100644 index 615459a3..00000000 --- a/aidedejeu_flutter/lib/database.dart +++ /dev/null @@ -1,143 +0,0 @@ -import 'dart:io'; - -import 'package:aidedejeu_flutter/models/items.dart'; -import 'package:flutter/services.dart'; -import 'package:path/path.dart'; -import 'package:sqflite/sqflite.dart'; - -import 'models/filters.dart'; - -Database _database; - -Future get database async { - if (_database != null) return _database; - _database = await getDatabaseInstance(); - return _database; -} - -Future getDatabaseInstance() async { - var databasesPath = await getDatabasesPath(); - var path = join(databasesPath, "library.db"); - - var exists = await databaseExists(path); - exists = false; - if (!exists) { - print("Creating new copy from asset"); - - try { - await Directory(dirname(path)).create(recursive: true); - } catch (_) {} - - ByteData data = await rootBundle.load(join("assets", "library.db")); - List bytes = - data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes); - - await File(path).writeAsBytes(bytes, flush: true); - } else { - print("Opening existing database"); - } - - return await openDatabase(path, readOnly: true); -} - -Future getItemWithId(String id) async { - print("getItemWithId " + id); - final db = await database; - var response = await db.query( - "Items", - where: "Id = ? OR RootId = ?", - whereArgs: [id, id] - ); - if (response.isEmpty) { - print("Id not found"); - } - return response.isNotEmpty ? itemFromMap(response.first) : null; -} - -Future loadChildrenItems(Item item, List filters) async { - print("getChildrenItems " + (item?.itemType ?? "")); - if (item.itemType.endsWith("Items")) { - String itemType = - item.itemType.substring(0, item.itemType.length - 1); - String family = ""; - if (item is FilteredItems) { - family = item.family ?? ""; - } - String whereFilter = ""; - if(filters != null) { - filters.forEach((filter) { - if(filter.selectedValues.isNotEmpty) { - whereFilter = " AND (${filter.name} LIKE '%" + filter.selectedValues.join("%' OR ${filter.name} LIKE '%") + "%')"; - } - if(filter.rangeValues != null && (filter.rangeValues.start > 0 || filter.rangeValues.end < filter.values.length - 1) ) { - whereFilter = " AND ([${filter.name}] BETWEEN '${filter.values[filter.rangeValues.start.round()]}' AND '${filter.values[filter.rangeValues.end.round()]}')"; - } - }); - } - print(whereFilter); - final db = await database; - var response = await db.query( - "Items", - where: "ItemType = ? AND Family = ?" + whereFilter, - whereArgs: [itemType, family], - orderBy: "NormalizedName" - ); - if (response.isEmpty) { - print("Children not found"); - } - item.children = response.isNotEmpty - ? itemsFromMapList(response) - : null; - } - return item; -} - -Future> loadRaces() async { - final db = await database; - var response = await db.query( - "Items", - where: "ItemType = 'RaceItem'", - orderBy: "NormalizedName" - ); - if (response.isNotEmpty) { - return itemsFromMapList(response); - } - return null; -} - -Future> loadSubRaces(RaceItem race) async { - final db = await database; - var response = await db.query( - "Items", - where: "ItemType = 'SubRaceItem' AND ParentLink = ?", - whereArgs: [race.id], - orderBy: "NormalizedName" - ); - if (response.isNotEmpty) { - return itemsFromMapList(response); - } - return null; -} - -Future> loadTypedItems({String itemType, Item item}) async { - final db = await database; - var response = await db.query( - "Items", - where: "ItemType = ?" + (item != null ? " AND ParentLink = ?" : ""), - whereArgs: item != null ? [itemType, item.id] : [itemType], - orderBy: "NormalizedName" - ); - if (response.isNotEmpty) { - return itemsFromMapList(response); - } - return null; -} - -Future> loadBackgrounds() async { - return loadTypedItems(itemType: "BackgroundItem"); -} - -Future> loadSubBackgrounds(Item item) async { - return loadTypedItems(itemType: "SubBackgroundItem", item: item); -} - diff --git a/aidedejeu_flutter/lib/databases/database.dart b/aidedejeu_flutter/lib/databases/database.dart new file mode 100644 index 00000000..fd0a4b91 --- /dev/null +++ b/aidedejeu_flutter/lib/databases/database.dart @@ -0,0 +1,18 @@ +import 'package:aidedejeu_flutter/models/filters.dart'; +import 'package:aidedejeu_flutter/models/items.dart'; + +abstract class BaseDB { + Future getItemWithId(String id); + + Future loadChildrenItems(Item item, List filters); + + Future> loadRaces(); + + Future> loadSubRaces(RaceItem race); + + Future> loadTypedItems({String itemType, Item item}); + + Future> loadBackgrounds(); + + Future> loadSubBackgrounds(Item item); +} diff --git a/aidedejeu_flutter/lib/databases/database_sembast.dart b/aidedejeu_flutter/lib/databases/database_sembast.dart new file mode 100644 index 00000000..6d4eda82 --- /dev/null +++ b/aidedejeu_flutter/lib/databases/database_sembast.dart @@ -0,0 +1,75 @@ +import 'package:aidedejeu_flutter/databases/database.dart'; +import 'package:aidedejeu_flutter/models/filters.dart' as Filters; +import 'package:aidedejeu_flutter/models/items.dart'; +import 'package:sembast/sembast.dart'; +import 'package:sembast/sembast_io.dart'; +import 'package:sembast_web/sembast_web.dart'; + +class SembastDB extends BaseDB { + static SembastDB _instance; + static SembastDB get instance { + if(_instance == null) { + _instance = SembastDB(); + } + return _instance; + } + + Database _database; + + Future get database async { + if (_database != null) return _database; + _database = await getDatabaseInstance(); + return _database; + } + + Future getDatabaseInstance() async { + // File path to a file in the current directory + String dbPath = 'library_sembast.db'; + DatabaseFactory dbFactory = databaseFactoryIo; + +// We use the database factory to open the database + return await dbFactory.openDatabase(dbPath); + } + + @override + Future getItemWithId(String id) { + // TODO: implement getItemWithId + throw UnimplementedError(); + } + + @override + Future> loadBackgrounds() { + // TODO: implement loadBackgrounds + throw UnimplementedError(); + } + + @override + Future loadChildrenItems(Item item, List filters) { + // TODO: implement loadChildrenItems + throw UnimplementedError(); + } + + @override + Future> loadRaces() { + // TODO: implement loadRaces + throw UnimplementedError(); + } + + @override + Future> loadSubBackgrounds(Item item) { + // TODO: implement loadSubBackgrounds + throw UnimplementedError(); + } + + @override + Future> loadSubRaces(RaceItem race) { + // TODO: implement loadSubRaces + throw UnimplementedError(); + } + + @override + Future> loadTypedItems({String itemType, Item item}) { + // TODO: implement loadTypedItems + throw UnimplementedError(); + } +} diff --git a/aidedejeu_flutter/lib/databases/database_sqflite.dart b/aidedejeu_flutter/lib/databases/database_sqflite.dart new file mode 100644 index 00000000..d8278f1b --- /dev/null +++ b/aidedejeu_flutter/lib/databases/database_sqflite.dart @@ -0,0 +1,160 @@ +import 'dart:io'; + +import 'package:aidedejeu_flutter/databases/database.dart'; +import 'package:aidedejeu_flutter/models/filters.dart' as Filters; +import 'package:aidedejeu_flutter/models/items.dart'; +import 'package:flutter/services.dart'; +import 'package:path/path.dart'; +import 'package:sqflite/sqflite.dart'; + +class SqfliteDB extends BaseDB { + static SqfliteDB _instance; + static SqfliteDB get instance { + if(_instance == null) { + _instance = SqfliteDB(); + } + return _instance; + } + Database _database; + + Future get database async { + if (_database != null) return _database; + _database = await getDatabaseInstance(); + return _database; + } + + Future getDatabaseInstance() async { + var databasesPath = await getDatabasesPath(); + var path = join(databasesPath, "library.db"); + + var exists = await databaseExists(path); + exists = false; + if (!exists) { + print("Creating new copy from asset"); + + try { + await Directory(dirname(path)).create(recursive: true); + } catch (_) {} + + ByteData data = await rootBundle.load(join("assets", "library.db")); + List bytes = + data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes); + + await File(path).writeAsBytes(bytes, flush: true); + } else { + print("Opening existing database"); + } + + return await openDatabase(path, readOnly: true); + } + + Future getItemWithId(String id) async { + print("getItemWithId " + id); + final db = await database; + var response = await db.query( + "Items", + where: "Id = ? OR RootId = ?", + whereArgs: [id, id] + ); + if (response.isEmpty) { + print("Id not found"); + } + return response.isNotEmpty ? itemFromMap(response.first) : null; + } + + Future loadChildrenItems(Item item, List filters) async { + print("getChildrenItems " + (item?.itemType ?? "")); + if (item.itemType.endsWith("Items")) { + String itemType = + item.itemType.substring(0, item.itemType.length - 1); + String family = ""; + if (item is FilteredItems) { + family = item.family ?? ""; + } + String whereFilter = ""; + if (filters != null) { + filters.forEach((filter) { + if (filter.selectedValues.isNotEmpty) { + whereFilter = " AND (${filter.name} LIKE '%" + + filter.selectedValues.join("%' OR ${filter.name} LIKE '%") + + "%')"; + } + if (filter.rangeValues != null && (filter.rangeValues.start > 0 || + filter.rangeValues.end < filter.values.length - 1)) { + whereFilter = + " AND ([${filter.name}] BETWEEN '${filter.values[filter.rangeValues + .start.round()]}' AND '${filter.values[filter.rangeValues.end + .round()]}')"; + } + }); + } + print(whereFilter); + final db = await database; + var response = await db.query( + "Items", + where: "ItemType = ? AND Family = ?" + whereFilter, + whereArgs: [itemType, family], + orderBy: "NormalizedName" + ); + if (response.isEmpty) { + print("Children not found"); + } + item.children = response.isNotEmpty + ? itemsFromMapList(response) + : null; + } + return item; + } + + Future> loadRaces() async { + final db = await database; + var response = await db.query( + "Items", + where: "ItemType = 'RaceItem'", + orderBy: "NormalizedName" + ); + if (response.isNotEmpty) { + return itemsFromMapList(response); + } + return null; + } + + Future> loadSubRaces(RaceItem race) async { + final db = await database; + var response = await db.query( + "Items", + where: "ItemType = 'SubRaceItem' AND ParentLink = ?", + whereArgs: [race.id], + orderBy: "NormalizedName" + ); + if (response.isNotEmpty) { + return itemsFromMapList(response); + } + return null; + } + + Future> loadTypedItems( + {String itemType, Item item}) async { + final db = await database; + var response = await db.query( + "Items", + where: "ItemType = ?" + (item != null ? " AND ParentLink = ?" : ""), + whereArgs: item != null ? [itemType, item.id] : [itemType], + orderBy: "NormalizedName" + ); + if (response.isNotEmpty) { + return itemsFromMapList(response); + } + return null; + } + + Future> loadBackgrounds() async { + return loadTypedItems(itemType: "BackgroundItem"); + } + + Future> loadSubBackgrounds(Item item) async { + return loadTypedItems( + itemType: "SubBackgroundItem", item: item); + } + +} \ No newline at end of file diff --git a/aidedejeu_flutter/lib/widgets/library.dart b/aidedejeu_flutter/lib/widgets/library.dart index 0fd77175..d02f5677 100644 --- a/aidedejeu_flutter/lib/widgets/library.dart +++ b/aidedejeu_flutter/lib/widgets/library.dart @@ -1,4 +1,5 @@ -import 'package:aidedejeu_flutter/database.dart'; +import 'file:///C:/dev/AideDeJeu/aidedejeu_flutter/lib/databases/database_sqflite.dart'; +import 'package:aidedejeu_flutter/databases/database.dart'; import 'package:aidedejeu_flutter/localization.dart'; import 'package:aidedejeu_flutter/models/filters.dart'; import 'package:aidedejeu_flutter/widgets/filters.dart'; @@ -13,12 +14,14 @@ class LibraryPage extends StatefulWidget { LibraryPage({Key key, @required this.id}) : super(key: key); final String id; + final BaseDB _db = SqfliteDB.instance; @override _LibraryPageState createState() => _LibraryPageState(); } class _LibraryPageState extends State { + final BaseDB _db = SqfliteDB.instance; void setItem(Item item) { setState(() { this.item = item; @@ -54,8 +57,8 @@ class _LibraryPageState extends State { } Future _loadItem() async { - var item = await getItemWithId(this.widget.id); - await loadChildrenItems(item, filters); + var item = await SqfliteDB.instance.getItemWithId(this.widget.id); + await _db.loadChildrenItems(item, filters); return item; } @@ -176,7 +179,7 @@ class _LibraryPageState extends State { setState(() { filter.selectedValues = choices; }); - loadChildrenItems(item, filters).then((value) => { + _db.loadChildrenItems(item, filters).then((value) => { setState(() { this.item = item; this.filters = filters; @@ -194,7 +197,7 @@ class _LibraryPageState extends State { setState(() { filter.rangeValues = values; }); - loadChildrenItems(item, filters).then((value) => { + _db.loadChildrenItems(item, filters).then((value) => { setState(() { this.item = item; this.filters = filters; diff --git a/aidedejeu_flutter/pubspec.lock b/aidedejeu_flutter/pubspec.lock index 2ac70421..74c31ddc 100644 --- a/aidedejeu_flutter/pubspec.lock +++ b/aidedejeu_flutter/pubspec.lock @@ -136,7 +136,7 @@ packages: name: flutter_svg url: "https://pub.dartlang.org" source: hosted - version: "0.17.2" + version: "0.17.3+1" flutter_test: dependency: "direct dev" description: flutter @@ -156,6 +156,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.14.0+3" + idb_shim: + dependency: transitive + description: + name: idb_shim + url: "https://pub.dartlang.org" + source: hosted + version: "1.10.3+1" image: dependency: transitive description: @@ -232,7 +239,7 @@ packages: name: package_config url: "https://pub.dartlang.org" source: hosted - version: "1.9.1" + version: "1.9.2" path: dependency: "direct main" description: @@ -281,7 +288,7 @@ packages: name: pub_semver url: "https://pub.dartlang.org" source: hosted - version: "1.4.3" + version: "1.4.4" quiver: dependency: transitive description: @@ -296,6 +303,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.23.1" + sembast: + dependency: "direct main" + description: + name: sembast + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.0" + sembast_web: + dependency: "direct main" + description: + name: sembast_web + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" sky_engine: dependency: transitive description: flutter @@ -314,7 +335,14 @@ packages: name: sqflite url: "https://pub.dartlang.org" source: hosted - version: "1.2.1" + version: "1.3.0" + sqflite_common: + dependency: transitive + description: + name: sqflite_common + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0+1" stack_trace: dependency: transitive description: @@ -377,7 +405,7 @@ packages: name: watcher url: "https://pub.dartlang.org" source: hosted - version: "0.9.7+13" + version: "0.9.7+14" xml: dependency: transitive description: diff --git a/aidedejeu_flutter/pubspec.yaml b/aidedejeu_flutter/pubspec.yaml index aa8f596a..1551c594 100644 --- a/aidedejeu_flutter/pubspec.yaml +++ b/aidedejeu_flutter/pubspec.yaml @@ -24,8 +24,10 @@ dependencies: sdk: flutter intl: intl_translation: - flutter_markdown: ^0.3.3 + flutter_markdown: sqflite: + sembast: + sembast_web: path: flutter_svg: bloc: