flutter-freaccess-hub/lib/shared/helpers/sqlite_storage_helper.dart

317 lines
10 KiB
Dart

import 'package:hub/shared/utils/cache_util.dart';
import 'package:sqflite/sqflite.dart';
import 'dart:developer';
import 'package:flutter/foundation.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'dart:developer';
import 'package:flutter/foundation.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
class DatabaseConfig {
static const String dbName = 'database.db';
static const int dbVersion = 1;
static const String tableKeychain = 'keychain';
static const String columnKey = 'key';
static const String columnValue = 'value';
static const String columnType = 'type';
static const String columnUpdateAt = 'updateAt';
static const String columnResolvedAt = 'resolvedAt';
static const String columnCreatedAt = 'createdAt';
static const List<Map<String, dynamic>> initialData = [
{'key': 'devUUID', 'value': '', 'type': 'user'},
{'key': 'userUUID', 'value': '', 'type': 'user'},
{'key': 'userDevUUID', 'value': '', 'type': 'user'},
{'key': 'status', 'value': '', 'type': 'user'},
{'key': 'userName', 'value': '', 'type': 'user'},
{'key': 'cliUUID', 'value': '', 'type': 'local'},
{'key': 'ownerUUID', 'value': '', 'type': 'local'},
{'key': 'cliName', 'value': '', 'type': 'local'},
{'key': 'whatsapp', 'value': 'false', 'type': 'util'},
{'key': 'provisional', 'value': 'false', 'type': 'util'},
{'key': 'pets', 'value': 'false', 'type': 'util'},
{'key': 'local', 'value': 'false', 'type': 'util'},
{'key': 'notify', 'value': 'false', 'type': 'util'},
{'key': 'fingerprint', 'value': 'false', 'type': 'util'},
{'key': 'access', 'value': 'false', 'type': 'util'},
{'key': 'panic', 'value': 'false', 'type': 'util'},
{'key': 'person', 'value': 'false', 'type': 'util'},
{'key': 'requestOSnotification', 'value': 'false', 'type': 'util'},
{'key': 'petAmountRegister', 'value': '', 'type': 'local'},
];
}
class SQLiteStorageHelper {
static final SQLiteStorageHelper _instance = SQLiteStorageHelper._internal();
static Database? _database;
static String? _databasePath;
factory SQLiteStorageHelper() => _instance;
SQLiteStorageHelper._internal();
Future<Database> get database async {
if (_database != null) return _database!;
_database = await _initDatabase();
return _database!;
}
Future<String> _getDatabasePath() async {
if (_databasePath != null) return _databasePath!;
final databasesPath = await getDatabasesPath();
_databasePath = join(databasesPath, DatabaseConfig.dbName);
log('Database path: $_databasePath');
return _databasePath!;
}
Future<Database> _initDatabase() async {
final path = await _getDatabasePath();
return await openDatabase(
path,
version: DatabaseConfig.dbVersion,
onCreate: _onCreate,
onOpen: _onOpen,
onUpgrade: _onUpgrade,
onDowngrade: _onDowngrade,
onConfigure: _onConfigure,
).catchError((error) {
log('Error initializing database: $error');
throw error;
}).whenComplete(() async => await setupLocalVariables());
}
Future<void> _onCreate(Database db, int version) async {
log('Creating tables...');
await db.execute('''
CREATE TABLE ${DatabaseConfig.tableKeychain} (
${DatabaseConfig.columnKey} TEXT UNIQUE,
${DatabaseConfig.columnValue} TEXT,
${DatabaseConfig.columnType} TEXT,
${DatabaseConfig.columnUpdateAt} TEXT,
${DatabaseConfig.columnResolvedAt} TEXT,
${DatabaseConfig.columnCreatedAt} TEXT
);
''');
await _insertInitialData(db);
log('Tables created');
}
Future<void> _insertInitialData(Database db) async {
final batch = db.batch();
for (var data in DatabaseConfig.initialData) {
batch.insert(DatabaseConfig.tableKeychain, data);
}
await batch.commit(noResult: true);
}
Future<void> _onOpen(Database db) async {
log('Checking existing data...');
await _checkExistingData(db);
}
Future<void> _onUpgrade(Database db, int oldVersion, int newVersion) async {
log('Upgrading database from version $oldVersion to $newVersion');
}
Future<void> _onDowngrade(Database db, int oldVersion, int newVersion) async {
log('Downgrading database from version $oldVersion to $newVersion');
}
Future<void> _onConfigure(Database db) async {
log('Configuring database...');
}
Future<void> _checkExistingData(Database db) async {
try {
final maps = await db.query(DatabaseConfig.tableKeychain);
log('Existing data: $maps');
} catch (error) {
log('Error checking existing data: $error');
}
}
String _devUUID = '';
String _userUUID = '';
String _userDevUUID = '';
String _status = '';
String _userName = '';
String _cliUUID = '';
String _ownerUUID = '';
String _cliName = '';
String _petAmountRegister = '';
bool _whatsapp = false;
bool _provisional = false;
bool _pets = false;
bool _local = false;
bool _notify = false;
bool _fingerprint = false;
bool _access = false;
bool _panic = false;
bool _person = false;
bool _requestOSnotification = false;
String get createdAt => '0000-00-00 00:00:00';
String get devUUID => _devUUID;
String get userUUID => _userUUID;
String get userDevUUID => _userDevUUID;
String get status => _status;
String get userName => _userName;
String get cliUUID => _cliUUID;
String get ownerUUID => _ownerUUID;
String get cliName => _cliName;
String get petAmountRegister => _petAmountRegister;
bool get whatsapp => _whatsapp;
bool get provisional => _provisional;
bool get pets => _pets;
bool get local => _local;
bool get notify => _notify;
bool get fingerprint => _fingerprint;
bool get access => _access;
bool get panic => _panic;
bool get person => _person;
bool get requestOSnotification => _requestOSnotification;
set devUUID(String value) => set('devUUID', value);
set userUUID(String value) => set('userUUID', value);
set userDevUUID(String value) => set('userDevUUID', value);
set status(String value) => set('status', value);
set userName(String value) => set('userName', value);
set cliUUID(String value) => set('cliUUID', value);
set ownerUUID(String value) => set('ownerUUID', value);
set cliName(String value) => set('cliName', value);
set petAmountRegister(String value) => set('petAmountRegister', value);
set whatsapp(bool value) => set('whatsapp', value);
set provisional(bool value) => set('provisional', value);
set pets(bool value) => set('pets', value);
set local(bool value) => set('local', value);
set notify(bool value) => set('notify', value);
set fingerprint(bool value) => set('fingerprint', value);
set access(bool value) => set('access', value);
set panic(bool value) => set('panic', value);
set person(bool value) => set('person', value);
set requestOSnotification(bool value) => set('requestOSnotification', value);
Future<void> setupLocalVariables() async {
log('Setting up local variables...');
await _database?.transaction((txn) async {
final keys = [
'devUUID',
'userUUID',
'userDevUUID',
'status',
'userName',
'cliUUID',
'ownerUUID',
'cliName',
'whatsapp',
'provisional',
'pets',
'local',
'notify',
'fingerprint',
'access',
'panic',
'person',
'requestOSnotification'
];
final results = await Future.wait(keys.map((key) => get(key)));
_devUUID = results[0]?.toString() ?? '';
_userUUID = results[1]?.toString() ?? '';
_userDevUUID = results[2]?.toString() ?? '';
_status = results[3]?.toString() ?? '';
_userName = results[4]?.toString() ?? '';
_cliUUID = results[5]?.toString() ?? '';
_ownerUUID = results[6]?.toString() ?? '';
_cliName = results[7]?.toString() ?? '';
_whatsapp = results[8] == 'true';
_provisional = results[9] == 'true';
_pets = results[10] == 'true';
_local = results[11] == 'true';
_notify = results[12] == 'true';
_fingerprint = results[13] == 'true';
_access = results[14] == 'true';
_panic = results[15] == 'true';
_person = results[16] == 'true';
_requestOSnotification = results[17] == 'true';
});
}
Future<bool> getBoolean(String key) async {
final value = await get(key);
return value == 'true';
}
Future<dynamic> get(String key) async {
final cachedValue = CacheUtil.get(key);
if (cachedValue != null) {
return cachedValue;
}
try {
final db = await database;
final result = await db.query(
DatabaseConfig.tableKeychain,
columns: [DatabaseConfig.columnValue],
where: '${DatabaseConfig.columnKey} = ?',
whereArgs: [key],
);
if (result.isNotEmpty) {
final value = result.first[DatabaseConfig.columnValue];
CacheUtil.set(key, value);
return value;
}
return null;
} catch (error) {
log('Error getting value for key $key: $error');
return null;
}
}
Future<int> set(String key, dynamic value) async {
CacheUtil.set(key, value);
final db = await database;
final data = {
DatabaseConfig.columnKey: key,
DatabaseConfig.columnValue: value.toString(),
DatabaseConfig.columnUpdateAt: DateTime.now().toIso8601String(),
DatabaseConfig.columnCreatedAt: DateTime.now().toIso8601String(),
};
return await db.insert(
DatabaseConfig.tableKeychain,
data,
conflictAlgorithm: ConflictAlgorithm.replace,
);
}
Future<int> delete(String key) async {
final db = await database;
return await db.transaction((txn) async {
return await txn.delete(
DatabaseConfig.tableKeychain,
where: '${DatabaseConfig.columnKey} = ?',
whereArgs: [key],
);
});
}
Future<void> purge() async {
await deleteDatabaseDB();
await database;
log('Database purged');
}
Future<void> deleteDatabaseDB() async {
final path = await _getDatabasePath();
await deleteDatabase(path);
log('Database deleted');
_database = null;
}
}