|
|
|
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]);
|
|
|
|
}
|
|
|
|
}
|