import 'dart:ffi'; import 'dart:io'; import 'package:counters/address.dart'; import 'package:counters/counters.dart'; import 'package:counters/value.dart'; import 'package:path/path.dart'; import 'package:path_provider/path_provider.dart'; import 'package:sqflite/sqflite.dart'; class DBProvider { static const int dbVersion = 1; static const String addressTableName = 'address$dbVersion'; static const String countersTableName = 'counters$dbVersion'; static const String ratesTableName = 'rates$dbVersion'; static const String valuesTableName = 'values$dbVersion'; DBProvider._(); static final DBProvider db = DBProvider._(); static Database? _database; Future get database async { if (_database != null) return _database!; _database = await initDB(); return _database!; } createTables(Database db) async { await db.execute("CREATE TABLE IF NOT EXISTS $addressTableName (" "id INTEGER PRIMARY KEY AUTOINCREMENT," "street_name TEXT," "comments TEXT" ")"); await db.execute("CREATE TABLE IF NOT EXISTS $countersTableName (" "id INTEGER PRIMARY KEY AUTOINCREMENT," "address_id INTEGER," "counter_type INTEGER," "name TEXT," "FOREIGN KEY (address_id) REFERENCES $addressTableName (id)" ")"); await db.execute("CREATE TABLE IF NOT EXISTS $ratesTableName (" "id INTEGER PRIMARY KEY AUTOINCREMENT," "counter_id INTEGER," "rate INTEGER," "name TEXT," "FOREIGN KEY (counter_id) REFERENCES $countersTableName (id)" ")"); await db.execute("CREATE TABLE IF NOT EXISTS $valuesTableName (" "id INTEGER PRIMARY KEY AUTOINCREMENT," "counter_id INTEGER," "date INTEGER," "rate1_id INTEGER," "value1 REAL default 0.0," "rate2_id INTEGER," "value2 REAL default 0.0," "rate3_id INTEGER," "value3 REAL default 0.0," "FOREIGN KEY (counter_id) REFERENCES $countersTableName (id)," "FOREIGN KEY (rate1_id) REFERENCES $ratesTableName (id)," "FOREIGN KEY (rate2_id) REFERENCES $ratesTableName (id)," "FOREIGN KEY (rate3_id) REFERENCES $ratesTableName (id)" ")"); } initDB() async { Directory documentsDirectory = await getApplicationSupportDirectory(); String path = join(documentsDirectory.path, "counters.db"); print(path); return await openDatabase(path, version: dbVersion, onOpen: createTables, onCreate: (Database db, int version) async { await createTables(db); }); } Future newAddress(Address newAddress) async { final db = await database; var res = await db.insert(addressTableName, newAddress.toMap()); return res; } Future getAddress(int id) async { final db = await database; var res = await db.query(addressTableName, where: "id = ?", whereArgs: [id]); return res.isNotEmpty ? Address.fromMap(res.first) : Null; } Future> getAllAddress() async { final db = await database; var res = await db.query(addressTableName); List
list = res.isNotEmpty ? res.map((c) => Address.fromMap(c)).toList() : []; return list; } Future deleteAddress(Address address) async { final db = await database; await deleteValuesByAddress(address); await deleteCountersByAddress(address); await db.delete(addressTableName, where: "id = ?", whereArgs: [address.id]); } Future updateAddress(Address address) async { final db = await database; var res = await db.update(addressTableName, address.toMap(), where: "id = ?", whereArgs: [address.id]); return res; } Future> getCountersOfAddress(Address address) async { final db = await database; var sql = 'select $countersTableName.id, $countersTableName.address_id, $countersTableName.counter_type, $countersTableName.name, 0 as value ' ' from $countersTableName ' ' where address_id=${address.id} and $countersTableName.id not in (select counter_id from $valuesTableName) ' ' union ' 'select $countersTableName.id, $countersTableName.address_id, $countersTableName.counter_type, $countersTableName.name, sum($valuesTableName.value1) + sum($valuesTableName.value2) + sum($valuesTableName.value3) as value ' ' from $countersTableName ' ' INNER JOIN $valuesTableName ON $valuesTableName.counter_id = $countersTableName.id ' ' where address_id=${address.id} ' ' group by counter_type'; var res = await db.rawQuery(sql, []); print(res); List list = res.isNotEmpty ? res.map((c) => Counter.fromMap(c)).toList() : []; return list; } Future newCounter(Counter newCounter) async { final db = await database; var res = await db.insert(countersTableName, newCounter.toMap()); return res; } Future updateCounter(Counter counter) async { final db = await database; var res = await db.update(countersTableName, counter.toMap(), where: "id = ?", whereArgs: [counter.id]); return res; } Future deleteCounter(Counter counter) async { final db = await database; await deleteValuesByCounter(counter); await db .delete(countersTableName, where: "id = ?", whereArgs: [counter.id]); } deleteCountersByAddress(Address address) async { final db = await database; await db.delete(countersTableName, where: 'address_id = ?', whereArgs: [address.id]); } Future> getValuesOfCounter(Counter counter) async { final db = await database; var res = await db.query(valuesTableName, where: "counter_id = ?", whereArgs: [counter.id]); List list = res.isNotEmpty ? res.map((v) => Value.fromMap(v)).toList() : []; return list; } Future newValue(Value newValue) async { final db = await database; var res = await db.insert(valuesTableName, newValue.toMap()); return res; } deleteValuesByAddress(Address address) async { final db = await database; await db.delete(valuesTableName, where: 'counter_id in (select id from $countersTableName where address_id = ?)', whereArgs: [address.id]); } deleteValuesByCounter(Counter counter) async { final db = await database; await db.delete(valuesTableName, where: 'counter_id = ?', whereArgs: [counter.id]); } }