import 'package:hub/shared/utils/cache_util.dart'; import 'package:sqflite/sqflite.dart'; import 'dart:developer'; import 'package:path/path.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> 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(); static SQLiteStorageHelper get instance => _instance; Future ensureInitialization() async { log('Getting database instance'); if (_database != null) return _database!; _database = await _initDatabase(); return _database!; } Future _getDatabasePath() async { log('Getting database path'); if (_databasePath != null) return _databasePath!; final databasesPath = await getDatabasesPath(); _databasePath = join(databasesPath, DatabaseConfig.dbName); log('Database path: $_databasePath'); return _databasePath!; } Future _initDatabase() async { log('Initializing database'); 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 { log('Database initialization complete'); await setupLocalVariables(); }); } Future _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 _insertInitialData(Database db) async { log('Inserting initial data'); final batch = db.batch(); for (var data in DatabaseConfig.initialData) { batch.insert(DatabaseConfig.tableKeychain, data); } await batch.commit(noResult: true); log('Initial data inserted'); } Future _onOpen(Database db) async { log('Opening database'); await _checkExistingData(db); } Future _onUpgrade(Database db, int oldVersion, int newVersion) async { log('Upgrading database from version $oldVersion to $newVersion'); } Future _onDowngrade(Database db, int oldVersion, int newVersion) async { log('Downgrading database from version $oldVersion to $newVersion'); } Future _onConfigure(Database db) async { log('Configuring database'); } Future _checkExistingData(Database db) async { log('Checking existing data'); 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 { log('Getting createdAt'); return '0000-00-00 00:00:00'; } String get devUUID { log('Getting devUUID'); return _devUUID; } String get userUUID { log('Getting userUUID'); return _userUUID; } String get userDevUUID { log('Getting userDevUUID'); return _userDevUUID; } String get status { log('Getting status'); return _status; } String get userName { log('Getting userName'); return _userName; } String get cliUUID { log('Getting cliUUID'); return _cliUUID; } String get ownerUUID { log('Getting ownerUUID'); return _ownerUUID; } String get cliName { log('Getting cliName'); return _cliName; } String get petAmountRegister { log('Getting petAmountRegister'); return _petAmountRegister; } bool get whatsapp { log('Getting whatsapp'); return _whatsapp; } bool get provisional { log('Getting provisional'); return _provisional; } bool get pets { log('Getting pets'); return _pets; } bool get local { log('Getting local'); return _local; } bool get notify { log('Getting notify'); return _notify; } bool get fingerprint { log('Getting fingerprint'); return _fingerprint; } bool get access { log('Getting access'); return _access; } bool get panic { log('Getting panic'); return _panic; } bool get person { log('Getting person'); return _person; } bool get requestOSnotification { log('Getting requestOSnotification'); return _requestOSnotification; } set devUUID(String value) { log('Setting devUUID to $value'); set('devUUID', value); } set userUUID(String value) { log('Setting userUUID to $value'); set('userUUID', value); } set userDevUUID(String value) { log('Setting userDevUUID to $value'); set('userDevUUID', value); } set status(String value) { log('Setting status to $value'); set('status', value); } set userName(String value) { log('Setting userName to $value'); set('userName', value); } set cliUUID(String value) { log('Setting cliUUID to $value'); set('cliUUID', value); } set ownerUUID(String value) { log('Setting ownerUUID to $value'); set('ownerUUID', value); } set cliName(String value) { log('Setting cliName to $value'); set('cliName', value); } set petAmountRegister(String value) { log('Setting petAmountRegister to $value'); set('petAmountRegister', value); } set whatsapp(bool value) { log('Setting whatsapp to $value'); set('whatsapp', value); } set provisional(bool value) { log('Setting provisional to $value'); set('provisional', value); } set pets(bool value) { log('Setting pets to $value'); set('pets', value); } set local(bool value) { log('Setting local to $value'); set('local', value); } set notify(bool value) { log('Setting notify to $value'); set('notify', value); } set fingerprint(bool value) { log('Setting fingerprint to $value'); set('fingerprint', value); } set access(bool value) { log('Setting access to $value'); set('access', value); } set panic(bool value) { log('Setting panic to $value'); set('panic', value); } set person(bool value) { log('Setting person to $value'); set('person', value); } set requestOSnotification(bool value) { log('Setting requestOSnotification to $value'); set('requestOSnotification', value); } Future setupLocalVariables() async { log('Setting up local variables'); try { await _database?.transaction((txn) async { final keys = [ 'devUUID', 'userUUID', 'userDevUUID', 'status', 'userName', 'cliUUID', 'ownerUUID', 'cliName', 'petAmountRegister', 'whatsapp', 'provisional', 'pets', 'local', 'notify', 'fingerprint', 'access', 'panic', 'person', 'requestOSnotification' ]; for (var key in keys) { log('Fetching value for key: $key'); final result = await txn.query( DatabaseConfig.tableKeychain, where: '${DatabaseConfig.columnKey} = ?', whereArgs: [key], ); log('Result for key $key: $result'); } }); log('Local variables setup complete'); } catch (error) { log('Error setting up local variables: $error'); } } Future getBoolean(String key) async { log('Getting boolean value for key: $key'); final value = await get(key); return value == 'true'; } Future get(String key) async { log('Getting value for key: $key'); final cachedValue = CacheUtil().get(key); if (cachedValue != null) { log('Found cached value for key: $key'); return cachedValue; } try { final db = await ensureInitialization(); 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); log('Value for key $key: $value'); return value; } log('No value found for key: $key'); return null; } catch (error) { log('Error getting value for key $key: $error'); return null; } } Future set(String key, dynamic value) async { log('Setting value for key: $key to $value'); CacheUtil().set(key, value); final db = await ensureInitialization(); final data = { DatabaseConfig.columnKey: key, DatabaseConfig.columnValue: value.toString(), DatabaseConfig.columnUpdateAt: DateTime.now().toIso8601String(), DatabaseConfig.columnCreatedAt: DateTime.now().toIso8601String(), }; final result = await db.insert( DatabaseConfig.tableKeychain, data, conflictAlgorithm: ConflictAlgorithm.replace, ); log('Value set for key: $key'); return result; } Future delete(String key) async { log('Deleting value for key: $key'); final db = await ensureInitialization(); final result = await db.transaction((txn) async { return await txn.delete( DatabaseConfig.tableKeychain, where: '${DatabaseConfig.columnKey} = ?', whereArgs: [key], ); }); log('Value deleted for key: $key'); return result; } Future purge() async { log('Purging database'); await deleteDatabaseDB(); await ensureInitialization(); log('Database purged'); } Future deleteDatabaseDB() async { log('Deleting database'); final path = await _getDatabasePath(); await deleteDatabase(path); log('Database deleted'); _database = null; } }