mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-07-30 07:48:51 +02:00
refactor: extract shared helpers for repeated low-level patterns
Dart: - notification_service: single _details() builder replaces 13 copies of the NotificationDetails block - platform_bridge: _invokeMap() for 34 invoke+decode call sites, _cachedInvoke() unifies the three TTL/in-flight cache scaffolds - ffmpeg_service: _promoteTempOutput(), _appendCoverInputArgs(), single _writeReplayGainTags() and _convertToLossless() for the ALAC/FLAC twins - sqlite_helpers.dart: shared openAppDatabase/path-key/migration helpers for the three database classes - library_collections: parametrized wishlist/loved/favorite CRUD - extension_provider: one predicate-based replacedBuiltIn* lookup Go: - extension runtime: parseGojaHeaders/coerceGojaBody/doExtensionHTTP shared by httpGet/httpPost/httpRequest/shortcuts/fetch - exports_metadata: applyAudioMetadataToResult + successMethodJSON, APE edit path reuses audioMetadataFromEditFields - lyrics: lrclibGet() for both LRCLib fetchers - extension_store: drop hand-rolled strings helpers
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
import 'package:path/path.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:spotiflac_android/utils/logger.dart';
|
||||
import 'package:spotiflac_android/utils/path_match_keys.dart';
|
||||
import 'package:sqflite/sqflite.dart';
|
||||
|
||||
final _log = AppLogger('AppSqlite');
|
||||
|
||||
/// Opens a database file in the app documents directory with the shared
|
||||
/// WAL + synchronous=NORMAL configuration.
|
||||
Future<Database> openAppDatabase(
|
||||
String fileName, {
|
||||
required int version,
|
||||
required Future<void> Function(Database db, int version) onCreate,
|
||||
required Future<void> Function(Database db, int oldVersion, int newVersion)
|
||||
onUpgrade,
|
||||
bool foreignKeys = false,
|
||||
}) async {
|
||||
final dbPath = await getApplicationDocumentsDirectory();
|
||||
final path = join(dbPath.path, fileName);
|
||||
|
||||
_log.i('Initializing database at: $path');
|
||||
|
||||
return openDatabase(
|
||||
path,
|
||||
version: version,
|
||||
onConfigure: (db) async {
|
||||
if (foreignKeys) {
|
||||
await db.execute('PRAGMA foreign_keys = ON');
|
||||
}
|
||||
await db.rawQuery('PRAGMA journal_mode = WAL');
|
||||
await db.execute('PRAGMA synchronous = NORMAL');
|
||||
},
|
||||
onCreate: onCreate,
|
||||
onUpgrade: onUpgrade,
|
||||
);
|
||||
}
|
||||
|
||||
String normalizeLookupText(String? value) {
|
||||
return (value ?? '').trim().toLowerCase();
|
||||
}
|
||||
|
||||
Future<void> addColumnIfMissing(
|
||||
Database db,
|
||||
String table,
|
||||
String column,
|
||||
String type,
|
||||
) async {
|
||||
final columns = await db.rawQuery('PRAGMA table_info($table)');
|
||||
final exists = columns.any(
|
||||
(row) => (row['name']?.toString().toLowerCase() ?? '') == column,
|
||||
);
|
||||
if (!exists) {
|
||||
await db.execute('ALTER TABLE $table ADD COLUMN $column $type');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> createPathKeyTable(DatabaseExecutor db, String table) async {
|
||||
await db.execute('''
|
||||
CREATE TABLE IF NOT EXISTS $table (
|
||||
item_id TEXT NOT NULL,
|
||||
path_key TEXT NOT NULL,
|
||||
PRIMARY KEY (item_id, path_key)
|
||||
)
|
||||
''');
|
||||
await db.execute(
|
||||
'CREATE INDEX IF NOT EXISTS idx_${table}_key ON $table(path_key)',
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> backfillPathKeys(
|
||||
Database db,
|
||||
String sourceTable,
|
||||
String keyTable,
|
||||
) async {
|
||||
final rows = await db.query(sourceTable, columns: ['id', 'file_path']);
|
||||
final batch = db.batch();
|
||||
for (final row in rows) {
|
||||
putPathKeysInBatch(
|
||||
batch,
|
||||
keyTable,
|
||||
row['id'] as String,
|
||||
row['file_path'] as String?,
|
||||
);
|
||||
}
|
||||
await batch.commit(noResult: true);
|
||||
}
|
||||
|
||||
void putPathKeysInBatch(
|
||||
Batch batch,
|
||||
String table,
|
||||
String id,
|
||||
String? filePath,
|
||||
) {
|
||||
batch.delete(table, where: 'item_id = ?', whereArgs: [id]);
|
||||
for (final key in buildPathMatchKeys(filePath)) {
|
||||
batch.insert(table, {
|
||||
'item_id': id,
|
||||
'path_key': key,
|
||||
}, conflictAlgorithm: ConflictAlgorithm.ignore);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user