mirror of
https://github.com/immich-app/immich.git
synced 2025-08-11 09:16:31 -04:00
feat: use sqlite for logging (#20414)
* feat: use drift for logging * fix: tests * feat: use the truncate limit from constants.ts as default * chore: move setupAll to top level and restructure * chore: code review changes * fix: inherits * feat: raise log line limit to 2000 * limit getAll to 250 lines * delete DLog and make LogRepository not a singleton * fix: drift build settings and `make migration` * fix: tests * remove sensitive log --------- Co-authored-by: Alex <alex.tran1502@gmail.com>
This commit is contained in:
parent
f2067221c5
commit
3cd7f5ab90
@ -19,6 +19,7 @@ targets:
|
|||||||
- lib/infrastructure/entities/*.dart
|
- lib/infrastructure/entities/*.dart
|
||||||
- lib/infrastructure/entities/*.drift
|
- lib/infrastructure/entities/*.drift
|
||||||
- lib/infrastructure/repositories/db.repository.dart
|
- lib/infrastructure/repositories/db.repository.dart
|
||||||
|
- lib/infrastructure/repositories/logger_db.repository.dart
|
||||||
drift_dev:modular:
|
drift_dev:modular:
|
||||||
enabled: true
|
enabled: true
|
||||||
options: *drift_options
|
options: *drift_options
|
||||||
|
@ -3,7 +3,7 @@ const double downloadCompleted = -1;
|
|||||||
const double downloadFailed = -2;
|
const double downloadFailed = -2;
|
||||||
|
|
||||||
// Number of log entries to retain on app start
|
// Number of log entries to retain on app start
|
||||||
const int kLogTruncateLimit = 250;
|
const int kLogTruncateLimit = 2000;
|
||||||
|
|
||||||
// Sync
|
// Sync
|
||||||
const int kSyncEventBatchSize = 5000;
|
const int kSyncEventBatchSize = 5000;
|
||||||
|
@ -6,7 +6,6 @@ import 'package:immich_mobile/infrastructure/repositories/local_album.repository
|
|||||||
import 'package:immich_mobile/infrastructure/repositories/local_asset.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/local_asset.repository.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/storage.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/storage.repository.dart';
|
||||||
import 'package:immich_mobile/platform/native_sync_api.g.dart';
|
import 'package:immich_mobile/platform/native_sync_api.g.dart';
|
||||||
import 'package:immich_mobile/presentation/pages/dev/dev_logger.dart';
|
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
|
|
||||||
class HashService {
|
class HashService {
|
||||||
@ -46,7 +45,6 @@ class HashService {
|
|||||||
|
|
||||||
stopwatch.stop();
|
stopwatch.stop();
|
||||||
_log.info("Hashing took - ${stopwatch.elapsedMilliseconds}ms");
|
_log.info("Hashing took - ${stopwatch.elapsedMilliseconds}ms");
|
||||||
DLog.log("Hashing took - ${stopwatch.elapsedMilliseconds}ms");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Processes a list of [LocalAsset]s, storing their hash and updating the assets in the DB
|
/// Processes a list of [LocalAsset]s, storing their hash and updating the assets in the DB
|
||||||
@ -101,7 +99,6 @@ class HashService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_log.fine("Hashed ${hashed.length}/${toHash.length} assets");
|
_log.fine("Hashed ${hashed.length}/${toHash.length} assets");
|
||||||
DLog.log("Hashed ${hashed.length}/${toHash.length} assets");
|
|
||||||
|
|
||||||
await _localAssetRepository.updateHashes(hashed);
|
await _localAssetRepository.updateHashes(hashed);
|
||||||
await _storageRepository.clearCache();
|
await _storageRepository.clearCache();
|
||||||
|
@ -6,7 +6,6 @@ import 'package:immich_mobile/domain/models/album/local_album.model.dart';
|
|||||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/local_album.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/local_album.repository.dart';
|
||||||
import 'package:immich_mobile/platform/native_sync_api.g.dart';
|
import 'package:immich_mobile/platform/native_sync_api.g.dart';
|
||||||
import 'package:immich_mobile/presentation/pages/dev/dev_logger.dart';
|
|
||||||
import 'package:immich_mobile/utils/diff.dart';
|
import 'package:immich_mobile/utils/diff.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:platform/platform.dart';
|
import 'package:platform/platform.dart';
|
||||||
@ -30,19 +29,17 @@ class LocalSyncService {
|
|||||||
try {
|
try {
|
||||||
if (full || await _nativeSyncApi.shouldFullSync()) {
|
if (full || await _nativeSyncApi.shouldFullSync()) {
|
||||||
_log.fine("Full sync request from ${full ? "user" : "native"}");
|
_log.fine("Full sync request from ${full ? "user" : "native"}");
|
||||||
DLog.log("Full sync request from ${full ? "user" : "native"}");
|
|
||||||
return await fullSync();
|
return await fullSync();
|
||||||
}
|
}
|
||||||
|
|
||||||
final delta = await _nativeSyncApi.getMediaChanges();
|
final delta = await _nativeSyncApi.getMediaChanges();
|
||||||
if (!delta.hasChanges) {
|
if (!delta.hasChanges) {
|
||||||
_log.fine("No media changes detected. Skipping sync");
|
_log.fine("No media changes detected. Skipping sync");
|
||||||
DLog.log("No media changes detected. Skipping sync");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DLog.log("Delta updated: ${delta.updates.length}");
|
_log.fine("Delta updated: ${delta.updates.length}");
|
||||||
DLog.log("Delta deleted: ${delta.deletes.length}");
|
_log.fine("Delta deleted: ${delta.deletes.length}");
|
||||||
|
|
||||||
final deviceAlbums = await _nativeSyncApi.getAlbums();
|
final deviceAlbums = await _nativeSyncApi.getAlbums();
|
||||||
await _localAlbumRepository.updateAll(deviceAlbums.toLocalAlbums());
|
await _localAlbumRepository.updateAll(deviceAlbums.toLocalAlbums());
|
||||||
@ -83,7 +80,6 @@ class LocalSyncService {
|
|||||||
} finally {
|
} finally {
|
||||||
stopwatch.stop();
|
stopwatch.stop();
|
||||||
_log.info("Device sync took - ${stopwatch.elapsedMilliseconds}ms");
|
_log.info("Device sync took - ${stopwatch.elapsedMilliseconds}ms");
|
||||||
DLog.log("Device sync took - ${stopwatch.elapsedMilliseconds}ms");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,7 +102,6 @@ class LocalSyncService {
|
|||||||
await _nativeSyncApi.checkpointSync();
|
await _nativeSyncApi.checkpointSync();
|
||||||
stopwatch.stop();
|
stopwatch.stop();
|
||||||
_log.info("Full device sync took - ${stopwatch.elapsedMilliseconds}ms");
|
_log.info("Full device sync took - ${stopwatch.elapsedMilliseconds}ms");
|
||||||
DLog.log("Full device sync took - ${stopwatch.elapsedMilliseconds}ms");
|
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
_log.severe("Error performing full device sync", e, s);
|
_log.severe("Error performing full device sync", e, s);
|
||||||
}
|
}
|
||||||
@ -150,7 +145,6 @@ class LocalSyncService {
|
|||||||
// Faster path - only new assets added
|
// Faster path - only new assets added
|
||||||
if (await checkAddition(dbAlbum, deviceAlbum)) {
|
if (await checkAddition(dbAlbum, deviceAlbum)) {
|
||||||
_log.fine("Fast synced device album ${dbAlbum.name}");
|
_log.fine("Fast synced device album ${dbAlbum.name}");
|
||||||
DLog.log("Fast synced device album ${dbAlbum.name}");
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ import 'package:logging/logging.dart';
|
|||||||
/// writes them to a persistent [ILogRepository], and manages log levels
|
/// writes them to a persistent [ILogRepository], and manages log levels
|
||||||
/// via [IStoreRepository]
|
/// via [IStoreRepository]
|
||||||
class LogService {
|
class LogService {
|
||||||
final IsarLogRepository _logRepository;
|
final LogRepository _logRepository;
|
||||||
final IsarStoreRepository _storeRepository;
|
final IsarStoreRepository _storeRepository;
|
||||||
|
|
||||||
final List<LogMessage> _msgBuffer = [];
|
final List<LogMessage> _msgBuffer = [];
|
||||||
@ -37,7 +37,7 @@ class LogService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Future<LogService> init({
|
static Future<LogService> init({
|
||||||
required IsarLogRepository logRepository,
|
required LogRepository logRepository,
|
||||||
required IsarStoreRepository storeRepository,
|
required IsarStoreRepository storeRepository,
|
||||||
bool shouldBuffer = true,
|
bool shouldBuffer = true,
|
||||||
}) async {
|
}) async {
|
||||||
@ -50,7 +50,7 @@ class LogService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Future<LogService> create({
|
static Future<LogService> create({
|
||||||
required IsarLogRepository logRepository,
|
required LogRepository logRepository,
|
||||||
required IsarStoreRepository storeRepository,
|
required IsarStoreRepository storeRepository,
|
||||||
bool shouldBuffer = true,
|
bool shouldBuffer = true,
|
||||||
}) async {
|
}) async {
|
||||||
@ -85,7 +85,7 @@ class LogService {
|
|||||||
|
|
||||||
if (_shouldBuffer) {
|
if (_shouldBuffer) {
|
||||||
_msgBuffer.add(record);
|
_msgBuffer.add(record);
|
||||||
_flushTimer ??= Timer(const Duration(seconds: 5), () => unawaited(flushBuffer()));
|
_flushTimer ??= Timer(const Duration(seconds: 5), () => unawaited(_flushBuffer()));
|
||||||
} else {
|
} else {
|
||||||
unawaited(_logRepository.insert(record));
|
unawaited(_logRepository.insert(record));
|
||||||
}
|
}
|
||||||
@ -108,20 +108,18 @@ class LogService {
|
|||||||
await _logRepository.deleteAll();
|
await _logRepository.deleteAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
void flush() {
|
Future<void> flush() {
|
||||||
_flushTimer?.cancel();
|
_flushTimer?.cancel();
|
||||||
// TODO: Rename enable this after moving to sqlite - #16504
|
return _flushBuffer();
|
||||||
// await _flushBufferToDatabase();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> dispose() {
|
Future<void> dispose() {
|
||||||
_flushTimer?.cancel();
|
_flushTimer?.cancel();
|
||||||
_logSubscription.cancel();
|
_logSubscription.cancel();
|
||||||
return flushBuffer();
|
return _flushBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TOOD: Move this to private once Isar is removed
|
Future<void> _flushBuffer() async {
|
||||||
Future<void> flushBuffer() async {
|
|
||||||
_flushTimer = null;
|
_flushTimer = null;
|
||||||
final buffer = [..._msgBuffer];
|
final buffer = [..._msgBuffer];
|
||||||
_msgBuffer.clear();
|
_msgBuffer.clear();
|
||||||
|
@ -3,7 +3,6 @@ import 'dart:async';
|
|||||||
import 'package:immich_mobile/domain/models/sync_event.model.dart';
|
import 'package:immich_mobile/domain/models/sync_event.model.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/sync_api.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/sync_api.repository.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/sync_stream.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/sync_stream.repository.dart';
|
||||||
import 'package:immich_mobile/presentation/pages/dev/dev_logger.dart';
|
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:openapi/api.dart';
|
import 'package:openapi/api.dart';
|
||||||
|
|
||||||
@ -26,7 +25,6 @@ class SyncStreamService {
|
|||||||
|
|
||||||
Future<void> sync() {
|
Future<void> sync() {
|
||||||
_logger.info("Remote sync request for user");
|
_logger.info("Remote sync request for user");
|
||||||
DLog.log("Remote sync request for user");
|
|
||||||
// Start the sync stream and handle events
|
// Start the sync stream and handle events
|
||||||
return _syncApiRepository.streamChanges(_handleEvents);
|
return _syncApiRepository.streamChanges(_handleEvents);
|
||||||
}
|
}
|
||||||
|
@ -1,47 +1,29 @@
|
|||||||
import 'package:immich_mobile/domain/models/log.model.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:immich_mobile/infrastructure/entities/log.entity.drift.dart';
|
||||||
|
import 'package:immich_mobile/domain/models/log.model.dart' as domain;
|
||||||
|
|
||||||
part 'log.entity.g.dart';
|
class LogMessageEntity extends Table {
|
||||||
|
const LogMessageEntity();
|
||||||
|
|
||||||
@Collection(inheritance: false)
|
@override
|
||||||
class LoggerMessage {
|
String get tableName => 'logger_messages';
|
||||||
final Id id = Isar.autoIncrement;
|
|
||||||
final String message;
|
|
||||||
final String? details;
|
|
||||||
@Enumerated(EnumType.ordinal)
|
|
||||||
final LogLevel level;
|
|
||||||
final DateTime createdAt;
|
|
||||||
final String? context1;
|
|
||||||
final String? context2;
|
|
||||||
|
|
||||||
const LoggerMessage({
|
IntColumn get id => integer().autoIncrement()();
|
||||||
required this.message,
|
TextColumn get message => text()();
|
||||||
required this.details,
|
TextColumn get details => text().nullable()();
|
||||||
this.level = LogLevel.info,
|
IntColumn get level => intEnum<domain.LogLevel>()();
|
||||||
required this.createdAt,
|
DateTimeColumn get createdAt => dateTime()();
|
||||||
required this.context1,
|
TextColumn get logger => text().nullable()();
|
||||||
required this.context2,
|
TextColumn get stack => text().nullable()();
|
||||||
});
|
}
|
||||||
|
|
||||||
LogMessage toDto() {
|
extension LogMessageEntityDataDomainEx on LogMessageEntityData {
|
||||||
return LogMessage(
|
domain.LogMessage toDto() => domain.LogMessage(
|
||||||
message: message,
|
message: message,
|
||||||
level: level,
|
level: level,
|
||||||
createdAt: createdAt,
|
createdAt: createdAt,
|
||||||
logger: context1,
|
logger: logger,
|
||||||
error: details,
|
error: details,
|
||||||
stack: context2,
|
stack: stack,
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
static LoggerMessage fromDto(LogMessage log) {
|
|
||||||
return LoggerMessage(
|
|
||||||
message: log.message,
|
|
||||||
details: log.error,
|
|
||||||
level: log.level,
|
|
||||||
createdAt: log.createdAt,
|
|
||||||
context1: log.logger,
|
|
||||||
context2: log.stack,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
697
mobile/lib/infrastructure/entities/log.entity.drift.dart
generated
Normal file
697
mobile/lib/infrastructure/entities/log.entity.drift.dart
generated
Normal file
@ -0,0 +1,697 @@
|
|||||||
|
// dart format width=80
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
import 'package:drift/drift.dart' as i0;
|
||||||
|
import 'package:immich_mobile/infrastructure/entities/log.entity.drift.dart'
|
||||||
|
as i1;
|
||||||
|
import 'package:immich_mobile/domain/models/log.model.dart' as i2;
|
||||||
|
import 'package:immich_mobile/infrastructure/entities/log.entity.dart' as i3;
|
||||||
|
|
||||||
|
typedef $$LogMessageEntityTableCreateCompanionBuilder =
|
||||||
|
i1.LogMessageEntityCompanion Function({
|
||||||
|
i0.Value<int> id,
|
||||||
|
required String message,
|
||||||
|
i0.Value<String?> details,
|
||||||
|
required i2.LogLevel level,
|
||||||
|
required DateTime createdAt,
|
||||||
|
i0.Value<String?> logger,
|
||||||
|
i0.Value<String?> stack,
|
||||||
|
});
|
||||||
|
typedef $$LogMessageEntityTableUpdateCompanionBuilder =
|
||||||
|
i1.LogMessageEntityCompanion Function({
|
||||||
|
i0.Value<int> id,
|
||||||
|
i0.Value<String> message,
|
||||||
|
i0.Value<String?> details,
|
||||||
|
i0.Value<i2.LogLevel> level,
|
||||||
|
i0.Value<DateTime> createdAt,
|
||||||
|
i0.Value<String?> logger,
|
||||||
|
i0.Value<String?> stack,
|
||||||
|
});
|
||||||
|
|
||||||
|
class $$LogMessageEntityTableFilterComposer
|
||||||
|
extends i0.Composer<i0.GeneratedDatabase, i1.$LogMessageEntityTable> {
|
||||||
|
$$LogMessageEntityTableFilterComposer({
|
||||||
|
required super.$db,
|
||||||
|
required super.$table,
|
||||||
|
super.joinBuilder,
|
||||||
|
super.$addJoinBuilderToRootComposer,
|
||||||
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
i0.ColumnFilters<int> get id => $composableBuilder(
|
||||||
|
column: $table.id,
|
||||||
|
builder: (column) => i0.ColumnFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
i0.ColumnFilters<String> get message => $composableBuilder(
|
||||||
|
column: $table.message,
|
||||||
|
builder: (column) => i0.ColumnFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
i0.ColumnFilters<String> get details => $composableBuilder(
|
||||||
|
column: $table.details,
|
||||||
|
builder: (column) => i0.ColumnFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
i0.ColumnWithTypeConverterFilters<i2.LogLevel, i2.LogLevel, int> get level =>
|
||||||
|
$composableBuilder(
|
||||||
|
column: $table.level,
|
||||||
|
builder: (column) => i0.ColumnWithTypeConverterFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
i0.ColumnFilters<DateTime> get createdAt => $composableBuilder(
|
||||||
|
column: $table.createdAt,
|
||||||
|
builder: (column) => i0.ColumnFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
i0.ColumnFilters<String> get logger => $composableBuilder(
|
||||||
|
column: $table.logger,
|
||||||
|
builder: (column) => i0.ColumnFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
i0.ColumnFilters<String> get stack => $composableBuilder(
|
||||||
|
column: $table.stack,
|
||||||
|
builder: (column) => i0.ColumnFilters(column),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class $$LogMessageEntityTableOrderingComposer
|
||||||
|
extends i0.Composer<i0.GeneratedDatabase, i1.$LogMessageEntityTable> {
|
||||||
|
$$LogMessageEntityTableOrderingComposer({
|
||||||
|
required super.$db,
|
||||||
|
required super.$table,
|
||||||
|
super.joinBuilder,
|
||||||
|
super.$addJoinBuilderToRootComposer,
|
||||||
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
i0.ColumnOrderings<int> get id => $composableBuilder(
|
||||||
|
column: $table.id,
|
||||||
|
builder: (column) => i0.ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
i0.ColumnOrderings<String> get message => $composableBuilder(
|
||||||
|
column: $table.message,
|
||||||
|
builder: (column) => i0.ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
i0.ColumnOrderings<String> get details => $composableBuilder(
|
||||||
|
column: $table.details,
|
||||||
|
builder: (column) => i0.ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
i0.ColumnOrderings<int> get level => $composableBuilder(
|
||||||
|
column: $table.level,
|
||||||
|
builder: (column) => i0.ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
i0.ColumnOrderings<DateTime> get createdAt => $composableBuilder(
|
||||||
|
column: $table.createdAt,
|
||||||
|
builder: (column) => i0.ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
i0.ColumnOrderings<String> get logger => $composableBuilder(
|
||||||
|
column: $table.logger,
|
||||||
|
builder: (column) => i0.ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
i0.ColumnOrderings<String> get stack => $composableBuilder(
|
||||||
|
column: $table.stack,
|
||||||
|
builder: (column) => i0.ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class $$LogMessageEntityTableAnnotationComposer
|
||||||
|
extends i0.Composer<i0.GeneratedDatabase, i1.$LogMessageEntityTable> {
|
||||||
|
$$LogMessageEntityTableAnnotationComposer({
|
||||||
|
required super.$db,
|
||||||
|
required super.$table,
|
||||||
|
super.joinBuilder,
|
||||||
|
super.$addJoinBuilderToRootComposer,
|
||||||
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
i0.GeneratedColumn<int> get id =>
|
||||||
|
$composableBuilder(column: $table.id, builder: (column) => column);
|
||||||
|
|
||||||
|
i0.GeneratedColumn<String> get message =>
|
||||||
|
$composableBuilder(column: $table.message, builder: (column) => column);
|
||||||
|
|
||||||
|
i0.GeneratedColumn<String> get details =>
|
||||||
|
$composableBuilder(column: $table.details, builder: (column) => column);
|
||||||
|
|
||||||
|
i0.GeneratedColumnWithTypeConverter<i2.LogLevel, int> get level =>
|
||||||
|
$composableBuilder(column: $table.level, builder: (column) => column);
|
||||||
|
|
||||||
|
i0.GeneratedColumn<DateTime> get createdAt =>
|
||||||
|
$composableBuilder(column: $table.createdAt, builder: (column) => column);
|
||||||
|
|
||||||
|
i0.GeneratedColumn<String> get logger =>
|
||||||
|
$composableBuilder(column: $table.logger, builder: (column) => column);
|
||||||
|
|
||||||
|
i0.GeneratedColumn<String> get stack =>
|
||||||
|
$composableBuilder(column: $table.stack, builder: (column) => column);
|
||||||
|
}
|
||||||
|
|
||||||
|
class $$LogMessageEntityTableTableManager
|
||||||
|
extends
|
||||||
|
i0.RootTableManager<
|
||||||
|
i0.GeneratedDatabase,
|
||||||
|
i1.$LogMessageEntityTable,
|
||||||
|
i1.LogMessageEntityData,
|
||||||
|
i1.$$LogMessageEntityTableFilterComposer,
|
||||||
|
i1.$$LogMessageEntityTableOrderingComposer,
|
||||||
|
i1.$$LogMessageEntityTableAnnotationComposer,
|
||||||
|
$$LogMessageEntityTableCreateCompanionBuilder,
|
||||||
|
$$LogMessageEntityTableUpdateCompanionBuilder,
|
||||||
|
(
|
||||||
|
i1.LogMessageEntityData,
|
||||||
|
i0.BaseReferences<
|
||||||
|
i0.GeneratedDatabase,
|
||||||
|
i1.$LogMessageEntityTable,
|
||||||
|
i1.LogMessageEntityData
|
||||||
|
>,
|
||||||
|
),
|
||||||
|
i1.LogMessageEntityData,
|
||||||
|
i0.PrefetchHooks Function()
|
||||||
|
> {
|
||||||
|
$$LogMessageEntityTableTableManager(
|
||||||
|
i0.GeneratedDatabase db,
|
||||||
|
i1.$LogMessageEntityTable table,
|
||||||
|
) : super(
|
||||||
|
i0.TableManagerState(
|
||||||
|
db: db,
|
||||||
|
table: table,
|
||||||
|
createFilteringComposer: () =>
|
||||||
|
i1.$$LogMessageEntityTableFilterComposer($db: db, $table: table),
|
||||||
|
createOrderingComposer: () => i1
|
||||||
|
.$$LogMessageEntityTableOrderingComposer($db: db, $table: table),
|
||||||
|
createComputedFieldComposer: () =>
|
||||||
|
i1.$$LogMessageEntityTableAnnotationComposer(
|
||||||
|
$db: db,
|
||||||
|
$table: table,
|
||||||
|
),
|
||||||
|
updateCompanionCallback:
|
||||||
|
({
|
||||||
|
i0.Value<int> id = const i0.Value.absent(),
|
||||||
|
i0.Value<String> message = const i0.Value.absent(),
|
||||||
|
i0.Value<String?> details = const i0.Value.absent(),
|
||||||
|
i0.Value<i2.LogLevel> level = const i0.Value.absent(),
|
||||||
|
i0.Value<DateTime> createdAt = const i0.Value.absent(),
|
||||||
|
i0.Value<String?> logger = const i0.Value.absent(),
|
||||||
|
i0.Value<String?> stack = const i0.Value.absent(),
|
||||||
|
}) => i1.LogMessageEntityCompanion(
|
||||||
|
id: id,
|
||||||
|
message: message,
|
||||||
|
details: details,
|
||||||
|
level: level,
|
||||||
|
createdAt: createdAt,
|
||||||
|
logger: logger,
|
||||||
|
stack: stack,
|
||||||
|
),
|
||||||
|
createCompanionCallback:
|
||||||
|
({
|
||||||
|
i0.Value<int> id = const i0.Value.absent(),
|
||||||
|
required String message,
|
||||||
|
i0.Value<String?> details = const i0.Value.absent(),
|
||||||
|
required i2.LogLevel level,
|
||||||
|
required DateTime createdAt,
|
||||||
|
i0.Value<String?> logger = const i0.Value.absent(),
|
||||||
|
i0.Value<String?> stack = const i0.Value.absent(),
|
||||||
|
}) => i1.LogMessageEntityCompanion.insert(
|
||||||
|
id: id,
|
||||||
|
message: message,
|
||||||
|
details: details,
|
||||||
|
level: level,
|
||||||
|
createdAt: createdAt,
|
||||||
|
logger: logger,
|
||||||
|
stack: stack,
|
||||||
|
),
|
||||||
|
withReferenceMapper: (p0) => p0
|
||||||
|
.map((e) => (e.readTable(table), i0.BaseReferences(db, table, e)))
|
||||||
|
.toList(),
|
||||||
|
prefetchHooksCallback: null,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef $$LogMessageEntityTableProcessedTableManager =
|
||||||
|
i0.ProcessedTableManager<
|
||||||
|
i0.GeneratedDatabase,
|
||||||
|
i1.$LogMessageEntityTable,
|
||||||
|
i1.LogMessageEntityData,
|
||||||
|
i1.$$LogMessageEntityTableFilterComposer,
|
||||||
|
i1.$$LogMessageEntityTableOrderingComposer,
|
||||||
|
i1.$$LogMessageEntityTableAnnotationComposer,
|
||||||
|
$$LogMessageEntityTableCreateCompanionBuilder,
|
||||||
|
$$LogMessageEntityTableUpdateCompanionBuilder,
|
||||||
|
(
|
||||||
|
i1.LogMessageEntityData,
|
||||||
|
i0.BaseReferences<
|
||||||
|
i0.GeneratedDatabase,
|
||||||
|
i1.$LogMessageEntityTable,
|
||||||
|
i1.LogMessageEntityData
|
||||||
|
>,
|
||||||
|
),
|
||||||
|
i1.LogMessageEntityData,
|
||||||
|
i0.PrefetchHooks Function()
|
||||||
|
>;
|
||||||
|
|
||||||
|
class $LogMessageEntityTable extends i3.LogMessageEntity
|
||||||
|
with i0.TableInfo<$LogMessageEntityTable, i1.LogMessageEntityData> {
|
||||||
|
@override
|
||||||
|
final i0.GeneratedDatabase attachedDatabase;
|
||||||
|
final String? _alias;
|
||||||
|
$LogMessageEntityTable(this.attachedDatabase, [this._alias]);
|
||||||
|
static const i0.VerificationMeta _idMeta = const i0.VerificationMeta('id');
|
||||||
|
@override
|
||||||
|
late final i0.GeneratedColumn<int> id = i0.GeneratedColumn<int>(
|
||||||
|
'id',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
hasAutoIncrement: true,
|
||||||
|
type: i0.DriftSqlType.int,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
defaultConstraints: i0.GeneratedColumn.constraintIsAlways(
|
||||||
|
'PRIMARY KEY AUTOINCREMENT',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
static const i0.VerificationMeta _messageMeta = const i0.VerificationMeta(
|
||||||
|
'message',
|
||||||
|
);
|
||||||
|
@override
|
||||||
|
late final i0.GeneratedColumn<String> message = i0.GeneratedColumn<String>(
|
||||||
|
'message',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
type: i0.DriftSqlType.string,
|
||||||
|
requiredDuringInsert: true,
|
||||||
|
);
|
||||||
|
static const i0.VerificationMeta _detailsMeta = const i0.VerificationMeta(
|
||||||
|
'details',
|
||||||
|
);
|
||||||
|
@override
|
||||||
|
late final i0.GeneratedColumn<String> details = i0.GeneratedColumn<String>(
|
||||||
|
'details',
|
||||||
|
aliasedName,
|
||||||
|
true,
|
||||||
|
type: i0.DriftSqlType.string,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
);
|
||||||
|
@override
|
||||||
|
late final i0.GeneratedColumnWithTypeConverter<i2.LogLevel, int> level =
|
||||||
|
i0.GeneratedColumn<int>(
|
||||||
|
'level',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
type: i0.DriftSqlType.int,
|
||||||
|
requiredDuringInsert: true,
|
||||||
|
).withConverter<i2.LogLevel>(i1.$LogMessageEntityTable.$converterlevel);
|
||||||
|
static const i0.VerificationMeta _createdAtMeta = const i0.VerificationMeta(
|
||||||
|
'createdAt',
|
||||||
|
);
|
||||||
|
@override
|
||||||
|
late final i0.GeneratedColumn<DateTime> createdAt =
|
||||||
|
i0.GeneratedColumn<DateTime>(
|
||||||
|
'created_at',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
type: i0.DriftSqlType.dateTime,
|
||||||
|
requiredDuringInsert: true,
|
||||||
|
);
|
||||||
|
static const i0.VerificationMeta _loggerMeta = const i0.VerificationMeta(
|
||||||
|
'logger',
|
||||||
|
);
|
||||||
|
@override
|
||||||
|
late final i0.GeneratedColumn<String> logger = i0.GeneratedColumn<String>(
|
||||||
|
'logger',
|
||||||
|
aliasedName,
|
||||||
|
true,
|
||||||
|
type: i0.DriftSqlType.string,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
);
|
||||||
|
static const i0.VerificationMeta _stackMeta = const i0.VerificationMeta(
|
||||||
|
'stack',
|
||||||
|
);
|
||||||
|
@override
|
||||||
|
late final i0.GeneratedColumn<String> stack = i0.GeneratedColumn<String>(
|
||||||
|
'stack',
|
||||||
|
aliasedName,
|
||||||
|
true,
|
||||||
|
type: i0.DriftSqlType.string,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
);
|
||||||
|
@override
|
||||||
|
List<i0.GeneratedColumn> get $columns => [
|
||||||
|
id,
|
||||||
|
message,
|
||||||
|
details,
|
||||||
|
level,
|
||||||
|
createdAt,
|
||||||
|
logger,
|
||||||
|
stack,
|
||||||
|
];
|
||||||
|
@override
|
||||||
|
String get aliasedName => _alias ?? actualTableName;
|
||||||
|
@override
|
||||||
|
String get actualTableName => $name;
|
||||||
|
static const String $name = 'logger_messages';
|
||||||
|
@override
|
||||||
|
i0.VerificationContext validateIntegrity(
|
||||||
|
i0.Insertable<i1.LogMessageEntityData> instance, {
|
||||||
|
bool isInserting = false,
|
||||||
|
}) {
|
||||||
|
final context = i0.VerificationContext();
|
||||||
|
final data = instance.toColumns(true);
|
||||||
|
if (data.containsKey('id')) {
|
||||||
|
context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta));
|
||||||
|
}
|
||||||
|
if (data.containsKey('message')) {
|
||||||
|
context.handle(
|
||||||
|
_messageMeta,
|
||||||
|
message.isAcceptableOrUnknown(data['message']!, _messageMeta),
|
||||||
|
);
|
||||||
|
} else if (isInserting) {
|
||||||
|
context.missing(_messageMeta);
|
||||||
|
}
|
||||||
|
if (data.containsKey('details')) {
|
||||||
|
context.handle(
|
||||||
|
_detailsMeta,
|
||||||
|
details.isAcceptableOrUnknown(data['details']!, _detailsMeta),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (data.containsKey('created_at')) {
|
||||||
|
context.handle(
|
||||||
|
_createdAtMeta,
|
||||||
|
createdAt.isAcceptableOrUnknown(data['created_at']!, _createdAtMeta),
|
||||||
|
);
|
||||||
|
} else if (isInserting) {
|
||||||
|
context.missing(_createdAtMeta);
|
||||||
|
}
|
||||||
|
if (data.containsKey('logger')) {
|
||||||
|
context.handle(
|
||||||
|
_loggerMeta,
|
||||||
|
logger.isAcceptableOrUnknown(data['logger']!, _loggerMeta),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (data.containsKey('stack')) {
|
||||||
|
context.handle(
|
||||||
|
_stackMeta,
|
||||||
|
stack.isAcceptableOrUnknown(data['stack']!, _stackMeta),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Set<i0.GeneratedColumn> get $primaryKey => {id};
|
||||||
|
@override
|
||||||
|
i1.LogMessageEntityData map(
|
||||||
|
Map<String, dynamic> data, {
|
||||||
|
String? tablePrefix,
|
||||||
|
}) {
|
||||||
|
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
|
||||||
|
return i1.LogMessageEntityData(
|
||||||
|
id: attachedDatabase.typeMapping.read(
|
||||||
|
i0.DriftSqlType.int,
|
||||||
|
data['${effectivePrefix}id'],
|
||||||
|
)!,
|
||||||
|
message: attachedDatabase.typeMapping.read(
|
||||||
|
i0.DriftSqlType.string,
|
||||||
|
data['${effectivePrefix}message'],
|
||||||
|
)!,
|
||||||
|
details: attachedDatabase.typeMapping.read(
|
||||||
|
i0.DriftSqlType.string,
|
||||||
|
data['${effectivePrefix}details'],
|
||||||
|
),
|
||||||
|
level: i1.$LogMessageEntityTable.$converterlevel.fromSql(
|
||||||
|
attachedDatabase.typeMapping.read(
|
||||||
|
i0.DriftSqlType.int,
|
||||||
|
data['${effectivePrefix}level'],
|
||||||
|
)!,
|
||||||
|
),
|
||||||
|
createdAt: attachedDatabase.typeMapping.read(
|
||||||
|
i0.DriftSqlType.dateTime,
|
||||||
|
data['${effectivePrefix}created_at'],
|
||||||
|
)!,
|
||||||
|
logger: attachedDatabase.typeMapping.read(
|
||||||
|
i0.DriftSqlType.string,
|
||||||
|
data['${effectivePrefix}logger'],
|
||||||
|
),
|
||||||
|
stack: attachedDatabase.typeMapping.read(
|
||||||
|
i0.DriftSqlType.string,
|
||||||
|
data['${effectivePrefix}stack'],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
$LogMessageEntityTable createAlias(String alias) {
|
||||||
|
return $LogMessageEntityTable(attachedDatabase, alias);
|
||||||
|
}
|
||||||
|
|
||||||
|
static i0.JsonTypeConverter2<i2.LogLevel, int, int> $converterlevel =
|
||||||
|
const i0.EnumIndexConverter<i2.LogLevel>(i2.LogLevel.values);
|
||||||
|
}
|
||||||
|
|
||||||
|
class LogMessageEntityData extends i0.DataClass
|
||||||
|
implements i0.Insertable<i1.LogMessageEntityData> {
|
||||||
|
final int id;
|
||||||
|
final String message;
|
||||||
|
final String? details;
|
||||||
|
final i2.LogLevel level;
|
||||||
|
final DateTime createdAt;
|
||||||
|
final String? logger;
|
||||||
|
final String? stack;
|
||||||
|
const LogMessageEntityData({
|
||||||
|
required this.id,
|
||||||
|
required this.message,
|
||||||
|
this.details,
|
||||||
|
required this.level,
|
||||||
|
required this.createdAt,
|
||||||
|
this.logger,
|
||||||
|
this.stack,
|
||||||
|
});
|
||||||
|
@override
|
||||||
|
Map<String, i0.Expression> toColumns(bool nullToAbsent) {
|
||||||
|
final map = <String, i0.Expression>{};
|
||||||
|
map['id'] = i0.Variable<int>(id);
|
||||||
|
map['message'] = i0.Variable<String>(message);
|
||||||
|
if (!nullToAbsent || details != null) {
|
||||||
|
map['details'] = i0.Variable<String>(details);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
map['level'] = i0.Variable<int>(
|
||||||
|
i1.$LogMessageEntityTable.$converterlevel.toSql(level),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
map['created_at'] = i0.Variable<DateTime>(createdAt);
|
||||||
|
if (!nullToAbsent || logger != null) {
|
||||||
|
map['logger'] = i0.Variable<String>(logger);
|
||||||
|
}
|
||||||
|
if (!nullToAbsent || stack != null) {
|
||||||
|
map['stack'] = i0.Variable<String>(stack);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
factory LogMessageEntityData.fromJson(
|
||||||
|
Map<String, dynamic> json, {
|
||||||
|
i0.ValueSerializer? serializer,
|
||||||
|
}) {
|
||||||
|
serializer ??= i0.driftRuntimeOptions.defaultSerializer;
|
||||||
|
return LogMessageEntityData(
|
||||||
|
id: serializer.fromJson<int>(json['id']),
|
||||||
|
message: serializer.fromJson<String>(json['message']),
|
||||||
|
details: serializer.fromJson<String?>(json['details']),
|
||||||
|
level: i1.$LogMessageEntityTable.$converterlevel.fromJson(
|
||||||
|
serializer.fromJson<int>(json['level']),
|
||||||
|
),
|
||||||
|
createdAt: serializer.fromJson<DateTime>(json['createdAt']),
|
||||||
|
logger: serializer.fromJson<String?>(json['logger']),
|
||||||
|
stack: serializer.fromJson<String?>(json['stack']),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson({i0.ValueSerializer? serializer}) {
|
||||||
|
serializer ??= i0.driftRuntimeOptions.defaultSerializer;
|
||||||
|
return <String, dynamic>{
|
||||||
|
'id': serializer.toJson<int>(id),
|
||||||
|
'message': serializer.toJson<String>(message),
|
||||||
|
'details': serializer.toJson<String?>(details),
|
||||||
|
'level': serializer.toJson<int>(
|
||||||
|
i1.$LogMessageEntityTable.$converterlevel.toJson(level),
|
||||||
|
),
|
||||||
|
'createdAt': serializer.toJson<DateTime>(createdAt),
|
||||||
|
'logger': serializer.toJson<String?>(logger),
|
||||||
|
'stack': serializer.toJson<String?>(stack),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
i1.LogMessageEntityData copyWith({
|
||||||
|
int? id,
|
||||||
|
String? message,
|
||||||
|
i0.Value<String?> details = const i0.Value.absent(),
|
||||||
|
i2.LogLevel? level,
|
||||||
|
DateTime? createdAt,
|
||||||
|
i0.Value<String?> logger = const i0.Value.absent(),
|
||||||
|
i0.Value<String?> stack = const i0.Value.absent(),
|
||||||
|
}) => i1.LogMessageEntityData(
|
||||||
|
id: id ?? this.id,
|
||||||
|
message: message ?? this.message,
|
||||||
|
details: details.present ? details.value : this.details,
|
||||||
|
level: level ?? this.level,
|
||||||
|
createdAt: createdAt ?? this.createdAt,
|
||||||
|
logger: logger.present ? logger.value : this.logger,
|
||||||
|
stack: stack.present ? stack.value : this.stack,
|
||||||
|
);
|
||||||
|
LogMessageEntityData copyWithCompanion(i1.LogMessageEntityCompanion data) {
|
||||||
|
return LogMessageEntityData(
|
||||||
|
id: data.id.present ? data.id.value : this.id,
|
||||||
|
message: data.message.present ? data.message.value : this.message,
|
||||||
|
details: data.details.present ? data.details.value : this.details,
|
||||||
|
level: data.level.present ? data.level.value : this.level,
|
||||||
|
createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt,
|
||||||
|
logger: data.logger.present ? data.logger.value : this.logger,
|
||||||
|
stack: data.stack.present ? data.stack.value : this.stack,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return (StringBuffer('LogMessageEntityData(')
|
||||||
|
..write('id: $id, ')
|
||||||
|
..write('message: $message, ')
|
||||||
|
..write('details: $details, ')
|
||||||
|
..write('level: $level, ')
|
||||||
|
..write('createdAt: $createdAt, ')
|
||||||
|
..write('logger: $logger, ')
|
||||||
|
..write('stack: $stack')
|
||||||
|
..write(')'))
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode =>
|
||||||
|
Object.hash(id, message, details, level, createdAt, logger, stack);
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
(other is i1.LogMessageEntityData &&
|
||||||
|
other.id == this.id &&
|
||||||
|
other.message == this.message &&
|
||||||
|
other.details == this.details &&
|
||||||
|
other.level == this.level &&
|
||||||
|
other.createdAt == this.createdAt &&
|
||||||
|
other.logger == this.logger &&
|
||||||
|
other.stack == this.stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
class LogMessageEntityCompanion
|
||||||
|
extends i0.UpdateCompanion<i1.LogMessageEntityData> {
|
||||||
|
final i0.Value<int> id;
|
||||||
|
final i0.Value<String> message;
|
||||||
|
final i0.Value<String?> details;
|
||||||
|
final i0.Value<i2.LogLevel> level;
|
||||||
|
final i0.Value<DateTime> createdAt;
|
||||||
|
final i0.Value<String?> logger;
|
||||||
|
final i0.Value<String?> stack;
|
||||||
|
const LogMessageEntityCompanion({
|
||||||
|
this.id = const i0.Value.absent(),
|
||||||
|
this.message = const i0.Value.absent(),
|
||||||
|
this.details = const i0.Value.absent(),
|
||||||
|
this.level = const i0.Value.absent(),
|
||||||
|
this.createdAt = const i0.Value.absent(),
|
||||||
|
this.logger = const i0.Value.absent(),
|
||||||
|
this.stack = const i0.Value.absent(),
|
||||||
|
});
|
||||||
|
LogMessageEntityCompanion.insert({
|
||||||
|
this.id = const i0.Value.absent(),
|
||||||
|
required String message,
|
||||||
|
this.details = const i0.Value.absent(),
|
||||||
|
required i2.LogLevel level,
|
||||||
|
required DateTime createdAt,
|
||||||
|
this.logger = const i0.Value.absent(),
|
||||||
|
this.stack = const i0.Value.absent(),
|
||||||
|
}) : message = i0.Value(message),
|
||||||
|
level = i0.Value(level),
|
||||||
|
createdAt = i0.Value(createdAt);
|
||||||
|
static i0.Insertable<i1.LogMessageEntityData> custom({
|
||||||
|
i0.Expression<int>? id,
|
||||||
|
i0.Expression<String>? message,
|
||||||
|
i0.Expression<String>? details,
|
||||||
|
i0.Expression<int>? level,
|
||||||
|
i0.Expression<DateTime>? createdAt,
|
||||||
|
i0.Expression<String>? logger,
|
||||||
|
i0.Expression<String>? stack,
|
||||||
|
}) {
|
||||||
|
return i0.RawValuesInsertable({
|
||||||
|
if (id != null) 'id': id,
|
||||||
|
if (message != null) 'message': message,
|
||||||
|
if (details != null) 'details': details,
|
||||||
|
if (level != null) 'level': level,
|
||||||
|
if (createdAt != null) 'created_at': createdAt,
|
||||||
|
if (logger != null) 'logger': logger,
|
||||||
|
if (stack != null) 'stack': stack,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
i1.LogMessageEntityCompanion copyWith({
|
||||||
|
i0.Value<int>? id,
|
||||||
|
i0.Value<String>? message,
|
||||||
|
i0.Value<String?>? details,
|
||||||
|
i0.Value<i2.LogLevel>? level,
|
||||||
|
i0.Value<DateTime>? createdAt,
|
||||||
|
i0.Value<String?>? logger,
|
||||||
|
i0.Value<String?>? stack,
|
||||||
|
}) {
|
||||||
|
return i1.LogMessageEntityCompanion(
|
||||||
|
id: id ?? this.id,
|
||||||
|
message: message ?? this.message,
|
||||||
|
details: details ?? this.details,
|
||||||
|
level: level ?? this.level,
|
||||||
|
createdAt: createdAt ?? this.createdAt,
|
||||||
|
logger: logger ?? this.logger,
|
||||||
|
stack: stack ?? this.stack,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, i0.Expression> toColumns(bool nullToAbsent) {
|
||||||
|
final map = <String, i0.Expression>{};
|
||||||
|
if (id.present) {
|
||||||
|
map['id'] = i0.Variable<int>(id.value);
|
||||||
|
}
|
||||||
|
if (message.present) {
|
||||||
|
map['message'] = i0.Variable<String>(message.value);
|
||||||
|
}
|
||||||
|
if (details.present) {
|
||||||
|
map['details'] = i0.Variable<String>(details.value);
|
||||||
|
}
|
||||||
|
if (level.present) {
|
||||||
|
map['level'] = i0.Variable<int>(
|
||||||
|
i1.$LogMessageEntityTable.$converterlevel.toSql(level.value),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (createdAt.present) {
|
||||||
|
map['created_at'] = i0.Variable<DateTime>(createdAt.value);
|
||||||
|
}
|
||||||
|
if (logger.present) {
|
||||||
|
map['logger'] = i0.Variable<String>(logger.value);
|
||||||
|
}
|
||||||
|
if (stack.present) {
|
||||||
|
map['stack'] = i0.Variable<String>(stack.value);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return (StringBuffer('LogMessageEntityCompanion(')
|
||||||
|
..write('id: $id, ')
|
||||||
|
..write('message: $message, ')
|
||||||
|
..write('details: $details, ')
|
||||||
|
..write('level: $level, ')
|
||||||
|
..write('createdAt: $createdAt, ')
|
||||||
|
..write('logger: $logger, ')
|
||||||
|
..write('stack: $stack')
|
||||||
|
..write(')'))
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
1322
mobile/lib/infrastructure/entities/log.entity.g.dart
generated
1322
mobile/lib/infrastructure/entities/log.entity.g.dart
generated
File diff suppressed because it is too large
Load Diff
@ -1,27 +1,43 @@
|
|||||||
|
import 'package:drift/drift.dart';
|
||||||
|
import 'package:immich_mobile/constants/constants.dart';
|
||||||
import 'package:immich_mobile/domain/models/log.model.dart';
|
import 'package:immich_mobile/domain/models/log.model.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/log.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/log.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
import 'package:immich_mobile/infrastructure/entities/log.entity.drift.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:immich_mobile/infrastructure/repositories/logger_db.repository.dart';
|
||||||
|
|
||||||
class IsarLogRepository extends IsarDatabaseRepository {
|
class LogRepository {
|
||||||
final Isar _db;
|
final DriftLogger _db;
|
||||||
const IsarLogRepository(super.db) : _db = db;
|
const LogRepository(this._db);
|
||||||
|
|
||||||
Future<bool> deleteAll() async {
|
Future<bool> deleteAll() async {
|
||||||
await transaction(() async => await _db.loggerMessages.clear());
|
await _db.logMessageEntity.deleteAll();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<LogMessage>> getAll() async {
|
Future<List<LogMessage>> getAll({int limit = 250}) async {
|
||||||
final logs = await _db.loggerMessages.where().sortByCreatedAtDesc().findAll();
|
final query = _db.logMessageEntity.select()
|
||||||
return logs.map((l) => l.toDto()).toList();
|
..orderBy([(row) => OrderingTerm.desc(row.createdAt)])
|
||||||
|
..limit(limit);
|
||||||
|
|
||||||
|
return query.map((log) => log.toDto()).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
LogMessageEntityCompanion _toEntityCompanion(LogMessage log) {
|
||||||
|
return LogMessageEntityCompanion.insert(
|
||||||
|
message: log.message,
|
||||||
|
level: log.level,
|
||||||
|
createdAt: log.createdAt,
|
||||||
|
logger: Value(log.logger),
|
||||||
|
details: Value(log.error),
|
||||||
|
stack: Value(log.stack),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> insert(LogMessage log) async {
|
Future<bool> insert(LogMessage log) async {
|
||||||
final logEntity = LoggerMessage.fromDto(log);
|
final logEntity = _toEntityCompanion(log);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await transaction(() => _db.loggerMessages.put(logEntity));
|
await _db.logMessageEntity.insertOne(logEntity);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -30,19 +46,30 @@ class IsarLogRepository extends IsarDatabaseRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> insertAll(Iterable<LogMessage> logs) async {
|
Future<bool> insertAll(Iterable<LogMessage> logs) async {
|
||||||
await transaction(() async {
|
final logEntities = logs.map(_toEntityCompanion).toList();
|
||||||
final logEntities = logs.map((log) => LoggerMessage.fromDto(log)).toList();
|
await _db.logMessageEntity.insertAll(logEntities);
|
||||||
await _db.loggerMessages.putAll(logEntities);
|
|
||||||
});
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> truncate({int limit = 250}) async {
|
Future<void> deleteByLogger(String logger) async {
|
||||||
await transaction(() async {
|
await _db.logMessageEntity.deleteWhere((row) => row.logger.equals(logger));
|
||||||
final count = await _db.loggerMessages.count();
|
}
|
||||||
if (count <= limit) return;
|
|
||||||
final toRemove = count - limit;
|
Stream<List<LogMessage>> watchMessages(String logger) {
|
||||||
await _db.loggerMessages.where().limit(toRemove).deleteAll();
|
final query = _db.logMessageEntity.select()
|
||||||
});
|
..orderBy([(row) => OrderingTerm.desc(row.createdAt)])
|
||||||
|
..where((row) => row.logger.equals(logger));
|
||||||
|
|
||||||
|
return query.watch().map((rows) => rows.map((row) => row.toDto()).toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> truncate({int limit = kLogTruncateLimit}) async {
|
||||||
|
final totalCount = await _db.managers.logMessageEntity.count();
|
||||||
|
if (totalCount > limit) {
|
||||||
|
final rowsToDelete = totalCount - limit;
|
||||||
|
|
||||||
|
await _db.managers.logMessageEntity.orderBy((o) => o.createdAt.asc()).limit(rowsToDelete).delete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
import 'package:drift/drift.dart';
|
||||||
|
import 'package:drift_flutter/drift_flutter.dart';
|
||||||
|
import 'package:immich_mobile/domain/interfaces/db.interface.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/entities/log.entity.dart';
|
||||||
|
|
||||||
|
import 'logger_db.repository.drift.dart';
|
||||||
|
|
||||||
|
@DriftDatabase(tables: [LogMessageEntity])
|
||||||
|
class DriftLogger extends $DriftLogger implements IDatabaseRepository {
|
||||||
|
DriftLogger([QueryExecutor? executor])
|
||||||
|
: super(
|
||||||
|
executor ?? driftDatabase(name: 'immich_logs', native: const DriftNativeOptions(shareAcrossIsolates: true)),
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get schemaVersion => 1;
|
||||||
|
|
||||||
|
@override
|
||||||
|
MigrationStrategy get migration => MigrationStrategy(
|
||||||
|
beforeOpen: (details) async {
|
||||||
|
await customStatement('PRAGMA foreign_keys = ON');
|
||||||
|
await customStatement('PRAGMA synchronous = NORMAL');
|
||||||
|
await customStatement('PRAGMA journal_mode = WAL');
|
||||||
|
await customStatement('PRAGMA busy_timeout = 500');
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
27
mobile/lib/infrastructure/repositories/logger_db.repository.drift.dart
generated
Normal file
27
mobile/lib/infrastructure/repositories/logger_db.repository.drift.dart
generated
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// dart format width=80
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
import 'package:drift/drift.dart' as i0;
|
||||||
|
import 'package:immich_mobile/infrastructure/entities/log.entity.drift.dart'
|
||||||
|
as i1;
|
||||||
|
|
||||||
|
abstract class $DriftLogger extends i0.GeneratedDatabase {
|
||||||
|
$DriftLogger(i0.QueryExecutor e) : super(e);
|
||||||
|
$DriftLoggerManager get managers => $DriftLoggerManager(this);
|
||||||
|
late final i1.$LogMessageEntityTable logMessageEntity = i1
|
||||||
|
.$LogMessageEntityTable(this);
|
||||||
|
@override
|
||||||
|
Iterable<i0.TableInfo<i0.Table, Object?>> get allTables =>
|
||||||
|
allSchemaEntities.whereType<i0.TableInfo<i0.Table, Object?>>();
|
||||||
|
@override
|
||||||
|
List<i0.DatabaseSchemaEntity> get allSchemaEntities => [logMessageEntity];
|
||||||
|
@override
|
||||||
|
i0.DriftDatabaseOptions get options =>
|
||||||
|
const i0.DriftDatabaseOptions(storeDateTimeAsText: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
class $DriftLoggerManager {
|
||||||
|
final $DriftLogger _db;
|
||||||
|
$DriftLoggerManager(this._db);
|
||||||
|
i1.$$LogMessageEntityTableTableManager get logMessageEntity =>
|
||||||
|
i1.$$LogMessageEntityTableTableManager(_db, _db.logMessageEntity);
|
||||||
|
}
|
@ -4,7 +4,6 @@ import 'dart:convert';
|
|||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:immich_mobile/constants/constants.dart';
|
import 'package:immich_mobile/constants/constants.dart';
|
||||||
import 'package:immich_mobile/domain/models/sync_event.model.dart';
|
import 'package:immich_mobile/domain/models/sync_event.model.dart';
|
||||||
import 'package:immich_mobile/presentation/pages/dev/dev_logger.dart';
|
|
||||||
import 'package:immich_mobile/services/api.service.dart';
|
import 'package:immich_mobile/services/api.service.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:openapi/api.dart';
|
import 'package:openapi/api.dart';
|
||||||
@ -107,7 +106,6 @@ class SyncApiRepository {
|
|||||||
}
|
}
|
||||||
stopwatch.stop();
|
stopwatch.stop();
|
||||||
_logger.info("Remote Sync completed in ${stopwatch.elapsed.inMilliseconds}ms");
|
_logger.info("Remote Sync completed in ${stopwatch.elapsed.inMilliseconds}ms");
|
||||||
DLog.log("Remote Sync completed in ${stopwatch.elapsed.inMilliseconds}ms");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<SyncEvent> _parseLines(List<String> lines) {
|
List<SyncEvent> _parseLines(List<String> lines) {
|
||||||
|
@ -65,7 +65,7 @@ class AppLogDetailPage extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
buildLogContext1(String context1) {
|
buildLogContext(String logger) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
@ -86,7 +86,7 @@ class AppLogDetailPage extends HookConsumerWidget {
|
|||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: SelectableText(
|
child: SelectableText(
|
||||||
context1.toString(),
|
logger.toString(),
|
||||||
style: const TextStyle(fontSize: 12.0, fontWeight: FontWeight.bold, fontFamily: "Inconsolata"),
|
style: const TextStyle(fontSize: 12.0, fontWeight: FontWeight.bold, fontFamily: "Inconsolata"),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -103,7 +103,7 @@ class AppLogDetailPage extends HookConsumerWidget {
|
|||||||
children: [
|
children: [
|
||||||
buildTextWithCopyButton("MESSAGE", logMessage.message),
|
buildTextWithCopyButton("MESSAGE", logMessage.message),
|
||||||
if (logMessage.error != null) buildTextWithCopyButton("DETAILS", logMessage.error.toString()),
|
if (logMessage.error != null) buildTextWithCopyButton("DETAILS", logMessage.error.toString()),
|
||||||
if (logMessage.logger != null) buildLogContext1(logMessage.logger.toString()),
|
if (logMessage.logger != null) buildLogContext(logMessage.logger.toString()),
|
||||||
if (logMessage.stack != null) buildTextWithCopyButton("STACK TRACE", logMessage.stack.toString()),
|
if (logMessage.stack != null) buildTextWithCopyButton("STACK TRACE", logMessage.stack.toString()),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -49,7 +49,6 @@ class SplashScreenPageState extends ConsumerState<SplashScreenPage> {
|
|||||||
final wsProvider = ref.read(websocketProvider.notifier);
|
final wsProvider = ref.read(websocketProvider.notifier);
|
||||||
ref.read(authProvider.notifier).saveAuthInfo(accessToken: accessToken).then(
|
ref.read(authProvider.notifier).saveAuthInfo(accessToken: accessToken).then(
|
||||||
(a) {
|
(a) {
|
||||||
log.info('Successfully updated auth info with access token: $accessToken');
|
|
||||||
try {
|
try {
|
||||||
wsProvider.connect();
|
wsProvider.connect();
|
||||||
infoProvider.getServerInfo();
|
infoProvider.getServerInfo();
|
||||||
|
@ -1,68 +0,0 @@
|
|||||||
import 'dart:async';
|
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/log.model.dart';
|
|
||||||
import 'package:immich_mobile/infrastructure/entities/log.entity.dart';
|
|
||||||
import 'package:immich_mobile/infrastructure/repositories/log.repository.dart';
|
|
||||||
// ignore: import_rule_isar
|
|
||||||
import 'package:isar/isar.dart';
|
|
||||||
|
|
||||||
const kDevLoggerTag = 'DEV';
|
|
||||||
|
|
||||||
abstract final class DLog {
|
|
||||||
const DLog();
|
|
||||||
|
|
||||||
static Stream<List<LogMessage>> watchLog() {
|
|
||||||
final db = Isar.getInstance();
|
|
||||||
if (db == null) {
|
|
||||||
return const Stream.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
return db.loggerMessages
|
|
||||||
.filter()
|
|
||||||
.context1EqualTo(kDevLoggerTag)
|
|
||||||
.sortByCreatedAtDesc()
|
|
||||||
.watch(fireImmediately: true)
|
|
||||||
.map((logs) => logs.map((log) => log.toDto()).toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
static void clearLog() {
|
|
||||||
final db = Isar.getInstance();
|
|
||||||
if (db == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
db.writeTxnSync(() {
|
|
||||||
db.loggerMessages.filter().context1EqualTo(kDevLoggerTag).deleteAllSync();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
static void log(String message, [Object? error, StackTrace? stackTrace]) {
|
|
||||||
if (!Platform.environment.containsKey('FLUTTER_TEST')) {
|
|
||||||
debugPrint('[$kDevLoggerTag] [${DateTime.now()}] $message');
|
|
||||||
}
|
|
||||||
if (error != null) {
|
|
||||||
debugPrint('Error: $error');
|
|
||||||
}
|
|
||||||
if (stackTrace != null) {
|
|
||||||
debugPrint('StackTrace: $stackTrace');
|
|
||||||
}
|
|
||||||
|
|
||||||
final isar = Isar.getInstance();
|
|
||||||
if (isar == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final record = LogMessage(
|
|
||||||
message: message,
|
|
||||||
level: LogLevel.info,
|
|
||||||
createdAt: DateTime.now(),
|
|
||||||
logger: kDevLoggerTag,
|
|
||||||
error: error?.toString(),
|
|
||||||
stack: stackTrace?.toString(),
|
|
||||||
);
|
|
||||||
|
|
||||||
unawaited(IsarLogRepository(isar).insert(record));
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,19 +2,16 @@ import 'dart:async';
|
|||||||
|
|
||||||
import 'package:auto_route/auto_route.dart';
|
import 'package:auto_route/auto_route.dart';
|
||||||
import 'package:drift/drift.dart' hide Column;
|
import 'package:drift/drift.dart' hide Column;
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
|
||||||
import 'package:immich_mobile/extensions/theme_extensions.dart';
|
|
||||||
import 'package:immich_mobile/presentation/pages/dev/dev_logger.dart';
|
|
||||||
import 'package:immich_mobile/providers/background_sync.provider.dart';
|
import 'package:immich_mobile/providers/background_sync.provider.dart';
|
||||||
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart';
|
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart';
|
||||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||||
import 'package:immich_mobile/providers/infrastructure/platform.provider.dart';
|
import 'package:immich_mobile/providers/infrastructure/platform.provider.dart';
|
||||||
import 'package:immich_mobile/providers/user.provider.dart';
|
import 'package:immich_mobile/providers/user.provider.dart';
|
||||||
import 'package:immich_mobile/routing/router.dart';
|
import 'package:immich_mobile/routing/router.dart';
|
||||||
|
import 'package:logging/logging.dart';
|
||||||
|
|
||||||
final _features = [
|
final _features = [
|
||||||
_Feature(
|
_Feature(
|
||||||
@ -37,7 +34,7 @@ final _features = [
|
|||||||
DriftAssetSelectionTimelineRoute(lockedSelectionAssets: assets.toSet()),
|
DriftAssetSelectionTimelineRoute(lockedSelectionAssets: assets.toSet()),
|
||||||
);
|
);
|
||||||
|
|
||||||
DLog.log("Selected ${selectedAssets?.length ?? 0} assets");
|
Logger("FeaturesInDevelopment").fine("Selected ${selectedAssets?.length ?? 0} assets");
|
||||||
|
|
||||||
return Future.value();
|
return Future.value();
|
||||||
},
|
},
|
||||||
@ -159,7 +156,6 @@ class FeatInDevPage extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Divider(height: 0),
|
const Divider(height: 0),
|
||||||
const Flexible(child: _DevLogs()),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -174,57 +170,3 @@ class _Feature {
|
|||||||
final TextStyle? style;
|
final TextStyle? style;
|
||||||
final Future<void> Function(BuildContext, WidgetRef _) onTap;
|
final Future<void> Function(BuildContext, WidgetRef _) onTap;
|
||||||
}
|
}
|
||||||
|
|
||||||
class _DevLogs extends StatelessWidget {
|
|
||||||
const _DevLogs();
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
appBar: AppBar(
|
|
||||||
automaticallyImplyLeading: false,
|
|
||||||
actions: [
|
|
||||||
IconButton(
|
|
||||||
onPressed: DLog.clearLog,
|
|
||||||
icon: Icon(
|
|
||||||
Icons.delete_outline_rounded,
|
|
||||||
size: 20.0,
|
|
||||||
color: context.primaryColor,
|
|
||||||
semanticLabel: "Clear logs",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
centerTitle: true,
|
|
||||||
),
|
|
||||||
body: StreamBuilder(
|
|
||||||
initialData: [],
|
|
||||||
stream: DLog.watchLog(),
|
|
||||||
builder: (_, logMessages) {
|
|
||||||
return ListView.separated(
|
|
||||||
itemBuilder: (ctx, index) {
|
|
||||||
final logMessage = logMessages.data![index];
|
|
||||||
return ListTile(
|
|
||||||
title: Text(
|
|
||||||
logMessage.message,
|
|
||||||
style: TextStyle(color: ctx.colorScheme.onSurface, fontSize: 14.0, overflow: TextOverflow.ellipsis),
|
|
||||||
),
|
|
||||||
subtitle: Text(
|
|
||||||
"at ${DateFormat("HH:mm:ss.SSS").format(logMessage.createdAt)}",
|
|
||||||
style: TextStyle(color: ctx.colorScheme.onSurfaceSecondary, fontSize: 12.0),
|
|
||||||
),
|
|
||||||
dense: true,
|
|
||||||
visualDensity: VisualDensity.compact,
|
|
||||||
tileColor: Colors.transparent,
|
|
||||||
minLeadingWidth: 10,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
separatorBuilder: (_, index) {
|
|
||||||
return const Divider(height: 0);
|
|
||||||
},
|
|
||||||
itemCount: logMessages.data?.length ?? 0,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -12,10 +12,10 @@ import 'package:immich_mobile/entities/etag.entity.dart';
|
|||||||
import 'package:immich_mobile/entities/ios_device_asset.entity.dart';
|
import 'package:immich_mobile/entities/ios_device_asset.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/device_asset.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/device_asset.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/exif.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/exif.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/log.entity.dart';
|
|
||||||
import 'package:immich_mobile/infrastructure/entities/store.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/store.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/user.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/user.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/log.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/log.repository.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/repositories/logger_db.repository.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/store.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/store.repository.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
@ -36,7 +36,6 @@ abstract final class Bootstrap {
|
|||||||
UserSchema,
|
UserSchema,
|
||||||
BackupAlbumSchema,
|
BackupAlbumSchema,
|
||||||
DuplicatedAssetSchema,
|
DuplicatedAssetSchema,
|
||||||
LoggerMessageSchema,
|
|
||||||
ETagSchema,
|
ETagSchema,
|
||||||
if (Platform.isAndroid) AndroidDeviceAssetSchema,
|
if (Platform.isAndroid) AndroidDeviceAssetSchema,
|
||||||
if (Platform.isIOS) IOSDeviceAssetSchema,
|
if (Platform.isIOS) IOSDeviceAssetSchema,
|
||||||
@ -49,9 +48,13 @@ abstract final class Bootstrap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Future<void> initDomain(Isar db, {bool shouldBufferLogs = true}) async {
|
static Future<void> initDomain(Isar db, {bool shouldBufferLogs = true}) async {
|
||||||
|
// load drift dbs
|
||||||
|
final loggerDb = DriftLogger();
|
||||||
|
|
||||||
await StoreService.init(storeRepository: IsarStoreRepository(db));
|
await StoreService.init(storeRepository: IsarStoreRepository(db));
|
||||||
|
|
||||||
await LogService.init(
|
await LogService.init(
|
||||||
logRepository: IsarLogRepository(db),
|
logRepository: LogRepository(loggerDb),
|
||||||
storeRepository: IsarStoreRepository(db),
|
storeRepository: IsarStoreRepository(db),
|
||||||
shouldBuffer: shouldBufferLogs,
|
shouldBuffer: shouldBufferLogs,
|
||||||
);
|
);
|
||||||
|
@ -56,7 +56,7 @@ Cancelable<T?> runInIsolateGentle<T>({
|
|||||||
log.severe("Error in runInIsolateGentle ${debugLabel == null ? '' : ' for $debugLabel'}", error, stack);
|
log.severe("Error in runInIsolateGentle ${debugLabel == null ? '' : ' for $debugLabel'}", error, stack);
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
await LogService.I.flushBuffer();
|
await LogService.I.flush();
|
||||||
await ref.read(driftProvider).close();
|
await ref.read(driftProvider).close();
|
||||||
|
|
||||||
// Close Isar safely
|
// Close Isar safely
|
||||||
|
@ -28,7 +28,7 @@ final _kWarnLog = LogMessage(
|
|||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
late LogService sut;
|
late LogService sut;
|
||||||
late IsarLogRepository mockLogRepo;
|
late LogRepository mockLogRepo;
|
||||||
late IsarStoreRepository mockStoreRepo;
|
late IsarStoreRepository mockStoreRepo;
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() async {
|
||||||
|
@ -12,7 +12,7 @@ import 'package:mocktail/mocktail.dart';
|
|||||||
|
|
||||||
class MockStoreRepository extends Mock implements IsarStoreRepository {}
|
class MockStoreRepository extends Mock implements IsarStoreRepository {}
|
||||||
|
|
||||||
class MockLogRepository extends Mock implements IsarLogRepository {}
|
class MockLogRepository extends Mock implements LogRepository {}
|
||||||
|
|
||||||
class MockIsarUserRepository extends Mock implements IsarUserRepository {}
|
class MockIsarUserRepository extends Mock implements IsarUserRepository {}
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import 'package:drift/drift.dart';
|
||||||
|
import 'package:drift/native.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:immich_mobile/constants/enums.dart';
|
import 'package:immich_mobile/constants/enums.dart';
|
||||||
@ -9,9 +11,10 @@ import 'package:immich_mobile/entities/asset.entity.dart';
|
|||||||
import 'package:immich_mobile/entities/etag.entity.dart';
|
import 'package:immich_mobile/entities/etag.entity.dart';
|
||||||
import 'package:immich_mobile/entities/store.entity.dart';
|
import 'package:immich_mobile/entities/store.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/log.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/log.repository.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/repositories/logger_db.repository.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/store.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/store.repository.dart';
|
||||||
import 'package:immich_mobile/repositories/partner_api.repository.dart';
|
|
||||||
import 'package:immich_mobile/repositories/asset.repository.dart';
|
import 'package:immich_mobile/repositories/asset.repository.dart';
|
||||||
|
import 'package:immich_mobile/repositories/partner_api.repository.dart';
|
||||||
import 'package:immich_mobile/services/sync.service.dart';
|
import 'package:immich_mobile/services/sync.service.dart';
|
||||||
import 'package:mocktail/mocktail.dart';
|
import 'package:mocktail/mocktail.dart';
|
||||||
|
|
||||||
@ -49,6 +52,28 @@ void main() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final owner = UserDto(
|
||||||
|
id: "1",
|
||||||
|
updatedAt: DateTime.now(),
|
||||||
|
email: "a@b.c",
|
||||||
|
name: "first last",
|
||||||
|
isAdmin: false,
|
||||||
|
profileChangedAt: DateTime.now(),
|
||||||
|
);
|
||||||
|
|
||||||
|
setUpAll(() async {
|
||||||
|
final loggerDb = DriftLogger(DatabaseConnection(NativeDatabase.memory(), closeStreamsSynchronously: true));
|
||||||
|
final LogRepository logRepository = LogRepository(loggerDb);
|
||||||
|
|
||||||
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
final db = await TestUtils.initIsar();
|
||||||
|
|
||||||
|
db.writeTxnSync(() => db.clearSync());
|
||||||
|
await StoreService.init(storeRepository: IsarStoreRepository(db));
|
||||||
|
await Store.put(StoreKey.currentUser, owner);
|
||||||
|
await LogService.init(logRepository: logRepository, storeRepository: IsarStoreRepository(db));
|
||||||
|
});
|
||||||
|
|
||||||
group('Test SyncService grouped', () {
|
group('Test SyncService grouped', () {
|
||||||
final MockHashService hs = MockHashService();
|
final MockHashService hs = MockHashService();
|
||||||
final MockEntityService entityService = MockEntityService();
|
final MockEntityService entityService = MockEntityService();
|
||||||
@ -74,16 +99,9 @@ void main() {
|
|||||||
isAdmin: false,
|
isAdmin: false,
|
||||||
profileChangedAt: DateTime(2021),
|
profileChangedAt: DateTime(2021),
|
||||||
);
|
);
|
||||||
late SyncService s;
|
|
||||||
setUpAll(() async {
|
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
|
||||||
final db = await TestUtils.initIsar();
|
|
||||||
|
|
||||||
db.writeTxnSync(() => db.clearSync());
|
late SyncService s;
|
||||||
await StoreService.init(storeRepository: IsarStoreRepository(db));
|
|
||||||
await Store.put(StoreKey.currentUser, owner);
|
|
||||||
await LogService.init(logRepository: IsarLogRepository(db), storeRepository: IsarStoreRepository(db));
|
|
||||||
});
|
|
||||||
final List<Asset> initialAssets = [
|
final List<Asset> initialAssets = [
|
||||||
makeAsset(checksum: "a", remoteId: "0-1"),
|
makeAsset(checksum: "a", remoteId: "0-1"),
|
||||||
makeAsset(checksum: "b", remoteId: "2-1"),
|
makeAsset(checksum: "b", remoteId: "2-1"),
|
||||||
|
@ -14,7 +14,6 @@ import 'package:immich_mobile/entities/etag.entity.dart';
|
|||||||
import 'package:immich_mobile/entities/ios_device_asset.entity.dart';
|
import 'package:immich_mobile/entities/ios_device_asset.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/device_asset.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/device_asset.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/exif.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/exif.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/log.entity.dart';
|
|
||||||
import 'package:immich_mobile/infrastructure/entities/store.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/store.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/user.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/user.entity.dart';
|
||||||
import 'package:isar/isar.dart';
|
import 'package:isar/isar.dart';
|
||||||
@ -48,7 +47,6 @@ abstract final class TestUtils {
|
|||||||
UserSchema,
|
UserSchema,
|
||||||
BackupAlbumSchema,
|
BackupAlbumSchema,
|
||||||
DuplicatedAssetSchema,
|
DuplicatedAssetSchema,
|
||||||
LoggerMessageSchema,
|
|
||||||
ETagSchema,
|
ETagSchema,
|
||||||
AndroidDeviceAssetSchema,
|
AndroidDeviceAssetSchema,
|
||||||
IOSDeviceAssetSchema,
|
IOSDeviceAssetSchema,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user