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'; } class DatabaseHelper { static final DatabaseHelper _instance = DatabaseHelper._internal(); static Database? _database; factory DatabaseHelper() => _instance; DatabaseHelper._internal(); Future get database async { if (_database != null) return _database!; _database = await _initDatabase(); return _database!; } Future _initDatabase() async { final path = await _getDatabasePath(); log('Database path: $path'); return await openDatabase( path, version: DatabaseConfig.dbVersion, onCreate: _onCreate, onOpen: _onOpen, onUpgrade: _onUpgrade, onDowngrade: _onDowngrade, onConfigure: _onConfigure, ).catchError((error) { throw error; }).whenComplete(() => log('Database initialized')); } Future _getDatabasePath() async { final databasesPath = await getDatabasesPath(); final path = join(databasesPath, DatabaseConfig.dbName); log('Database path: $path'); return path; } 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 { final 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'}, ]; for (var data in initialData) { await db.insert(DatabaseConfig.tableKeychain, data); } } Future _onOpen(Database db) async { log('Checking existing data...'); 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 { try { final maps = await db.query(DatabaseConfig.tableKeychain); log('Existing data: $maps'); } catch (error) { log('Error checking existing data: $error'); } } Future deleteDatabaseDB() async { final path = await _getDatabasePath(); await deleteDatabase(path); log('Database deleted'); _database = null; } Future get({String? key, String? field}) async { try { final db = await database; List> queryResult; if (field != null && key != null) { queryResult = await db.query( DatabaseConfig.tableKeychain, columns: [field], where: '${DatabaseConfig.columnKey} = ?', whereArgs: [key], ); } else if (field != null) { queryResult = await db.query( DatabaseConfig.tableKeychain, columns: [field], ); } else if (key != null) { field = DatabaseConfig.columnValue; queryResult = await db.query( DatabaseConfig.tableKeychain, columns: [field], where: '${DatabaseConfig.columnKey} = ?', whereArgs: [key], ); } else { queryResult = await db.query(DatabaseConfig.tableKeychain); } log('Query result for key: $key, field: $field -> $queryResult'); if (queryResult.isNotEmpty) { return queryResult.first[field]; } else { return null; } } catch (error) { log('Error getting: $error'); return null; } } Future insert(String key, dynamic value, String? type) async { final db = await database; final Map data = { DatabaseConfig.columnKey: key, DatabaseConfig.columnValue: value.toString(), DatabaseConfig.columnType: type, DatabaseConfig.columnUpdateAt: DateTime.now().toIso8601String(), DatabaseConfig.columnResolvedAt: null, DatabaseConfig.columnCreatedAt: DateTime.now().toIso8601String(), }; log('Inserting: $data'); return await db.insert(DatabaseConfig.tableKeychain, data); } Future update(String key, dynamic value, String? type) async { final db = await database; final Map data = { DatabaseConfig.columnKey: key, if (value != null) DatabaseConfig.columnValue: value.toString(), if (type != null) DatabaseConfig.columnType: type, DatabaseConfig.columnUpdateAt: DateTime.now().toIso8601String(), DatabaseConfig.columnResolvedAt: null, DatabaseConfig.columnCreatedAt: DateTime.now().toIso8601String(), }; log('Updating: $data'); return await db.update( DatabaseConfig.tableKeychain, data, where: '${DatabaseConfig.columnKey} = ?', whereArgs: [key], ); } Future clear(String key) async { final db = await database; log('Setting value of key: $key to empty string'); return await db.update( DatabaseConfig.tableKeychain, {DatabaseConfig.columnValue: ''}, where: '${DatabaseConfig.columnKey} = ?', whereArgs: [key], ); } Future delete(String key) async { final db = await database; log('Deleting key: $key'); return await db.delete( DatabaseConfig.tableKeychain, where: '${DatabaseConfig.columnKey} = ?', whereArgs: [key], ); } Future purge() async { await deleteDatabaseDB(); await database; log('Purge'); } }