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

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