mirror of
https://gitlab.com/nkming2/nc-photos.git
synced 2025-02-02 06:46:22 +01:00
Add db api to query summary of all the files
This commit is contained in:
parent
99c8448bde
commit
97b3e99aa7
5 changed files with 173 additions and 0 deletions
|
@ -126,6 +126,31 @@ class DbLocationGroupResult {
|
|||
final List<DbLocationGroup> countryCode;
|
||||
}
|
||||
|
||||
@toString
|
||||
class DbFilesSummaryItem {
|
||||
const DbFilesSummaryItem({
|
||||
required this.count,
|
||||
});
|
||||
|
||||
@override
|
||||
String toString() => _$toString();
|
||||
|
||||
final int count;
|
||||
}
|
||||
|
||||
@toString
|
||||
class DbFilesSummary {
|
||||
const DbFilesSummary({
|
||||
required this.items,
|
||||
});
|
||||
|
||||
@override
|
||||
String toString() => _$toString();
|
||||
|
||||
@Format(r"{length: ${$?.length}}")
|
||||
final Map<DateTime, DbFilesSummaryItem> items;
|
||||
}
|
||||
|
||||
@npLog
|
||||
abstract class NpDb {
|
||||
factory NpDb() => NpDbSqlite();
|
||||
|
@ -321,9 +346,23 @@ abstract class NpDb {
|
|||
String? location,
|
||||
bool? isFavorite,
|
||||
List<String>? mimes,
|
||||
int? offset,
|
||||
int? limit,
|
||||
});
|
||||
|
||||
/// Summarize files matching some specific requirements
|
||||
///
|
||||
/// See [getFileDescriptors]
|
||||
///
|
||||
/// Returned data are sorted by [DbFileDescriptor.bestDateTime] in descending
|
||||
/// order
|
||||
Future<DbFilesSummary> getFilesSummary({
|
||||
required DbAccount account,
|
||||
List<String>? includeRelativeRoots,
|
||||
List<String>? excludeRelativeRoots,
|
||||
List<String>? mimes,
|
||||
});
|
||||
|
||||
Future<DbLocationGroupResult> groupLocations({
|
||||
required DbAccount account,
|
||||
List<String>? includeRelativeRoots,
|
||||
|
|
|
@ -37,3 +37,17 @@ extension _$DbLocationGroupResultToString on DbLocationGroupResult {
|
|||
return "DbLocationGroupResult {name: [length: ${name.length}], admin1: [length: ${admin1.length}], admin2: [length: ${admin2.length}], countryCode: [length: ${countryCode.length}]}";
|
||||
}
|
||||
}
|
||||
|
||||
extension _$DbFilesSummaryItemToString on DbFilesSummaryItem {
|
||||
String _$toString() {
|
||||
// ignore: unnecessary_string_interpolations
|
||||
return "DbFilesSummaryItem {count: $count}";
|
||||
}
|
||||
}
|
||||
|
||||
extension _$DbFilesSummaryToString on DbFilesSummary {
|
||||
String _$toString() {
|
||||
// ignore: unnecessary_string_interpolations
|
||||
return "DbFilesSummary {items: {length: ${items.length}}}";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,14 @@ class FileDescriptor {
|
|||
final DateTime bestDateTime;
|
||||
}
|
||||
|
||||
class CountFileGroupsByDateResult {
|
||||
const CountFileGroupsByDateResult({
|
||||
required this.dateCount,
|
||||
});
|
||||
|
||||
final Map<DateTime, int> dateCount;
|
||||
}
|
||||
|
||||
extension SqliteDbFileExtension on SqliteDb {
|
||||
/// Return files located inside [dir]
|
||||
Future<List<CompleteFile>> queryFilesByDirKey({
|
||||
|
@ -574,6 +582,62 @@ extension SqliteDbFileExtension on SqliteDb {
|
|||
return query.map((r) => r.read(files.fileId)!).getSingleOrNull();
|
||||
}
|
||||
|
||||
/// Count number of files per date
|
||||
Future<CountFileGroupsByDateResult> countFileGroupsByDate({
|
||||
required ByAccount account,
|
||||
List<String>? includeRelativeRoots,
|
||||
List<String>? excludeRelativeRoots,
|
||||
List<String>? mimes,
|
||||
}) async {
|
||||
_log.info(
|
||||
"[countFileGroupsByDate] "
|
||||
"includeRelativeRoots: $includeRelativeRoots, "
|
||||
"excludeRelativeRoots: $excludeRelativeRoots, "
|
||||
"mimes: $mimes",
|
||||
);
|
||||
|
||||
final count = countAll();
|
||||
final localDate = accountFiles.bestDateTime
|
||||
.modify(const DateTimeModifier.localTime())
|
||||
.date;
|
||||
final query = _queryFiles().let((q) {
|
||||
q
|
||||
..setQueryMode(
|
||||
FilesQueryMode.expression,
|
||||
expressions: [localDate, count],
|
||||
)
|
||||
..setAccount(account);
|
||||
if (includeRelativeRoots != null) {
|
||||
if (includeRelativeRoots.none((p) => p.isEmpty)) {
|
||||
for (final r in includeRelativeRoots) {
|
||||
q.byOrRelativePathPattern("$r/%");
|
||||
}
|
||||
}
|
||||
}
|
||||
return q.build();
|
||||
});
|
||||
if (excludeRelativeRoots != null) {
|
||||
for (final r in excludeRelativeRoots) {
|
||||
query.where(accountFiles.relativePath.like("$r/%").not());
|
||||
}
|
||||
}
|
||||
if (mimes != null) {
|
||||
query.where(files.contentType.isIn(mimes));
|
||||
} else {
|
||||
query.where(files.isCollection.isNotValue(true));
|
||||
}
|
||||
query
|
||||
..orderBy([OrderingTerm.desc(accountFiles.bestDateTime)])
|
||||
..groupBy([localDate]);
|
||||
final results = await query
|
||||
.map((r) => MapEntry<DateTime, int>(
|
||||
DateTime.parse(r.read(localDate)!),
|
||||
r.read(count)!,
|
||||
))
|
||||
.get();
|
||||
return CountFileGroupsByDateResult(dateCount: results.toMap());
|
||||
}
|
||||
|
||||
/// Update Db files
|
||||
///
|
||||
/// Return a list of files that are not yet inserted to the DB (thus not
|
||||
|
|
|
@ -461,6 +461,27 @@ class NpDbSqlite implements NpDb {
|
|||
return sqlObjs.toDbFileDescriptors();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<DbFilesSummary> getFilesSummary({
|
||||
required DbAccount account,
|
||||
List<String>? includeRelativeRoots,
|
||||
List<String>? excludeRelativeRoots,
|
||||
List<String>? mimes,
|
||||
}) async {
|
||||
final result = await _db.use((db) async {
|
||||
return await db.countFileGroupsByDate(
|
||||
account: ByAccount.db(account),
|
||||
includeRelativeRoots: includeRelativeRoots,
|
||||
excludeRelativeRoots: excludeRelativeRoots,
|
||||
mimes: mimes,
|
||||
);
|
||||
});
|
||||
return DbFilesSummary(
|
||||
items: result.dateCount
|
||||
.map((key, value) => MapEntry(key, DbFilesSummaryItem(count: value))),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<DbLocationGroupResult> groupLocations({
|
||||
required DbAccount account,
|
||||
|
|
|
@ -8,6 +8,7 @@ import '../test_util.dart' as util;
|
|||
void main() {
|
||||
group("database.SqliteDbFileExtension", () {
|
||||
test("cleanUpDanglingFiles", _cleanUpDanglingFiles);
|
||||
test("countFileGroupsByDate", _countFileGroupsByDate);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -46,3 +47,37 @@ Future<void> _cleanUpDanglingFiles() async {
|
|||
[0, 1],
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _countFileGroupsByDate() async {
|
||||
final account = util.buildAccount();
|
||||
final files = (util.FilesBuilder()
|
||||
..addDir("admin")
|
||||
..addJpeg(
|
||||
"admin/test1.jpg",
|
||||
lastModified: DateTime(2024, 1, 2, 3, 4, 5),
|
||||
)
|
||||
..addJpeg(
|
||||
"admin/test2.jpg",
|
||||
lastModified: DateTime(2024, 1, 2, 4, 5, 6),
|
||||
)
|
||||
..addJpeg(
|
||||
"admin/test3.jpg",
|
||||
lastModified: DateTime(2024, 1, 3, 4, 5, 6),
|
||||
))
|
||||
.build();
|
||||
final db = util.buildTestDb();
|
||||
addTearDown(() => db.close());
|
||||
await db.transaction(() async {
|
||||
await db.insertAccounts([account]);
|
||||
await util.insertFiles(db, account, files);
|
||||
});
|
||||
|
||||
final result = await db.countFileGroupsByDate(account: ByAccount.db(account));
|
||||
expect(
|
||||
result.dateCount,
|
||||
{
|
||||
DateTime(2024, 1, 2): 2,
|
||||
DateTime(2024, 1, 3): 1,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue