You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
187 lines
6.3 KiB
187 lines
6.3 KiB
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<Database> 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<int> newAddress(Address newAddress) async { |
|
final db = await database; |
|
var res = await db.insert(addressTableName, newAddress.toMap()); |
|
return res; |
|
} |
|
|
|
Future<Object> 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<List<Address>> getAllAddress() async { |
|
final db = await database; |
|
var res = await db.query(addressTableName); |
|
List<Address> 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<List<Counter>> 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<Counter> list = |
|
res.isNotEmpty ? res.map((c) => Counter.fromMap(c)).toList() : []; |
|
return list; |
|
} |
|
|
|
Future<int> 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<List<Value>> getValuesOfCounter(Counter counter) async { |
|
final db = await database; |
|
var res = await db.query(valuesTableName, |
|
where: "counter_id = ?", whereArgs: [counter.id]); |
|
List<Value> list = |
|
res.isNotEmpty ? res.map((v) => Value.fromMap(v)).toList() : []; |
|
return list; |
|
} |
|
|
|
Future<int> 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]); |
|
} |
|
}
|
|
|