import 'dart:io'; import 'package:satu/core/base/base_service.dart'; import 'package:satu/core/entity/category_entity.dart'; import 'package:satu/core/entity/goods_entity.dart'; import 'package:satu/core/entity/transaction_entity.dart'; import 'package:satu/core/entity/transaction_rec_entity.dart'; import 'package:sqflite/sqflite.dart'; import 'package:path/path.dart'; import 'package:path_provider/path_provider.dart'; class DbService extends BaseService { static const _databaseName = 'AmanSatuDb.db'; static const _databaseVersion = 2; // make this a singleton class DbService._privateConstructor(); static final DbService instance = DbService._privateConstructor(); // only have a single app-wide reference to the database static Database? _database; Future get database async { return _database ?? await _initDatabase(); } // this opens the database (and creates it if it doesn't exist) Future _initDatabase() async { final Directory documentsDirectory = await getApplicationDocumentsDirectory(); final String path = join(documentsDirectory.path, _databaseName); final Database db = await openDatabase(path, version: _databaseVersion, onUpgrade: _onUpdate, onCreate: _onCreate); return db; } Future _onUpdate(Database db, int oldVersion, int newVersion) async { log.i('update from $oldVersion to $newVersion'); //Goods table await db.execute('DROP TABLE IF EXISTS $goodTableName;'); await db.execute('DROP TABLE IF EXISTS $categoryTableName;'); await db.execute('DROP TABLE IF EXISTS $transactionTableName;'); await db.execute('DROP TABLE IF EXISTS $transactionRecTableName;'); log.i('dropped tables'); _onCreate(db, newVersion); } Future _onCreate(Database db, int version) async { log.i('create tables'); //Goods table await db.execute(''' CREATE TABLE IF NOT EXISTS $goodTableName ( $GoodColumnId integer primary key unique, $GoodColumnArticul integer not null, $GoodColumnName text not null, $GoodColumnPrice real not null, $GoodColumnCategoryId integer not null, $GoodColumnEan text, $GoodColumnAppCompanyId integer, $GoodColumnOptPrice real, $GoodColumnBasePrice real, $GoodColumnDivisible integer, $GoodColumnUpdatedAt text not null ); '''); await db.execute(''' CREATE TABLE IF NOT EXISTS $categoryTableName ( $categoryColumnId integer primary key unique, $categoryColumnName text not null, $categoryColumnParentIn integer, $categoryColumnAppCompanyId integer, $categoryColumnUpdatedAt text not null ); '''); await db.execute(''' CREATE TABLE IF NOT EXISTS $transactionTableName ( $transactionColumnId integer primary key autoincrement, $transactionColumnUuid text, $transactionColumnType integer not null, $transactionColumnAppCompanyId integer not null, $transactionColumnStatus integer not null, $transactionColumnData text, $transactionColumnCreatedAt text not null, $transactionColumnUpdatedAt text not null ); '''); await db.execute(''' CREATE TABLE IF NOT EXISTS $transactionRecTableName ( $transactionRecColumnId integer primary key autoincrement, $transactionRecTransactionIdRef integer not null, $transactionRecColumnData text, $transactionRecColumnCreatedAt text not null, CONSTRAINT fk_$transactionTableName FOREIGN KEY ($transactionRecTransactionIdRef) REFERENCES $transactionTableName($transactionColumnId) ); '''); } // Inserts a row in the database where each key in the Map is a column name // and the value is the column value. The return value is the id of the // inserted row. Future insert(String table, Map row) async { final Database db = await instance.database; final int result = await db.insert(table, row); return result; } // All of the rows are returned as a list of maps, where each map is // a key-value list of columns. Future>> queryAllRows(String table) async { final Database db = await instance.database; final List> result = await db.query(table); return result; } Future>> queryRaw( String sql, List args) async { final Database db = await instance.database; final List> result = await db.rawQuery(sql, args); return result; } Future>> queryAllRowsOrderBy( String table, String orderBy) async { final Database db = await instance.database; final List> result = await db.query(table, orderBy: orderBy); return result; } Future>> queryRowsWithWhere( String table, String where, List args, {String? orderBy}) async { final Database db = await instance.database; final List> result = await db.query(table, where: where, whereArgs: args, orderBy: orderBy); return result; } Future?> queryById(String table, dynamic id, {String? idColumnName}) async { final Database db = await instance.database; final List> result = await db .query(table, where: '${idColumnName ?? 'id'} = ?', whereArgs: [id]); return result.isNotEmpty ? result.first : null; } // All of the methods (insert, query, update, delete) can also be done using // raw SQL commands. This method uses a raw query to give the row count. Future queryRowCount(String table, {String? where}) async { final Database db = await instance.database; final int? result = Sqflite.firstIntValue(await db.rawQuery( 'SELECT COUNT(*) FROM $table ${where != null ? 'where $where' : ''}')); return result; } // We are assuming here that the id column in the map is set. The other // column values will be used to update the row. Future update(String table, Map row) async { final Database db = await instance.database; final int id = row['id'] as int; final int result = await db.update(table, row, where: 'id = ?', whereArgs: [id]); return result; } // Deletes the row specified by the id. The number of affected rows is // returned. This should be 1 as long as the row exists. Future delete(String table, int id) async { final Database db = await instance.database; final int result = await db.delete(table, where: 'id = ?', whereArgs: [id]); return result; } Future deleteAll(String table) async { final Database db = await instance.database; final int result = await db.delete(table); return result; } Future deleteByWhere( String table, String where, List args) async { final Database db = await instance.database; final int result = await db.delete(table, where: where, whereArgs: args); return result; } Future close() async => instance.close(); }