nc-photos/app/lib/use_case/find_file.dart
Ming Ming 8ce0125879 Limit number of async queries to be fired at the same time
While the plugin can handle this no problem, the dart side will get stuck when all the results come in over a tiny period of time
2022-05-28 14:38:11 +08:00

55 lines
1.7 KiB
Dart

import 'package:idb_shim/idb_client.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/app_db.dart';
import 'package:nc_photos/di_container.dart';
import 'package:nc_photos/entity/file.dart';
import 'package:nc_photos/iterable_extension.dart';
import 'package:nc_photos/k.dart' as k;
import 'package:quiver/iterables.dart';
class FindFile {
FindFile(this._c) : assert(require(_c));
static bool require(DiContainer c) => DiContainer.has(c, DiType.appDb);
/// Find list of files in the DB by [fileIds]
///
/// If an id is not found, [onFileNotFound] will be called. If
/// [onFileNotFound] is null, a [StateError] will be thrown
Future<List<File>> call(
Account account,
List<int> fileIds, {
void Function(int fileId)? onFileNotFound,
}) async {
final dbItems = await _c.appDb.use(
(db) => db.transaction(AppDb.file2StoreName, idbModeReadOnly),
(transaction) async {
final fileStore = transaction.objectStore(AppDb.file2StoreName);
return await fileIds
.mapStream(
(id) => fileStore
.getObject(AppDbFile2Entry.toPrimaryKey(account, id)),
k.simultaneousQuery)
.toList();
},
);
final files = <File>[];
for (final pair in zip([fileIds, dbItems])) {
final dbItem = pair[1] as Map?;
if (dbItem == null) {
if (onFileNotFound == null) {
throw StateError("File ID not found: ${pair[0]}");
} else {
onFileNotFound(pair[0] as int);
}
} else {
final dbEntry =
AppDbFile2Entry.fromJson(dbItem.cast<String, dynamic>());
files.add(dbEntry.file);
}
}
return files;
}
final DiContainer _c;
}