1
0
mirror of https://gitlab.com/comunic/comunicmobile synced 2024-11-25 22:39:22 +00:00

Do not use SQLite anymore for users

This commit is contained in:
Pierre HUBERT 2021-03-14 18:15:38 +01:00
parent e474725965
commit bd794f8079
12 changed files with 89 additions and 106 deletions

View File

@ -3,12 +3,3 @@
/// @author Pierre HUBERT /// @author Pierre HUBERT
enum UserPageVisibility { PRIVATE, PUBLIC, OPEN } enum UserPageVisibility { PRIVATE, PUBLIC, OPEN }
/// Find the visibility level matching a string
UserPageVisibility userPageVisibilityFromString(String str) {
for (int i = 0; i < UserPageVisibility.values.length; i++)
if (UserPageVisibility.values[i].toString() == str)
return UserPageVisibility.values[i];
throw "$str is not a valid user page visibility level!";
}

View File

@ -5,12 +5,13 @@
// ignore_for_file: lines_longer_than_80_chars // ignore_for_file: lines_longer_than_80_chars
import 'package:file_picker/src/file_picker_web.dart'; import 'package:file_picker/src/file_picker_web.dart';
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
import 'package:shared_preferences_web/shared_preferences_web.dart'; import 'package:shared_preferences_web/shared_preferences_web.dart';
import 'package:url_launcher_web/url_launcher_web.dart'; import 'package:url_launcher_web/url_launcher_web.dart';
import 'package:video_player_web/video_player_web.dart'; import 'package:video_player_web/video_player_web.dart';
import 'package:wakelock_web/wakelock_web.dart'; import 'package:wakelock_web/wakelock_web.dart';
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
// ignore: public_member_api_docs // ignore: public_member_api_docs
void registerPlugins(Registrar registrar) { void registerPlugins(Registrar registrar) {
FilePickerWeb.registerWith(registrar); FilePickerWeb.registerWith(registrar);

View File

@ -13,18 +13,6 @@ abstract class BaseTableContract {
static const C_ID = "id"; static const C_ID = "id";
} }
/// User table contract
abstract class UserTableContract {
static const TABLE_NAME = "users";
static const C_ID = BaseTableContract.C_ID;
static const C_FIRST_NAME = "first_name";
static const C_LAST_NAME = "last_name";
static const C_VISIBILITY = "visibility";
static const C_VIRTUAL_DIRECTORY = "virtual_directory";
static const C_ACCOUNT_IMAGE_URL = "account_image_url";
static const C_CUSTOM_EMOJIES = "custom_emojies";
}
/// Friends table contract /// Friends table contract
abstract class FriendsListTableContract { abstract class FriendsListTableContract {
static const TABLE_NAME = "friends"; static const TABLE_NAME = "friends";

View File

@ -1,5 +1,4 @@
import 'package:comunic/helpers/database/database_contract.dart'; import 'package:comunic/helpers/database/database_contract.dart';
import 'package:connectivity/connectivity.dart';
import 'package:path/path.dart'; import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart'; import 'package:sqflite/sqflite.dart';
@ -30,21 +29,11 @@ abstract class DatabaseHelper {
return _db; return _db;
} }
/// Cleanup database
static Future<void> cleanUpDatabase() async {
// If connected to a network, cleanup user information
if (await Connectivity().checkConnectivity() != ConnectivityResult.none)
await _db.execute("DELETE FROM ${UserTableContract.TABLE_NAME}");
}
/// Perform database update /// Perform database update
/// ///
/// Currently : delete all the database tables and initialize it again /// Currently : delete all the database tables and initialize it again
static Future<void> _performDatabaseUpdate( static Future<void> _performDatabaseUpdate(
Database db, int oldVersion, int newVersion) async { Database db, int oldVersion, int newVersion) async {
// Drop users table
await db.execute("DROP TABLE IF EXISTS ${UserTableContract.TABLE_NAME}");
// Drop friends list table // Drop friends list table
await db await db
.execute("DROP TABLE IF EXISTS ${FriendsListTableContract.TABLE_NAME}"); .execute("DROP TABLE IF EXISTS ${FriendsListTableContract.TABLE_NAME}");
@ -55,17 +44,6 @@ abstract class DatabaseHelper {
/// Initialize the database /// Initialize the database
static Future<void> _initializeDatabase(Database db, int version) async { static Future<void> _initializeDatabase(Database db, int version) async {
// Create users table
await db.execute("CREATE TABLE ${UserTableContract.TABLE_NAME} ("
"${UserTableContract.C_ID} INTEGER PRIMARY KEY, "
"${UserTableContract.C_FIRST_NAME} TEXT, "
"${UserTableContract.C_LAST_NAME} TEXT, "
"${UserTableContract.C_VISIBILITY} TEXT, "
"${UserTableContract.C_VIRTUAL_DIRECTORY} TEXT, "
"${UserTableContract.C_ACCOUNT_IMAGE_URL} TEXT, "
"${UserTableContract.C_CUSTOM_EMOJIES} TEXT"
")");
// Friends list table // Friends list table
await db.execute("CREATE TABLE ${FriendsListTableContract.TABLE_NAME} (" await db.execute("CREATE TABLE ${FriendsListTableContract.TABLE_NAME} ("
"${FriendsListTableContract.C_ID} INTEGER PRIMARY KEY, " "${FriendsListTableContract.C_ID} INTEGER PRIMARY KEY, "

View File

@ -1,24 +0,0 @@
import 'package:comunic/helpers/database/model_database_helper.dart';
import 'package:comunic/models/user.dart';
import 'database_contract.dart';
/// User database helper
///
/// @author Pierre HUBERT
class UsersDatabaseHelper extends ModelDatabaseHelper<User> {
@override
String tableName() {
return UserTableContract.TABLE_NAME;
}
@override
User initializeFromMap(Map<String, dynamic> map) {
return User.fromMap(map);
}
}

View File

@ -102,6 +102,8 @@ abstract class BaseSerializationHelper<T extends SerializableElement> {
return _cache.any((element) => isContained(element)); return _cache.any((element) => isContained(element));
} }
Future<bool> has(T el) => any((t) => t == el);
/// Check if any entry in the last match the predicate /// Check if any entry in the last match the predicate
Future<T> first(bool filter(T t)) async { Future<T> first(bool filter(T t)) async {
await _loadCache(); await _loadCache();
@ -120,10 +122,26 @@ abstract class BaseSerializationHelper<T extends SerializableElement> {
await _saveCache(); await _saveCache();
} }
/// Insert or replace many elements
Future<void> insertOrReplaceElements(List<T> list) async {
await _loadCache();
_cache.removeWhere((element) => list.any((newEl) => element == newEl));
_cache.addAll(list);
await _saveCache();
}
/// Remove elements /// Remove elements
Future<void> removeElement(bool isToRemove(T t)) async { Future<void> removeElement(bool isToRemove(T t)) async {
await _loadCache(); await _loadCache();
_cache.removeWhere((element) => isToRemove(element)); _cache.removeWhere((element) => isToRemove(element));
await _saveCache(); await _saveCache();
} }
/// Remove all elements
Future<void> removeAll() async {
_cache = [];
await _saveCache();
}
} }

View File

@ -0,0 +1,28 @@
import 'package:comunic/helpers/serialization/base_serialization_helper.dart';
import 'package:comunic/models/user.dart';
/// User serialization helper
///
/// @author Pierre Hubert
UsersListSerialisationHelper _singleton;
class UsersListSerialisationHelper extends BaseSerializationHelper<User> {
UsersListSerialisationHelper._();
factory UsersListSerialisationHelper() {
if (_singleton == null) _singleton = UsersListSerialisationHelper._();
return _singleton;
}
@override
String get type => "users-list";
@override
User parse(Map<String, dynamic> m) => User.fromJson(m);
/// Remove a user by its ID
Future<void> removeUserByID(int userID) =>
removeElement((t) => t.id == userID);
}

View File

@ -1,5 +1,5 @@
import 'package:comunic/enums/user_page_visibility.dart'; import 'package:comunic/enums/user_page_visibility.dart';
import 'package:comunic/helpers/database/users_database_helper.dart'; import 'package:comunic/helpers/serialization/user_list_serialization_helper.dart';
import 'package:comunic/lists/custom_emojies_list.dart'; import 'package:comunic/lists/custom_emojies_list.dart';
import 'package:comunic/lists/users_list.dart'; import 'package:comunic/lists/users_list.dart';
import 'package:comunic/models/advanced_user_info.dart'; import 'package:comunic/models/advanced_user_info.dart';
@ -27,7 +27,6 @@ class GetUserAdvancedUserError extends Error {
} }
class UsersHelper { class UsersHelper {
final UsersDatabaseHelper _usersDatabaseHelper = UsersDatabaseHelper();
/// Download information about some given users ID /// Download information about some given users ID
/// ///
@ -64,7 +63,7 @@ class UsersHelper {
); );
// Save the list // Save the list
_usersDatabaseHelper.insertOrUpdateAll(list); await UsersListSerialisationHelper().insertOrReplaceElements(list);
return list; return list;
} }
@ -114,8 +113,8 @@ class UsersHelper {
// Check cache // Check cache
for (int userID in users) { for (int userID in users) {
if (!forceDownload && await _usersDatabaseHelper.has(userID)) if (!forceDownload && await UsersListSerialisationHelper().any((u) => u.id == userID))
list.add(await _usersDatabaseHelper.get(userID)); list.add(await UsersListSerialisationHelper().first((u) => u.id == userID));
else else
toDownload.add(userID); toDownload.add(userID);
} }

View File

@ -1,10 +1,12 @@
import 'package:comunic/helpers/account_helper.dart'; import 'package:comunic/helpers/account_helper.dart';
import 'package:comunic/helpers/database/database_helper.dart'; import 'package:comunic/helpers/database/database_helper.dart';
import 'package:comunic/helpers/preferences_helper.dart'; import 'package:comunic/helpers/preferences_helper.dart';
import 'package:comunic/helpers/serialization/user_list_serialization_helper.dart';
import 'package:comunic/helpers/version_helper.dart'; import 'package:comunic/helpers/version_helper.dart';
import 'package:comunic/ui/widgets/init_widget.dart'; import 'package:comunic/ui/widgets/init_widget.dart';
import 'package:comunic/utils/flutter_utils.dart'; import 'package:comunic/utils/flutter_utils.dart';
import 'package:comunic/utils/intl_utils.dart'; import 'package:comunic/utils/intl_utils.dart';
import 'package:connectivity/connectivity.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
/// Main file of the application /// Main file of the application
@ -18,9 +20,11 @@ void subMain() async {
await VersionHelper.ensureLoaded(); await VersionHelper.ensureLoaded();
// Connect to database // Connect to database
if(!isWeb) { if (!isWeb) {
await DatabaseHelper.open(); await DatabaseHelper.open();
await DatabaseHelper.cleanUpDatabase();
if (await Connectivity().checkConnectivity() != ConnectivityResult.none)
await UsersListSerialisationHelper().removeAll();
} }
// Get current system language // Get current system language

View File

@ -1,9 +1,8 @@
import 'dart:convert'; import 'dart:convert';
import 'package:comunic/enums/user_page_visibility.dart'; import 'package:comunic/enums/user_page_visibility.dart';
import 'package:comunic/helpers/database/database_contract.dart'; import 'package:comunic/helpers/serialization/base_serialization_helper.dart';
import 'package:comunic/lists/custom_emojies_list.dart'; import 'package:comunic/lists/custom_emojies_list.dart';
import 'package:comunic/models/cache_model.dart';
import 'package:comunic/utils/ui_utils.dart'; import 'package:comunic/utils/ui_utils.dart';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
@ -11,7 +10,8 @@ import 'package:meta/meta.dart';
/// ///
/// @author Pierre HUBERT /// @author Pierre HUBERT
class User extends CacheModel { class User implements SerializableElement<User> {
final int id;
final String firstName; final String firstName;
final String lastName; final String lastName;
final UserPageVisibility pageVisibility; final UserPageVisibility pageVisibility;
@ -20,7 +20,7 @@ class User extends CacheModel {
final CustomEmojiesList customEmojies; final CustomEmojiesList customEmojies;
const User({ const User({
@required int id, @required this.id,
@required this.firstName, @required this.firstName,
@required this.lastName, @required this.lastName,
@required this.pageVisibility, @required this.pageVisibility,
@ -28,12 +28,12 @@ class User extends CacheModel {
@required this.accountImageURL, @required this.accountImageURL,
@required this.customEmojies, @required this.customEmojies,
}) : assert(id != null), }) : assert(id != null),
assert(id > 0),
assert(firstName != null), assert(firstName != null),
assert(lastName != null), assert(lastName != null),
assert(pageVisibility != null), assert(pageVisibility != null),
assert(accountImageURL != null), assert(accountImageURL != null),
assert(customEmojies != null), assert(customEmojies != null);
super(id: id);
/// Get user full name /// Get user full name
String get fullName => firstName + " " + lastName; String get fullName => firstName + " " + lastName;
@ -44,27 +44,27 @@ class User extends CacheModel {
bool get hasVirtualDirectory => bool get hasVirtualDirectory =>
virtualDirectory != null && virtualDirectory.length > 0; virtualDirectory != null && virtualDirectory.length > 0;
Map<String, dynamic> toMap() { Map<String, dynamic> toJson() => {
return { "id": id,
UserTableContract.C_ID: id, "firstName": firstName,
UserTableContract.C_FIRST_NAME: firstName, "lastName": lastName,
UserTableContract.C_LAST_NAME: lastName, "pageVisibility": pageVisibility.toString(),
UserTableContract.C_VISIBILITY: pageVisibility.toString(), "virtualDirectory": virtualDirectory,
UserTableContract.C_VIRTUAL_DIRECTORY: virtualDirectory, "accountImageURL": accountImageURL,
UserTableContract.C_ACCOUNT_IMAGE_URL: accountImageURL, "customEmojies": customEmojies.toSerializableList()
UserTableContract.C_CUSTOM_EMOJIES: };
jsonEncode(customEmojies.toSerializableList()),
};
}
User.fromMap(Map<String, dynamic> map) User.fromJson(Map<String, dynamic> map)
: this.firstName = map[UserTableContract.C_FIRST_NAME], : this.id = map["id"],
this.lastName = map[UserTableContract.C_LAST_NAME], this.firstName = map["firstName"],
this.pageVisibility = this.lastName = map["lastName"],
userPageVisibilityFromString(map[UserTableContract.C_VISIBILITY]), this.pageVisibility = UserPageVisibility.values.firstWhere(
this.virtualDirectory = map[UserTableContract.C_VIRTUAL_DIRECTORY], (element) => element.toString() == map["pageVisibility"]),
this.accountImageURL = map[UserTableContract.C_ACCOUNT_IMAGE_URL], this.virtualDirectory = map["virtualDirectory"],
this.accountImageURL = map["accountImageURL"],
this.customEmojies = CustomEmojiesList.fromSerializedList( this.customEmojies = CustomEmojiesList.fromSerializedList(
jsonDecode(map[UserTableContract.C_CUSTOM_EMOJIES])), jsonDecode(map["customEmojies"]));
super.fromMap(map);
@override
int compareTo(User other) => id.compareTo(other.id);
} }

View File

@ -1,4 +1,4 @@
import 'package:comunic/helpers/database/users_database_helper.dart'; import 'package:comunic/helpers/serialization/user_list_serialization_helper.dart';
import 'package:comunic/helpers/settings_helper.dart'; import 'package:comunic/helpers/settings_helper.dart';
import 'package:comunic/models/account_image_settings.dart'; import 'package:comunic/models/account_image_settings.dart';
import 'package:comunic/ui/dialogs/multi_choices_dialog.dart'; import 'package:comunic/ui/dialogs/multi_choices_dialog.dart';
@ -38,7 +38,7 @@ class _AccountImageSettingsScreenState
@override @override
void dispose() { void dispose() {
// Remove current user information to force refresh of account image // Remove current user information to force refresh of account image
UsersDatabaseHelper().delete(userID()); UsersListSerialisationHelper().removeUserByID(userID());
super.dispose(); super.dispose();
} }

View File

@ -1,5 +1,5 @@
import 'package:comunic/enums/user_page_visibility.dart'; import 'package:comunic/enums/user_page_visibility.dart';
import 'package:comunic/helpers/database/users_database_helper.dart'; import 'package:comunic/helpers/serialization/user_list_serialization_helper.dart';
import 'package:comunic/helpers/settings_helper.dart'; import 'package:comunic/helpers/settings_helper.dart';
import 'package:comunic/models/general_settings.dart'; import 'package:comunic/models/general_settings.dart';
import 'package:comunic/ui/dialogs/multi_choices_dialog.dart'; import 'package:comunic/ui/dialogs/multi_choices_dialog.dart';
@ -34,7 +34,7 @@ class _GeneralAccountSettingsScreenState
@override @override
void dispose() { void dispose() {
// Remove current user information to force refresh of account image // Remove current user information to force refresh of account image
UsersDatabaseHelper().delete(userID()); UsersListSerialisationHelper().removeUserByID(userID());
super.dispose(); super.dispose();
} }