95 lines
2.6 KiB
Dart
95 lines
2.6 KiB
Dart
|
|
import 'dart:io';
|
||
|
|
|
||
|
|
import 'package:guru_utils/log/log.dart';
|
||
|
|
import 'package:path/path.dart';
|
||
|
|
import 'package:sqflite/sqflite.dart';
|
||
|
|
export 'batch/batch_data.dart';
|
||
|
|
export 'batch/batch_aware.dart';
|
||
|
|
export 'package:sqflite/sqflite.dart';
|
||
|
|
|
||
|
|
/// Created by Haoyi on 2022/8/24
|
||
|
|
///
|
||
|
|
part 'migration.dart';
|
||
|
|
|
||
|
|
|
||
|
|
typedef TableCreator = Future Function(Transaction delegate);
|
||
|
|
|
||
|
|
abstract class AppDatabase {
|
||
|
|
late Database _database;
|
||
|
|
|
||
|
|
List<TableCreator> get tableCreators;
|
||
|
|
|
||
|
|
List<Migration> get migrations;
|
||
|
|
|
||
|
|
int get version;
|
||
|
|
|
||
|
|
String get dbName;
|
||
|
|
|
||
|
|
Future<String> getTestingPath() async {
|
||
|
|
return "./mocks_dir/db";
|
||
|
|
}
|
||
|
|
|
||
|
|
Future _createTables(Database db) {
|
||
|
|
return db.transaction((Transaction delegate) async {
|
||
|
|
final List<TableCreator> creators = tableCreators;
|
||
|
|
for (var creator in creators) {
|
||
|
|
await creator(delegate);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
Future _migrate(Database database, int from, int to) async {
|
||
|
|
Log.d("MIGRATE [$from] => [$to]");
|
||
|
|
final _migrations = migrations;
|
||
|
|
return database.transaction((txn) async {
|
||
|
|
for (int index = from - 1; (index < to - 1) && (index < _migrations.length); ++index) {
|
||
|
|
var result = MigrateResult.failed;
|
||
|
|
try {
|
||
|
|
Log.d("====> BEGIN MIGRATE [${index + 1}] => [${index + 2}]");
|
||
|
|
result = await _migrations[index].migrate(txn);
|
||
|
|
} catch (error) {
|
||
|
|
Log.d(" migrate [${index + 1}] => [${index + 2}] error:[$error]");
|
||
|
|
rethrow;
|
||
|
|
}
|
||
|
|
Log.d("====> END MIGRATE [${index + 1}] => [${index + 2}] result: $result");
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
Future initDatabase() async {
|
||
|
|
final isTesting = Platform.environment.containsKey('FLUTTER_TEST');
|
||
|
|
final dbDir = isTesting ? await getTestingPath() : await getDatabasesPath();
|
||
|
|
final dbPath = join(dbDir, "$dbName.db");
|
||
|
|
Log.d("dbPath:$dbPath");
|
||
|
|
_database = await openDatabase(
|
||
|
|
dbPath,
|
||
|
|
version: version,
|
||
|
|
onCreate: (Database db, int version) async {
|
||
|
|
// When creating the db, create the table
|
||
|
|
try {
|
||
|
|
await _createTables(db);
|
||
|
|
} catch (error, stacktrace) {
|
||
|
|
Log.w("createTables error! $error", stackTrace: stacktrace);
|
||
|
|
}
|
||
|
|
},
|
||
|
|
onUpgrade: (Database db, int oldVersion, int newVersion) async {
|
||
|
|
await _migrate(db, oldVersion, newVersion);
|
||
|
|
},
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
Database getDb() {
|
||
|
|
return _database;
|
||
|
|
}
|
||
|
|
|
||
|
|
Future<T> runInTransaction<T>(Future<T> Function(Transaction txn) action) {
|
||
|
|
return getDb().transaction(action);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
extension DatabaseExt on AppDatabase {
|
||
|
|
String joinTextValue(List<String> value, [String separator = ""]) {
|
||
|
|
return value.map((str) => "'$str'").toList().join(separator);
|
||
|
|
}
|
||
|
|
}
|