mirror of
https://github.com/immich-app/immich
synced 2025-11-14 17:36:12 +00:00
feat(db): add local_trashed_asset table and integrate with restoration flow
- Add new `local_trashed_asset` table to store metadata of trashed assets - Save trashed asset info into `local_trashed_asset` before deletion - Use `local_trashed_asset` as source for asset restoration - Implement file restoration by `mediaId`
This commit is contained in:
parent
57540f6259
commit
020dfa7818
15 changed files with 8285 additions and 31 deletions
|
|
@ -157,14 +157,22 @@ class BackgroundServicePlugin : FlutterPlugin, MethodChannel.MethodCallHandler,
|
||||||
val fileName = call.argument<String>("fileName")
|
val fileName = call.argument<String>("fileName")
|
||||||
val type = call.argument<Int>("type")
|
val type = call.argument<Int>("type")
|
||||||
val checksum = call.argument<String>("checksum")
|
val checksum = call.argument<String>("checksum")
|
||||||
|
val mediaId = call.argument<String>("mediaId")
|
||||||
if (fileName != null && type != null && checksum != null) {
|
if (fileName != null && type != null && checksum != null) {
|
||||||
if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) && hasManageMediaPermission()) {
|
if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) && hasManageMediaPermission()) {
|
||||||
restoreFromTrash(fileName, type, checksum, result)
|
restoreFromTrash(fileName, type, checksum, result)
|
||||||
} else {
|
} else {
|
||||||
result.error("PERMISSION_DENIED", "Media permission required", null)
|
result.error("PERMISSION_DENIED", "Media permission required", null)
|
||||||
}
|
}
|
||||||
|
} else
|
||||||
|
if (mediaId != null && type != null) {
|
||||||
|
if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) && hasManageMediaPermission()) {
|
||||||
|
restoreFromTrashById(mediaId, type, result)
|
||||||
} else {
|
} else {
|
||||||
result.error("INVALID_NAME", "The file name or checksum is not specified.", null)
|
result.error("PERMISSION_DENIED", "Media permission required", null)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result.error("INVALID_PARAMS", "Required params are not specified.", null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -225,6 +233,30 @@ class BackgroundServicePlugin : FlutterPlugin, MethodChannel.MethodCallHandler,
|
||||||
uri.let { toggleTrash(listOf(it), false, result) }
|
uri.let { toggleTrash(listOf(it), false, result) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.R)
|
||||||
|
private fun restoreFromTrashById(mediaId: String, type: Int, result: Result) {
|
||||||
|
val id = mediaId.toLongOrNull()
|
||||||
|
if (id == null) {
|
||||||
|
result.error("INVALID_ID", "The file id is not a valid number: $mediaId", null)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!isInTrash(id)) {
|
||||||
|
result.error("TrashNotFound", "Item with id=$id not found in trash", null)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val primary = ContentUris.withAppendedId(contentUriForType(type), id)
|
||||||
|
val fallback = ContentUris.withAppendedId(MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL), id)
|
||||||
|
|
||||||
|
try {
|
||||||
|
Log.i(TAG, "restoreFromTrashById: primary=$primary (type=$type,id=$id)")
|
||||||
|
restoreUris(listOf(primary), result)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, "restoreFromTrashById: primary failed, try fallback=$fallback", e)
|
||||||
|
restoreUris(listOf(fallback), result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.R)
|
@RequiresApi(Build.VERSION_CODES.R)
|
||||||
private fun toggleTrash(contentUris: List<Uri>, isTrashed: Boolean, result: Result) {
|
private fun toggleTrash(contentUris: List<Uri>, isTrashed: Boolean, result: Result) {
|
||||||
val activity = activityBinding?.activity
|
val activity = activityBinding?.activity
|
||||||
|
|
@ -292,13 +324,7 @@ class BackgroundServicePlugin : FlutterPlugin, MethodChannel.MethodCallHandler,
|
||||||
} ?: continue
|
} ?: continue
|
||||||
|
|
||||||
if (sha1Bytes.contentEquals(expectedBytes)) {
|
if (sha1Bytes.contentEquals(expectedBytes)) {
|
||||||
// same order as AssetType from dart
|
val contentUri = contentUriForType(type)
|
||||||
val contentUri = when (type) {
|
|
||||||
1 -> MediaStore.Images.Media.EXTERNAL_CONTENT_URI
|
|
||||||
2 -> MediaStore.Video.Media.EXTERNAL_CONTENT_URI
|
|
||||||
3 -> MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
|
|
||||||
else -> queryUri
|
|
||||||
}
|
|
||||||
return ContentUris.withAppendedId(contentUri, id)
|
return ContentUris.withAppendedId(contentUri, id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -346,6 +372,30 @@ class BackgroundServicePlugin : FlutterPlugin, MethodChannel.MethodCallHandler,
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.R)
|
||||||
|
private fun isInTrash(id: Long): Boolean {
|
||||||
|
val contentResolver = context?.contentResolver ?: return false
|
||||||
|
val filesUri = MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL)
|
||||||
|
val args = Bundle().apply {
|
||||||
|
putString(ContentResolver.QUERY_ARG_SQL_SELECTION, "${MediaStore.Files.FileColumns._ID}=?")
|
||||||
|
putStringArray(ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS, arrayOf(id.toString()))
|
||||||
|
putInt(MediaStore.QUERY_ARG_MATCH_TRASHED, MediaStore.MATCH_ONLY)
|
||||||
|
putInt(ContentResolver.QUERY_ARG_LIMIT, 1)
|
||||||
|
}
|
||||||
|
return contentResolver.query(filesUri, arrayOf(MediaStore.Files.FileColumns._ID), args, null)
|
||||||
|
?.use { it.moveToFirst() } == true
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.R)
|
||||||
|
private fun restoreUris(uris: List<Uri>, result: Result) {
|
||||||
|
if (uris.isEmpty()) {
|
||||||
|
result.error("TrashError", "No URIs to restore", null)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Log.i(TAG, "restoreUris: count=${uris.size}, first=${uris.first()}")
|
||||||
|
toggleTrash(uris, false, result)
|
||||||
|
}
|
||||||
|
|
||||||
private fun sha1OfStream(ins: InputStream): ByteArray {
|
private fun sha1OfStream(ins: InputStream): ByteArray {
|
||||||
val buf = ByteArray(BUFFER_SIZE)
|
val buf = ByteArray(BUFFER_SIZE)
|
||||||
val md = MessageDigest.getInstance("SHA-1")
|
val md = MessageDigest.getInstance("SHA-1")
|
||||||
|
|
@ -357,6 +407,16 @@ class BackgroundServicePlugin : FlutterPlugin, MethodChannel.MethodCallHandler,
|
||||||
}
|
}
|
||||||
return md.digest()
|
return md.digest()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.Q)
|
||||||
|
private fun contentUriForType(type: Int): Uri =
|
||||||
|
when (type) {
|
||||||
|
// same order as AssetType from dart
|
||||||
|
1 -> MediaStore.Images.Media.EXTERNAL_CONTENT_URI
|
||||||
|
2 -> MediaStore.Video.Media.EXTERNAL_CONTENT_URI
|
||||||
|
3 -> MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
|
||||||
|
else -> MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private const val TAG = "BackgroundServicePlugin"
|
private const val TAG = "BackgroundServicePlugin"
|
||||||
|
|
|
||||||
1
mobile/drift_schemas/main/drift_schema_v10.json
generated
Normal file
1
mobile/drift_schemas/main/drift_schema_v10.json
generated
Normal file
File diff suppressed because one or more lines are too long
37
mobile/lib/domain/models/local_trashed_asset.model.dart
Normal file
37
mobile/lib/domain/models/local_trashed_asset.model.dart
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
class LocalTrashedAsset {
|
||||||
|
final String localId;
|
||||||
|
final String remoteId;
|
||||||
|
final DateTime createdAt;
|
||||||
|
|
||||||
|
const LocalTrashedAsset({required this.localId, required this.remoteId, required this.createdAt});
|
||||||
|
|
||||||
|
LocalTrashedAsset copyWith({String? localId, String? remoteId, DateTime? createdAt}) {
|
||||||
|
return LocalTrashedAsset(
|
||||||
|
localId: localId ?? this.localId,
|
||||||
|
remoteId: remoteId ?? this.remoteId,
|
||||||
|
createdAt: createdAt ?? this.createdAt,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (other is! LocalTrashedAsset) return false;
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
|
||||||
|
return other.localId == localId && other.remoteId == remoteId && other.createdAt == createdAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return localId.hashCode ^ remoteId.hashCode ^ createdAt.hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return '''LocalTrashedAsset: {
|
||||||
|
localId: $localId,
|
||||||
|
remoteId: $remoteId,
|
||||||
|
createdAt: $createdAt
|
||||||
|
}''';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -85,7 +85,7 @@ class SyncStreamService {
|
||||||
case SyncEntityType.assetV1:
|
case SyncEntityType.assetV1:
|
||||||
final remoteSyncAssets = data.cast<SyncAssetV1>();
|
final remoteSyncAssets = data.cast<SyncAssetV1>();
|
||||||
await _trashSyncService.handleRemoteChanges(
|
await _trashSyncService.handleRemoteChanges(
|
||||||
remoteSyncAssets.map<TrashSyncItem>((e) => (checksum: e.checksum, deletedAt: e.deletedAt)),
|
remoteSyncAssets.map<TrashSyncItem>((e) => (remoteId: e.id, checksum: e.checksum, deletedAt: e.deletedAt)),
|
||||||
);
|
);
|
||||||
return _syncStreamRepository.updateAssetsV1(remoteSyncAssets);
|
return _syncStreamRepository.updateAssetsV1(remoteSyncAssets);
|
||||||
case SyncEntityType.assetDeleteV1:
|
case SyncEntityType.assetDeleteV1:
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
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/domain/models/local_trashed_asset.model.dart';
|
||||||
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/remote_asset.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/remote_asset.repository.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/storage.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/storage.repository.dart';
|
||||||
|
|
@ -7,7 +8,7 @@ import 'package:immich_mobile/services/app_settings.service.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:platform/platform.dart';
|
import 'package:platform/platform.dart';
|
||||||
|
|
||||||
typedef TrashSyncItem = ({String checksum, DateTime? deletedAt});
|
typedef TrashSyncItem = ({String remoteId, String checksum, DateTime? deletedAt});
|
||||||
|
|
||||||
class TrashSyncService {
|
class TrashSyncService {
|
||||||
final AppSettingsService _appSettingsService;
|
final AppSettingsService _appSettingsService;
|
||||||
|
|
@ -35,24 +36,25 @@ class TrashSyncService {
|
||||||
if (!_platform.isAndroid || !_appSettingsService.getSetting<bool>(AppSettingsEnum.manageLocalMediaAndroid)) {
|
if (!_platform.isAndroid || !_appSettingsService.getSetting<bool>(AppSettingsEnum.manageLocalMediaAndroid)) {
|
||||||
return Future.value();
|
return Future.value();
|
||||||
}
|
}
|
||||||
final trashedAssetsChecksums = <String>{};
|
final trashedAssetsItems = <TrashSyncItem>[];
|
||||||
final modifiedAssetsChecksums = <String>{};
|
final modifiedAssetsChecksums = <String>{};
|
||||||
for (var syncItem in syncItems) {
|
for (var syncItem in syncItems) {
|
||||||
if (syncItem.deletedAt != null) {
|
if (syncItem.deletedAt != null) {
|
||||||
trashedAssetsChecksums.add(syncItem.checksum);
|
trashedAssetsItems.add(syncItem);
|
||||||
} else {
|
} else {
|
||||||
modifiedAssetsChecksums.add(syncItem.checksum);
|
modifiedAssetsChecksums.add(syncItem.checksum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await _applyRemoteTrashToLocal(trashedAssetsChecksums);
|
await _applyRemoteTrashToLocal(trashedAssetsItems);
|
||||||
await _applyRemoteRestoreToLocal(modifiedAssetsChecksums);
|
await _applyRemoteRestoreToLocal(modifiedAssetsChecksums);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _applyRemoteTrashToLocal(Iterable<String> trashedAssetsChecksums) async {
|
Future<void> _applyRemoteTrashToLocal(Iterable<TrashSyncItem> trashedAssets) async {
|
||||||
if (trashedAssetsChecksums.isEmpty) {
|
if (trashedAssets.isEmpty) {
|
||||||
return Future.value();
|
return Future.value();
|
||||||
} else {
|
} else {
|
||||||
final localAssetsToTrash = await _localAssetRepository.getBackupSelectedAssets(trashedAssetsChecksums);
|
final trashedAssetsMap = <String, String>{for (final e in trashedAssets) e.checksum: e.remoteId};
|
||||||
|
final localAssetsToTrash = await _localAssetRepository.getBackupSelectedAssets(trashedAssetsMap.keys);
|
||||||
if (localAssetsToTrash.isNotEmpty) {
|
if (localAssetsToTrash.isNotEmpty) {
|
||||||
final mediaUrls = await Future.wait(
|
final mediaUrls = await Future.wait(
|
||||||
localAssetsToTrash.map(
|
localAssetsToTrash.map(
|
||||||
|
|
@ -61,9 +63,14 @@ class TrashSyncService {
|
||||||
);
|
);
|
||||||
_logger.info("Moving to trash ${mediaUrls.join(", ")} assets");
|
_logger.info("Moving to trash ${mediaUrls.join(", ")} assets");
|
||||||
await _localFilesManager.moveToTrash(mediaUrls.nonNulls.toList());
|
await _localFilesManager.moveToTrash(mediaUrls.nonNulls.toList());
|
||||||
await _localAssetRepository.delete(localAssetsToTrash.map((asset) => asset.id));
|
final itemsToTrash = <LocalRemoteIds>[];
|
||||||
|
for (final asset in localAssetsToTrash) {
|
||||||
|
final remoteId = trashedAssetsMap[asset.checksum]!;
|
||||||
|
itemsToTrash.add((localId: asset.id, remoteId: remoteId));
|
||||||
|
}
|
||||||
|
await _localAssetRepository.trash(itemsToTrash);
|
||||||
} else {
|
} else {
|
||||||
_logger.info("No assets found in backup-enabled albums for checksums: $trashedAssetsChecksums");
|
_logger.info("No assets found in backup-enabled albums for assets: $trashedAssetsMap");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -77,12 +84,21 @@ class TrashSyncService {
|
||||||
isTrashed: true,
|
isTrashed: true,
|
||||||
);
|
);
|
||||||
if (remoteAssetsToRestore.isNotEmpty) {
|
if (remoteAssetsToRestore.isNotEmpty) {
|
||||||
_logger.info(
|
final remoteAssetMap = <String, AssetType>{for (final e in remoteAssetsToRestore) e.id: e.type};
|
||||||
"Restoring from trash ${remoteAssetsToRestore.map((e) => "${e.name}/${e.checksum}").join(", ")} assets",
|
_logger.info("remoteAssetsToRestore: $remoteAssetMap");
|
||||||
);
|
final localTrashedAssets = await _localAssetRepository.getLocalTrashedAssets(remoteAssetMap.keys);
|
||||||
for (RemoteAsset asset in remoteAssetsToRestore) {
|
if (localTrashedAssets.isNotEmpty) {
|
||||||
await _localFilesManager.restoreFromTrash(asset.name, asset.type.index, asset.checksum!);
|
for (final LocalTrashedAsset asset in localTrashedAssets) {
|
||||||
}
|
_logger.info("Restoring from trash, localId: ${asset.localId}, remoteId: ${asset.remoteId}");
|
||||||
|
final type = remoteAssetMap[asset.remoteId]!;
|
||||||
|
await _localFilesManager.restoreFromTrashById(asset.localId, type.index);
|
||||||
|
await _localAssetRepository.deleteLocalTrashedAssets(remoteAssetMap.keys);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_logger.info("No local assets found for restoration");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_logger.info("No remote assets found for restoration");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
import 'package:drift/drift.dart';
|
||||||
|
import 'package:immich_mobile/domain/models/local_trashed_asset.model.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/entities/local_trashed_asset.entity.drift.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/utils/drift_default.mixin.dart';
|
||||||
|
|
||||||
|
@TableIndex.sql(
|
||||||
|
'CREATE INDEX IF NOT EXISTS idx_local_trashed_asset_remote_id ON local_trashed_asset_entity (remote_id)',
|
||||||
|
)
|
||||||
|
class LocalTrashedAssetEntity extends Table with DriftDefaultsMixin {
|
||||||
|
const LocalTrashedAssetEntity();
|
||||||
|
|
||||||
|
TextColumn get id => text()();
|
||||||
|
|
||||||
|
TextColumn get remoteId => text().references(RemoteAssetEntity, #id, onDelete: KeyAction.cascade)();
|
||||||
|
|
||||||
|
DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Set<Column> get primaryKey => {id};
|
||||||
|
}
|
||||||
|
|
||||||
|
extension LocalTrashedAssetEntityDataDomainExtension on LocalTrashedAssetEntityData {
|
||||||
|
LocalTrashedAsset toDto() => LocalTrashedAsset(localId: id, remoteId: remoteId, createdAt: createdAt);
|
||||||
|
}
|
||||||
614
mobile/lib/infrastructure/entities/local_trashed_asset.entity.drift.dart
generated
Normal file
614
mobile/lib/infrastructure/entities/local_trashed_asset.entity.drift.dart
generated
Normal file
|
|
@ -0,0 +1,614 @@
|
||||||
|
// dart format width=80
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
import 'package:drift/drift.dart' as i0;
|
||||||
|
import 'package:immich_mobile/infrastructure/entities/local_trashed_asset.entity.drift.dart'
|
||||||
|
as i1;
|
||||||
|
import 'package:immich_mobile/infrastructure/entities/local_trashed_asset.entity.dart'
|
||||||
|
as i2;
|
||||||
|
import 'package:drift/src/runtime/query_builder/query_builder.dart' as i3;
|
||||||
|
import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.drift.dart'
|
||||||
|
as i4;
|
||||||
|
import 'package:drift/internal/modular.dart' as i5;
|
||||||
|
|
||||||
|
typedef $$LocalTrashedAssetEntityTableCreateCompanionBuilder =
|
||||||
|
i1.LocalTrashedAssetEntityCompanion Function({
|
||||||
|
required String id,
|
||||||
|
required String remoteId,
|
||||||
|
i0.Value<DateTime> createdAt,
|
||||||
|
});
|
||||||
|
typedef $$LocalTrashedAssetEntityTableUpdateCompanionBuilder =
|
||||||
|
i1.LocalTrashedAssetEntityCompanion Function({
|
||||||
|
i0.Value<String> id,
|
||||||
|
i0.Value<String> remoteId,
|
||||||
|
i0.Value<DateTime> createdAt,
|
||||||
|
});
|
||||||
|
|
||||||
|
final class $$LocalTrashedAssetEntityTableReferences
|
||||||
|
extends
|
||||||
|
i0.BaseReferences<
|
||||||
|
i0.GeneratedDatabase,
|
||||||
|
i1.$LocalTrashedAssetEntityTable,
|
||||||
|
i1.LocalTrashedAssetEntityData
|
||||||
|
> {
|
||||||
|
$$LocalTrashedAssetEntityTableReferences(
|
||||||
|
super.$_db,
|
||||||
|
super.$_table,
|
||||||
|
super.$_typedResult,
|
||||||
|
);
|
||||||
|
|
||||||
|
static i4.$RemoteAssetEntityTable _remoteIdTable(i0.GeneratedDatabase db) =>
|
||||||
|
i5.ReadDatabaseContainer(db)
|
||||||
|
.resultSet<i4.$RemoteAssetEntityTable>('remote_asset_entity')
|
||||||
|
.createAlias(
|
||||||
|
i0.$_aliasNameGenerator(
|
||||||
|
i5.ReadDatabaseContainer(db)
|
||||||
|
.resultSet<i1.$LocalTrashedAssetEntityTable>(
|
||||||
|
'local_trashed_asset_entity',
|
||||||
|
)
|
||||||
|
.remoteId,
|
||||||
|
i5.ReadDatabaseContainer(
|
||||||
|
db,
|
||||||
|
).resultSet<i4.$RemoteAssetEntityTable>('remote_asset_entity').id,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
i4.$$RemoteAssetEntityTableProcessedTableManager get remoteId {
|
||||||
|
final $_column = $_itemColumn<String>('remote_id')!;
|
||||||
|
|
||||||
|
final manager = i4
|
||||||
|
.$$RemoteAssetEntityTableTableManager(
|
||||||
|
$_db,
|
||||||
|
i5.ReadDatabaseContainer(
|
||||||
|
$_db,
|
||||||
|
).resultSet<i4.$RemoteAssetEntityTable>('remote_asset_entity'),
|
||||||
|
)
|
||||||
|
.filter((f) => f.id.sqlEquals($_column));
|
||||||
|
final item = $_typedResult.readTableOrNull(_remoteIdTable($_db));
|
||||||
|
if (item == null) return manager;
|
||||||
|
return i0.ProcessedTableManager(
|
||||||
|
manager.$state.copyWith(prefetchedData: [item]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class $$LocalTrashedAssetEntityTableFilterComposer
|
||||||
|
extends
|
||||||
|
i0.Composer<i0.GeneratedDatabase, i1.$LocalTrashedAssetEntityTable> {
|
||||||
|
$$LocalTrashedAssetEntityTableFilterComposer({
|
||||||
|
required super.$db,
|
||||||
|
required super.$table,
|
||||||
|
super.joinBuilder,
|
||||||
|
super.$addJoinBuilderToRootComposer,
|
||||||
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
i0.ColumnFilters<String> get id => $composableBuilder(
|
||||||
|
column: $table.id,
|
||||||
|
builder: (column) => i0.ColumnFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
i0.ColumnFilters<DateTime> get createdAt => $composableBuilder(
|
||||||
|
column: $table.createdAt,
|
||||||
|
builder: (column) => i0.ColumnFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
i4.$$RemoteAssetEntityTableFilterComposer get remoteId {
|
||||||
|
final i4.$$RemoteAssetEntityTableFilterComposer composer = $composerBuilder(
|
||||||
|
composer: this,
|
||||||
|
getCurrentColumn: (t) => t.remoteId,
|
||||||
|
referencedTable: i5.ReadDatabaseContainer(
|
||||||
|
$db,
|
||||||
|
).resultSet<i4.$RemoteAssetEntityTable>('remote_asset_entity'),
|
||||||
|
getReferencedColumn: (t) => t.id,
|
||||||
|
builder:
|
||||||
|
(
|
||||||
|
joinBuilder, {
|
||||||
|
$addJoinBuilderToRootComposer,
|
||||||
|
$removeJoinBuilderFromRootComposer,
|
||||||
|
}) => i4.$$RemoteAssetEntityTableFilterComposer(
|
||||||
|
$db: $db,
|
||||||
|
$table: i5.ReadDatabaseContainer(
|
||||||
|
$db,
|
||||||
|
).resultSet<i4.$RemoteAssetEntityTable>('remote_asset_entity'),
|
||||||
|
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
|
||||||
|
joinBuilder: joinBuilder,
|
||||||
|
$removeJoinBuilderFromRootComposer:
|
||||||
|
$removeJoinBuilderFromRootComposer,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return composer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class $$LocalTrashedAssetEntityTableOrderingComposer
|
||||||
|
extends
|
||||||
|
i0.Composer<i0.GeneratedDatabase, i1.$LocalTrashedAssetEntityTable> {
|
||||||
|
$$LocalTrashedAssetEntityTableOrderingComposer({
|
||||||
|
required super.$db,
|
||||||
|
required super.$table,
|
||||||
|
super.joinBuilder,
|
||||||
|
super.$addJoinBuilderToRootComposer,
|
||||||
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
i0.ColumnOrderings<String> get id => $composableBuilder(
|
||||||
|
column: $table.id,
|
||||||
|
builder: (column) => i0.ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
i0.ColumnOrderings<DateTime> get createdAt => $composableBuilder(
|
||||||
|
column: $table.createdAt,
|
||||||
|
builder: (column) => i0.ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
|
||||||
|
i4.$$RemoteAssetEntityTableOrderingComposer get remoteId {
|
||||||
|
final i4.$$RemoteAssetEntityTableOrderingComposer composer =
|
||||||
|
$composerBuilder(
|
||||||
|
composer: this,
|
||||||
|
getCurrentColumn: (t) => t.remoteId,
|
||||||
|
referencedTable: i5.ReadDatabaseContainer(
|
||||||
|
$db,
|
||||||
|
).resultSet<i4.$RemoteAssetEntityTable>('remote_asset_entity'),
|
||||||
|
getReferencedColumn: (t) => t.id,
|
||||||
|
builder:
|
||||||
|
(
|
||||||
|
joinBuilder, {
|
||||||
|
$addJoinBuilderToRootComposer,
|
||||||
|
$removeJoinBuilderFromRootComposer,
|
||||||
|
}) => i4.$$RemoteAssetEntityTableOrderingComposer(
|
||||||
|
$db: $db,
|
||||||
|
$table: i5.ReadDatabaseContainer(
|
||||||
|
$db,
|
||||||
|
).resultSet<i4.$RemoteAssetEntityTable>('remote_asset_entity'),
|
||||||
|
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
|
||||||
|
joinBuilder: joinBuilder,
|
||||||
|
$removeJoinBuilderFromRootComposer:
|
||||||
|
$removeJoinBuilderFromRootComposer,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return composer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class $$LocalTrashedAssetEntityTableAnnotationComposer
|
||||||
|
extends
|
||||||
|
i0.Composer<i0.GeneratedDatabase, i1.$LocalTrashedAssetEntityTable> {
|
||||||
|
$$LocalTrashedAssetEntityTableAnnotationComposer({
|
||||||
|
required super.$db,
|
||||||
|
required super.$table,
|
||||||
|
super.joinBuilder,
|
||||||
|
super.$addJoinBuilderToRootComposer,
|
||||||
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
i0.GeneratedColumn<String> get id =>
|
||||||
|
$composableBuilder(column: $table.id, builder: (column) => column);
|
||||||
|
|
||||||
|
i0.GeneratedColumn<DateTime> get createdAt =>
|
||||||
|
$composableBuilder(column: $table.createdAt, builder: (column) => column);
|
||||||
|
|
||||||
|
i4.$$RemoteAssetEntityTableAnnotationComposer get remoteId {
|
||||||
|
final i4.$$RemoteAssetEntityTableAnnotationComposer composer =
|
||||||
|
$composerBuilder(
|
||||||
|
composer: this,
|
||||||
|
getCurrentColumn: (t) => t.remoteId,
|
||||||
|
referencedTable: i5.ReadDatabaseContainer(
|
||||||
|
$db,
|
||||||
|
).resultSet<i4.$RemoteAssetEntityTable>('remote_asset_entity'),
|
||||||
|
getReferencedColumn: (t) => t.id,
|
||||||
|
builder:
|
||||||
|
(
|
||||||
|
joinBuilder, {
|
||||||
|
$addJoinBuilderToRootComposer,
|
||||||
|
$removeJoinBuilderFromRootComposer,
|
||||||
|
}) => i4.$$RemoteAssetEntityTableAnnotationComposer(
|
||||||
|
$db: $db,
|
||||||
|
$table: i5.ReadDatabaseContainer(
|
||||||
|
$db,
|
||||||
|
).resultSet<i4.$RemoteAssetEntityTable>('remote_asset_entity'),
|
||||||
|
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
|
||||||
|
joinBuilder: joinBuilder,
|
||||||
|
$removeJoinBuilderFromRootComposer:
|
||||||
|
$removeJoinBuilderFromRootComposer,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return composer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class $$LocalTrashedAssetEntityTableTableManager
|
||||||
|
extends
|
||||||
|
i0.RootTableManager<
|
||||||
|
i0.GeneratedDatabase,
|
||||||
|
i1.$LocalTrashedAssetEntityTable,
|
||||||
|
i1.LocalTrashedAssetEntityData,
|
||||||
|
i1.$$LocalTrashedAssetEntityTableFilterComposer,
|
||||||
|
i1.$$LocalTrashedAssetEntityTableOrderingComposer,
|
||||||
|
i1.$$LocalTrashedAssetEntityTableAnnotationComposer,
|
||||||
|
$$LocalTrashedAssetEntityTableCreateCompanionBuilder,
|
||||||
|
$$LocalTrashedAssetEntityTableUpdateCompanionBuilder,
|
||||||
|
(
|
||||||
|
i1.LocalTrashedAssetEntityData,
|
||||||
|
i1.$$LocalTrashedAssetEntityTableReferences,
|
||||||
|
),
|
||||||
|
i1.LocalTrashedAssetEntityData,
|
||||||
|
i0.PrefetchHooks Function({bool remoteId})
|
||||||
|
> {
|
||||||
|
$$LocalTrashedAssetEntityTableTableManager(
|
||||||
|
i0.GeneratedDatabase db,
|
||||||
|
i1.$LocalTrashedAssetEntityTable table,
|
||||||
|
) : super(
|
||||||
|
i0.TableManagerState(
|
||||||
|
db: db,
|
||||||
|
table: table,
|
||||||
|
createFilteringComposer: () =>
|
||||||
|
i1.$$LocalTrashedAssetEntityTableFilterComposer(
|
||||||
|
$db: db,
|
||||||
|
$table: table,
|
||||||
|
),
|
||||||
|
createOrderingComposer: () =>
|
||||||
|
i1.$$LocalTrashedAssetEntityTableOrderingComposer(
|
||||||
|
$db: db,
|
||||||
|
$table: table,
|
||||||
|
),
|
||||||
|
createComputedFieldComposer: () =>
|
||||||
|
i1.$$LocalTrashedAssetEntityTableAnnotationComposer(
|
||||||
|
$db: db,
|
||||||
|
$table: table,
|
||||||
|
),
|
||||||
|
updateCompanionCallback:
|
||||||
|
({
|
||||||
|
i0.Value<String> id = const i0.Value.absent(),
|
||||||
|
i0.Value<String> remoteId = const i0.Value.absent(),
|
||||||
|
i0.Value<DateTime> createdAt = const i0.Value.absent(),
|
||||||
|
}) => i1.LocalTrashedAssetEntityCompanion(
|
||||||
|
id: id,
|
||||||
|
remoteId: remoteId,
|
||||||
|
createdAt: createdAt,
|
||||||
|
),
|
||||||
|
createCompanionCallback:
|
||||||
|
({
|
||||||
|
required String id,
|
||||||
|
required String remoteId,
|
||||||
|
i0.Value<DateTime> createdAt = const i0.Value.absent(),
|
||||||
|
}) => i1.LocalTrashedAssetEntityCompanion.insert(
|
||||||
|
id: id,
|
||||||
|
remoteId: remoteId,
|
||||||
|
createdAt: createdAt,
|
||||||
|
),
|
||||||
|
withReferenceMapper: (p0) => p0
|
||||||
|
.map(
|
||||||
|
(e) => (
|
||||||
|
e.readTable(table),
|
||||||
|
i1.$$LocalTrashedAssetEntityTableReferences(db, table, e),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
|
prefetchHooksCallback: ({remoteId = false}) {
|
||||||
|
return i0.PrefetchHooks(
|
||||||
|
db: db,
|
||||||
|
explicitlyWatchedTables: [],
|
||||||
|
addJoins:
|
||||||
|
<
|
||||||
|
T extends i0.TableManagerState<
|
||||||
|
dynamic,
|
||||||
|
dynamic,
|
||||||
|
dynamic,
|
||||||
|
dynamic,
|
||||||
|
dynamic,
|
||||||
|
dynamic,
|
||||||
|
dynamic,
|
||||||
|
dynamic,
|
||||||
|
dynamic,
|
||||||
|
dynamic,
|
||||||
|
dynamic
|
||||||
|
>
|
||||||
|
>(state) {
|
||||||
|
if (remoteId) {
|
||||||
|
state =
|
||||||
|
state.withJoin(
|
||||||
|
currentTable: table,
|
||||||
|
currentColumn: table.remoteId,
|
||||||
|
referencedTable: i1
|
||||||
|
.$$LocalTrashedAssetEntityTableReferences
|
||||||
|
._remoteIdTable(db),
|
||||||
|
referencedColumn: i1
|
||||||
|
.$$LocalTrashedAssetEntityTableReferences
|
||||||
|
._remoteIdTable(db)
|
||||||
|
.id,
|
||||||
|
)
|
||||||
|
as T;
|
||||||
|
}
|
||||||
|
|
||||||
|
return state;
|
||||||
|
},
|
||||||
|
getPrefetchedDataCallback: (items) async {
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef $$LocalTrashedAssetEntityTableProcessedTableManager =
|
||||||
|
i0.ProcessedTableManager<
|
||||||
|
i0.GeneratedDatabase,
|
||||||
|
i1.$LocalTrashedAssetEntityTable,
|
||||||
|
i1.LocalTrashedAssetEntityData,
|
||||||
|
i1.$$LocalTrashedAssetEntityTableFilterComposer,
|
||||||
|
i1.$$LocalTrashedAssetEntityTableOrderingComposer,
|
||||||
|
i1.$$LocalTrashedAssetEntityTableAnnotationComposer,
|
||||||
|
$$LocalTrashedAssetEntityTableCreateCompanionBuilder,
|
||||||
|
$$LocalTrashedAssetEntityTableUpdateCompanionBuilder,
|
||||||
|
(
|
||||||
|
i1.LocalTrashedAssetEntityData,
|
||||||
|
i1.$$LocalTrashedAssetEntityTableReferences,
|
||||||
|
),
|
||||||
|
i1.LocalTrashedAssetEntityData,
|
||||||
|
i0.PrefetchHooks Function({bool remoteId})
|
||||||
|
>;
|
||||||
|
i0.Index get idxLocalTrashedAssetRemoteId => i0.Index(
|
||||||
|
'idx_local_trashed_asset_remote_id',
|
||||||
|
'CREATE INDEX IF NOT EXISTS idx_local_trashed_asset_remote_id ON local_trashed_asset_entity (remote_id)',
|
||||||
|
);
|
||||||
|
|
||||||
|
class $LocalTrashedAssetEntityTable extends i2.LocalTrashedAssetEntity
|
||||||
|
with
|
||||||
|
i0.TableInfo<
|
||||||
|
$LocalTrashedAssetEntityTable,
|
||||||
|
i1.LocalTrashedAssetEntityData
|
||||||
|
> {
|
||||||
|
@override
|
||||||
|
final i0.GeneratedDatabase attachedDatabase;
|
||||||
|
final String? _alias;
|
||||||
|
$LocalTrashedAssetEntityTable(this.attachedDatabase, [this._alias]);
|
||||||
|
static const i0.VerificationMeta _idMeta = const i0.VerificationMeta('id');
|
||||||
|
@override
|
||||||
|
late final i0.GeneratedColumn<String> id = i0.GeneratedColumn<String>(
|
||||||
|
'id',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
type: i0.DriftSqlType.string,
|
||||||
|
requiredDuringInsert: true,
|
||||||
|
);
|
||||||
|
static const i0.VerificationMeta _remoteIdMeta = const i0.VerificationMeta(
|
||||||
|
'remoteId',
|
||||||
|
);
|
||||||
|
@override
|
||||||
|
late final i0.GeneratedColumn<String> remoteId = i0.GeneratedColumn<String>(
|
||||||
|
'remote_id',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
type: i0.DriftSqlType.string,
|
||||||
|
requiredDuringInsert: true,
|
||||||
|
defaultConstraints: i0.GeneratedColumn.constraintIsAlways(
|
||||||
|
'REFERENCES remote_asset_entity (id) ON DELETE CASCADE',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
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: false,
|
||||||
|
defaultValue: i3.currentDateAndTime,
|
||||||
|
);
|
||||||
|
@override
|
||||||
|
List<i0.GeneratedColumn> get $columns => [id, remoteId, createdAt];
|
||||||
|
@override
|
||||||
|
String get aliasedName => _alias ?? actualTableName;
|
||||||
|
@override
|
||||||
|
String get actualTableName => $name;
|
||||||
|
static const String $name = 'local_trashed_asset_entity';
|
||||||
|
@override
|
||||||
|
i0.VerificationContext validateIntegrity(
|
||||||
|
i0.Insertable<i1.LocalTrashedAssetEntityData> 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));
|
||||||
|
} else if (isInserting) {
|
||||||
|
context.missing(_idMeta);
|
||||||
|
}
|
||||||
|
if (data.containsKey('remote_id')) {
|
||||||
|
context.handle(
|
||||||
|
_remoteIdMeta,
|
||||||
|
remoteId.isAcceptableOrUnknown(data['remote_id']!, _remoteIdMeta),
|
||||||
|
);
|
||||||
|
} else if (isInserting) {
|
||||||
|
context.missing(_remoteIdMeta);
|
||||||
|
}
|
||||||
|
if (data.containsKey('created_at')) {
|
||||||
|
context.handle(
|
||||||
|
_createdAtMeta,
|
||||||
|
createdAt.isAcceptableOrUnknown(data['created_at']!, _createdAtMeta),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Set<i0.GeneratedColumn> get $primaryKey => {id};
|
||||||
|
@override
|
||||||
|
i1.LocalTrashedAssetEntityData map(
|
||||||
|
Map<String, dynamic> data, {
|
||||||
|
String? tablePrefix,
|
||||||
|
}) {
|
||||||
|
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
|
||||||
|
return i1.LocalTrashedAssetEntityData(
|
||||||
|
id: attachedDatabase.typeMapping.read(
|
||||||
|
i0.DriftSqlType.string,
|
||||||
|
data['${effectivePrefix}id'],
|
||||||
|
)!,
|
||||||
|
remoteId: attachedDatabase.typeMapping.read(
|
||||||
|
i0.DriftSqlType.string,
|
||||||
|
data['${effectivePrefix}remote_id'],
|
||||||
|
)!,
|
||||||
|
createdAt: attachedDatabase.typeMapping.read(
|
||||||
|
i0.DriftSqlType.dateTime,
|
||||||
|
data['${effectivePrefix}created_at'],
|
||||||
|
)!,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
$LocalTrashedAssetEntityTable createAlias(String alias) {
|
||||||
|
return $LocalTrashedAssetEntityTable(attachedDatabase, alias);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get withoutRowId => true;
|
||||||
|
@override
|
||||||
|
bool get isStrict => true;
|
||||||
|
}
|
||||||
|
|
||||||
|
class LocalTrashedAssetEntityData extends i0.DataClass
|
||||||
|
implements i0.Insertable<i1.LocalTrashedAssetEntityData> {
|
||||||
|
final String id;
|
||||||
|
final String remoteId;
|
||||||
|
final DateTime createdAt;
|
||||||
|
const LocalTrashedAssetEntityData({
|
||||||
|
required this.id,
|
||||||
|
required this.remoteId,
|
||||||
|
required this.createdAt,
|
||||||
|
});
|
||||||
|
@override
|
||||||
|
Map<String, i0.Expression> toColumns(bool nullToAbsent) {
|
||||||
|
final map = <String, i0.Expression>{};
|
||||||
|
map['id'] = i0.Variable<String>(id);
|
||||||
|
map['remote_id'] = i0.Variable<String>(remoteId);
|
||||||
|
map['created_at'] = i0.Variable<DateTime>(createdAt);
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
factory LocalTrashedAssetEntityData.fromJson(
|
||||||
|
Map<String, dynamic> json, {
|
||||||
|
i0.ValueSerializer? serializer,
|
||||||
|
}) {
|
||||||
|
serializer ??= i0.driftRuntimeOptions.defaultSerializer;
|
||||||
|
return LocalTrashedAssetEntityData(
|
||||||
|
id: serializer.fromJson<String>(json['id']),
|
||||||
|
remoteId: serializer.fromJson<String>(json['remoteId']),
|
||||||
|
createdAt: serializer.fromJson<DateTime>(json['createdAt']),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson({i0.ValueSerializer? serializer}) {
|
||||||
|
serializer ??= i0.driftRuntimeOptions.defaultSerializer;
|
||||||
|
return <String, dynamic>{
|
||||||
|
'id': serializer.toJson<String>(id),
|
||||||
|
'remoteId': serializer.toJson<String>(remoteId),
|
||||||
|
'createdAt': serializer.toJson<DateTime>(createdAt),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
i1.LocalTrashedAssetEntityData copyWith({
|
||||||
|
String? id,
|
||||||
|
String? remoteId,
|
||||||
|
DateTime? createdAt,
|
||||||
|
}) => i1.LocalTrashedAssetEntityData(
|
||||||
|
id: id ?? this.id,
|
||||||
|
remoteId: remoteId ?? this.remoteId,
|
||||||
|
createdAt: createdAt ?? this.createdAt,
|
||||||
|
);
|
||||||
|
LocalTrashedAssetEntityData copyWithCompanion(
|
||||||
|
i1.LocalTrashedAssetEntityCompanion data,
|
||||||
|
) {
|
||||||
|
return LocalTrashedAssetEntityData(
|
||||||
|
id: data.id.present ? data.id.value : this.id,
|
||||||
|
remoteId: data.remoteId.present ? data.remoteId.value : this.remoteId,
|
||||||
|
createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return (StringBuffer('LocalTrashedAssetEntityData(')
|
||||||
|
..write('id: $id, ')
|
||||||
|
..write('remoteId: $remoteId, ')
|
||||||
|
..write('createdAt: $createdAt')
|
||||||
|
..write(')'))
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(id, remoteId, createdAt);
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
(other is i1.LocalTrashedAssetEntityData &&
|
||||||
|
other.id == this.id &&
|
||||||
|
other.remoteId == this.remoteId &&
|
||||||
|
other.createdAt == this.createdAt);
|
||||||
|
}
|
||||||
|
|
||||||
|
class LocalTrashedAssetEntityCompanion
|
||||||
|
extends i0.UpdateCompanion<i1.LocalTrashedAssetEntityData> {
|
||||||
|
final i0.Value<String> id;
|
||||||
|
final i0.Value<String> remoteId;
|
||||||
|
final i0.Value<DateTime> createdAt;
|
||||||
|
const LocalTrashedAssetEntityCompanion({
|
||||||
|
this.id = const i0.Value.absent(),
|
||||||
|
this.remoteId = const i0.Value.absent(),
|
||||||
|
this.createdAt = const i0.Value.absent(),
|
||||||
|
});
|
||||||
|
LocalTrashedAssetEntityCompanion.insert({
|
||||||
|
required String id,
|
||||||
|
required String remoteId,
|
||||||
|
this.createdAt = const i0.Value.absent(),
|
||||||
|
}) : id = i0.Value(id),
|
||||||
|
remoteId = i0.Value(remoteId);
|
||||||
|
static i0.Insertable<i1.LocalTrashedAssetEntityData> custom({
|
||||||
|
i0.Expression<String>? id,
|
||||||
|
i0.Expression<String>? remoteId,
|
||||||
|
i0.Expression<DateTime>? createdAt,
|
||||||
|
}) {
|
||||||
|
return i0.RawValuesInsertable({
|
||||||
|
if (id != null) 'id': id,
|
||||||
|
if (remoteId != null) 'remote_id': remoteId,
|
||||||
|
if (createdAt != null) 'created_at': createdAt,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
i1.LocalTrashedAssetEntityCompanion copyWith({
|
||||||
|
i0.Value<String>? id,
|
||||||
|
i0.Value<String>? remoteId,
|
||||||
|
i0.Value<DateTime>? createdAt,
|
||||||
|
}) {
|
||||||
|
return i1.LocalTrashedAssetEntityCompanion(
|
||||||
|
id: id ?? this.id,
|
||||||
|
remoteId: remoteId ?? this.remoteId,
|
||||||
|
createdAt: createdAt ?? this.createdAt,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, i0.Expression> toColumns(bool nullToAbsent) {
|
||||||
|
final map = <String, i0.Expression>{};
|
||||||
|
if (id.present) {
|
||||||
|
map['id'] = i0.Variable<String>(id.value);
|
||||||
|
}
|
||||||
|
if (remoteId.present) {
|
||||||
|
map['remote_id'] = i0.Variable<String>(remoteId.value);
|
||||||
|
}
|
||||||
|
if (createdAt.present) {
|
||||||
|
map['created_at'] = i0.Variable<DateTime>(createdAt.value);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return (StringBuffer('LocalTrashedAssetEntityCompanion(')
|
||||||
|
..write('id: $id, ')
|
||||||
|
..write('remoteId: $remoteId, ')
|
||||||
|
..write('createdAt: $createdAt')
|
||||||
|
..write(')'))
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -9,6 +9,7 @@ import 'package:immich_mobile/infrastructure/entities/exif.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/local_album.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/local_album.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/local_album_asset.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/local_album_asset.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/local_asset.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/local_asset.entity.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/entities/local_trashed_asset.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/memory.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/memory.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/memory_asset.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/memory_asset.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/partner.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/partner.entity.dart';
|
||||||
|
|
@ -60,6 +61,7 @@ class IsarDatabaseRepository implements IDatabaseRepository {
|
||||||
PersonEntity,
|
PersonEntity,
|
||||||
AssetFaceEntity,
|
AssetFaceEntity,
|
||||||
StoreEntity,
|
StoreEntity,
|
||||||
|
LocalTrashedAssetEntity,
|
||||||
],
|
],
|
||||||
include: {'package:immich_mobile/infrastructure/entities/merged_asset.drift'},
|
include: {'package:immich_mobile/infrastructure/entities/merged_asset.drift'},
|
||||||
)
|
)
|
||||||
|
|
@ -68,7 +70,7 @@ class Drift extends $Drift implements IDatabaseRepository {
|
||||||
: super(executor ?? driftDatabase(name: 'immich', native: const DriftNativeOptions(shareAcrossIsolates: true)));
|
: super(executor ?? driftDatabase(name: 'immich', native: const DriftNativeOptions(shareAcrossIsolates: true)));
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get schemaVersion => 9;
|
int get schemaVersion => 10;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
MigrationStrategy get migration => MigrationStrategy(
|
MigrationStrategy get migration => MigrationStrategy(
|
||||||
|
|
@ -126,6 +128,9 @@ class Drift extends $Drift implements IDatabaseRepository {
|
||||||
from8To9: (m, v9) async {
|
from8To9: (m, v9) async {
|
||||||
await m.addColumn(v9.localAlbumEntity, v9.localAlbumEntity.linkedRemoteAlbumId);
|
await m.addColumn(v9.localAlbumEntity, v9.localAlbumEntity.linkedRemoteAlbumId);
|
||||||
},
|
},
|
||||||
|
from9To10: (m, v10) async {
|
||||||
|
await m.create(v10.localTrashedAssetEntity);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -148,6 +153,7 @@ class Drift extends $Drift implements IDatabaseRepository {
|
||||||
|
|
||||||
class DriftDatabaseRepository implements IDatabaseRepository {
|
class DriftDatabaseRepository implements IDatabaseRepository {
|
||||||
final Drift _db;
|
final Drift _db;
|
||||||
|
|
||||||
const DriftDatabaseRepository(this._db);
|
const DriftDatabaseRepository(this._db);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
||||||
|
|
@ -35,9 +35,11 @@ import 'package:immich_mobile/infrastructure/entities/asset_face.entity.drift.da
|
||||||
as i16;
|
as i16;
|
||||||
import 'package:immich_mobile/infrastructure/entities/store.entity.drift.dart'
|
import 'package:immich_mobile/infrastructure/entities/store.entity.drift.dart'
|
||||||
as i17;
|
as i17;
|
||||||
import 'package:immich_mobile/infrastructure/entities/merged_asset.drift.dart'
|
import 'package:immich_mobile/infrastructure/entities/local_trashed_asset.entity.drift.dart'
|
||||||
as i18;
|
as i18;
|
||||||
import 'package:drift/internal/modular.dart' as i19;
|
import 'package:immich_mobile/infrastructure/entities/merged_asset.drift.dart'
|
||||||
|
as i19;
|
||||||
|
import 'package:drift/internal/modular.dart' as i20;
|
||||||
|
|
||||||
abstract class $Drift extends i0.GeneratedDatabase {
|
abstract class $Drift extends i0.GeneratedDatabase {
|
||||||
$Drift(i0.QueryExecutor e) : super(e);
|
$Drift(i0.QueryExecutor e) : super(e);
|
||||||
|
|
@ -72,9 +74,11 @@ abstract class $Drift extends i0.GeneratedDatabase {
|
||||||
late final i16.$AssetFaceEntityTable assetFaceEntity = i16
|
late final i16.$AssetFaceEntityTable assetFaceEntity = i16
|
||||||
.$AssetFaceEntityTable(this);
|
.$AssetFaceEntityTable(this);
|
||||||
late final i17.$StoreEntityTable storeEntity = i17.$StoreEntityTable(this);
|
late final i17.$StoreEntityTable storeEntity = i17.$StoreEntityTable(this);
|
||||||
i18.MergedAssetDrift get mergedAssetDrift => i19.ReadDatabaseContainer(
|
late final i18.$LocalTrashedAssetEntityTable localTrashedAssetEntity = i18
|
||||||
|
.$LocalTrashedAssetEntityTable(this);
|
||||||
|
i19.MergedAssetDrift get mergedAssetDrift => i20.ReadDatabaseContainer(
|
||||||
this,
|
this,
|
||||||
).accessor<i18.MergedAssetDrift>(i18.MergedAssetDrift.new);
|
).accessor<i19.MergedAssetDrift>(i19.MergedAssetDrift.new);
|
||||||
@override
|
@override
|
||||||
Iterable<i0.TableInfo<i0.Table, Object?>> get allTables =>
|
Iterable<i0.TableInfo<i0.Table, Object?>> get allTables =>
|
||||||
allSchemaEntities.whereType<i0.TableInfo<i0.Table, Object?>>();
|
allSchemaEntities.whereType<i0.TableInfo<i0.Table, Object?>>();
|
||||||
|
|
@ -102,7 +106,9 @@ abstract class $Drift extends i0.GeneratedDatabase {
|
||||||
personEntity,
|
personEntity,
|
||||||
assetFaceEntity,
|
assetFaceEntity,
|
||||||
storeEntity,
|
storeEntity,
|
||||||
|
localTrashedAssetEntity,
|
||||||
i10.idxLatLng,
|
i10.idxLatLng,
|
||||||
|
i18.idxLocalTrashedAssetRemoteId,
|
||||||
];
|
];
|
||||||
@override
|
@override
|
||||||
i0.StreamQueryUpdateRules
|
i0.StreamQueryUpdateRules
|
||||||
|
|
@ -282,6 +288,18 @@ abstract class $Drift extends i0.GeneratedDatabase {
|
||||||
),
|
),
|
||||||
result: [i0.TableUpdate('asset_face_entity', kind: i0.UpdateKind.update)],
|
result: [i0.TableUpdate('asset_face_entity', kind: i0.UpdateKind.update)],
|
||||||
),
|
),
|
||||||
|
i0.WritePropagation(
|
||||||
|
on: i0.TableUpdateQuery.onTableName(
|
||||||
|
'remote_asset_entity',
|
||||||
|
limitUpdateKind: i0.UpdateKind.delete,
|
||||||
|
),
|
||||||
|
result: [
|
||||||
|
i0.TableUpdate(
|
||||||
|
'local_trashed_asset_entity',
|
||||||
|
kind: i0.UpdateKind.delete,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
]);
|
]);
|
||||||
@override
|
@override
|
||||||
i0.DriftDatabaseOptions get options =>
|
i0.DriftDatabaseOptions get options =>
|
||||||
|
|
@ -328,4 +346,9 @@ class $DriftManager {
|
||||||
i16.$$AssetFaceEntityTableTableManager(_db, _db.assetFaceEntity);
|
i16.$$AssetFaceEntityTableTableManager(_db, _db.assetFaceEntity);
|
||||||
i17.$$StoreEntityTableTableManager get storeEntity =>
|
i17.$$StoreEntityTableTableManager get storeEntity =>
|
||||||
i17.$$StoreEntityTableTableManager(_db, _db.storeEntity);
|
i17.$$StoreEntityTableTableManager(_db, _db.storeEntity);
|
||||||
|
i18.$$LocalTrashedAssetEntityTableTableManager get localTrashedAssetEntity =>
|
||||||
|
i18.$$LocalTrashedAssetEntityTableTableManager(
|
||||||
|
_db,
|
||||||
|
_db.localTrashedAssetEntity,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3820,6 +3820,394 @@ i1.GeneratedColumn<String> _column_90(String aliasedName) =>
|
||||||
'REFERENCES remote_album_entity (id) ON DELETE SET NULL',
|
'REFERENCES remote_album_entity (id) ON DELETE SET NULL',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final class Schema10 extends i0.VersionedSchema {
|
||||||
|
Schema10({required super.database}) : super(version: 10);
|
||||||
|
@override
|
||||||
|
late final List<i1.DatabaseSchemaEntity> entities = [
|
||||||
|
userEntity,
|
||||||
|
remoteAssetEntity,
|
||||||
|
stackEntity,
|
||||||
|
localAssetEntity,
|
||||||
|
remoteAlbumEntity,
|
||||||
|
localAlbumEntity,
|
||||||
|
localAlbumAssetEntity,
|
||||||
|
idxLocalAssetChecksum,
|
||||||
|
idxRemoteAssetOwnerChecksum,
|
||||||
|
uQRemoteAssetsOwnerChecksum,
|
||||||
|
uQRemoteAssetsOwnerLibraryChecksum,
|
||||||
|
idxRemoteAssetChecksum,
|
||||||
|
userMetadataEntity,
|
||||||
|
partnerEntity,
|
||||||
|
remoteExifEntity,
|
||||||
|
remoteAlbumAssetEntity,
|
||||||
|
remoteAlbumUserEntity,
|
||||||
|
memoryEntity,
|
||||||
|
memoryAssetEntity,
|
||||||
|
personEntity,
|
||||||
|
assetFaceEntity,
|
||||||
|
storeEntity,
|
||||||
|
localTrashedAssetEntity,
|
||||||
|
idxLatLng,
|
||||||
|
idxLocalTrashedAssetChecksum,
|
||||||
|
];
|
||||||
|
late final Shape16 userEntity = Shape16(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'user_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(id)'],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_1,
|
||||||
|
_column_2,
|
||||||
|
_column_3,
|
||||||
|
_column_84,
|
||||||
|
_column_85,
|
||||||
|
_column_5,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape17 remoteAssetEntity = Shape17(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'remote_asset_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(id)'],
|
||||||
|
columns: [
|
||||||
|
_column_1,
|
||||||
|
_column_8,
|
||||||
|
_column_9,
|
||||||
|
_column_5,
|
||||||
|
_column_10,
|
||||||
|
_column_11,
|
||||||
|
_column_12,
|
||||||
|
_column_0,
|
||||||
|
_column_13,
|
||||||
|
_column_14,
|
||||||
|
_column_15,
|
||||||
|
_column_16,
|
||||||
|
_column_17,
|
||||||
|
_column_18,
|
||||||
|
_column_19,
|
||||||
|
_column_20,
|
||||||
|
_column_21,
|
||||||
|
_column_86,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape3 stackEntity = Shape3(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'stack_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(id)'],
|
||||||
|
columns: [_column_0, _column_9, _column_5, _column_15, _column_75],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape2 localAssetEntity = Shape2(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'local_asset_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(id)'],
|
||||||
|
columns: [
|
||||||
|
_column_1,
|
||||||
|
_column_8,
|
||||||
|
_column_9,
|
||||||
|
_column_5,
|
||||||
|
_column_10,
|
||||||
|
_column_11,
|
||||||
|
_column_12,
|
||||||
|
_column_0,
|
||||||
|
_column_22,
|
||||||
|
_column_14,
|
||||||
|
_column_23,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape9 remoteAlbumEntity = Shape9(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'remote_album_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(id)'],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_1,
|
||||||
|
_column_56,
|
||||||
|
_column_9,
|
||||||
|
_column_5,
|
||||||
|
_column_15,
|
||||||
|
_column_57,
|
||||||
|
_column_58,
|
||||||
|
_column_59,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape19 localAlbumEntity = Shape19(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'local_album_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(id)'],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_1,
|
||||||
|
_column_5,
|
||||||
|
_column_31,
|
||||||
|
_column_32,
|
||||||
|
_column_90,
|
||||||
|
_column_33,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape7 localAlbumAssetEntity = Shape7(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'local_album_asset_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(asset_id, album_id)'],
|
||||||
|
columns: [_column_34, _column_35],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
final i1.Index idxLocalAssetChecksum = i1.Index(
|
||||||
|
'idx_local_asset_checksum',
|
||||||
|
'CREATE INDEX IF NOT EXISTS idx_local_asset_checksum ON local_asset_entity (checksum)',
|
||||||
|
);
|
||||||
|
final i1.Index idxRemoteAssetOwnerChecksum = i1.Index(
|
||||||
|
'idx_remote_asset_owner_checksum',
|
||||||
|
'CREATE INDEX IF NOT EXISTS idx_remote_asset_owner_checksum ON remote_asset_entity (owner_id, checksum)',
|
||||||
|
);
|
||||||
|
final i1.Index uQRemoteAssetsOwnerChecksum = i1.Index(
|
||||||
|
'UQ_remote_assets_owner_checksum',
|
||||||
|
'CREATE UNIQUE INDEX IF NOT EXISTS UQ_remote_assets_owner_checksum ON remote_asset_entity (owner_id, checksum) WHERE(library_id IS NULL)',
|
||||||
|
);
|
||||||
|
final i1.Index uQRemoteAssetsOwnerLibraryChecksum = i1.Index(
|
||||||
|
'UQ_remote_assets_owner_library_checksum',
|
||||||
|
'CREATE UNIQUE INDEX IF NOT EXISTS UQ_remote_assets_owner_library_checksum ON remote_asset_entity (owner_id, library_id, checksum) WHERE(library_id IS NOT NULL)',
|
||||||
|
);
|
||||||
|
final i1.Index idxRemoteAssetChecksum = i1.Index(
|
||||||
|
'idx_remote_asset_checksum',
|
||||||
|
'CREATE INDEX IF NOT EXISTS idx_remote_asset_checksum ON remote_asset_entity (checksum)',
|
||||||
|
);
|
||||||
|
late final Shape4 userMetadataEntity = Shape4(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'user_metadata_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(user_id, "key")'],
|
||||||
|
columns: [_column_25, _column_26, _column_27],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape5 partnerEntity = Shape5(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'partner_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(shared_by_id, shared_with_id)'],
|
||||||
|
columns: [_column_28, _column_29, _column_30],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape8 remoteExifEntity = Shape8(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'remote_exif_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(asset_id)'],
|
||||||
|
columns: [
|
||||||
|
_column_36,
|
||||||
|
_column_37,
|
||||||
|
_column_38,
|
||||||
|
_column_39,
|
||||||
|
_column_40,
|
||||||
|
_column_41,
|
||||||
|
_column_11,
|
||||||
|
_column_10,
|
||||||
|
_column_42,
|
||||||
|
_column_43,
|
||||||
|
_column_44,
|
||||||
|
_column_45,
|
||||||
|
_column_46,
|
||||||
|
_column_47,
|
||||||
|
_column_48,
|
||||||
|
_column_49,
|
||||||
|
_column_50,
|
||||||
|
_column_51,
|
||||||
|
_column_52,
|
||||||
|
_column_53,
|
||||||
|
_column_54,
|
||||||
|
_column_55,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape7 remoteAlbumAssetEntity = Shape7(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'remote_album_asset_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(asset_id, album_id)'],
|
||||||
|
columns: [_column_36, _column_60],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape10 remoteAlbumUserEntity = Shape10(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'remote_album_user_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(album_id, user_id)'],
|
||||||
|
columns: [_column_60, _column_25, _column_61],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape11 memoryEntity = Shape11(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'memory_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(id)'],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_9,
|
||||||
|
_column_5,
|
||||||
|
_column_18,
|
||||||
|
_column_15,
|
||||||
|
_column_8,
|
||||||
|
_column_62,
|
||||||
|
_column_63,
|
||||||
|
_column_64,
|
||||||
|
_column_65,
|
||||||
|
_column_66,
|
||||||
|
_column_67,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape12 memoryAssetEntity = Shape12(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'memory_asset_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(asset_id, memory_id)'],
|
||||||
|
columns: [_column_36, _column_68],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape14 personEntity = Shape14(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'person_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(id)'],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_9,
|
||||||
|
_column_5,
|
||||||
|
_column_15,
|
||||||
|
_column_1,
|
||||||
|
_column_69,
|
||||||
|
_column_71,
|
||||||
|
_column_72,
|
||||||
|
_column_73,
|
||||||
|
_column_74,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape15 assetFaceEntity = Shape15(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'asset_face_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(id)'],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_36,
|
||||||
|
_column_76,
|
||||||
|
_column_77,
|
||||||
|
_column_78,
|
||||||
|
_column_79,
|
||||||
|
_column_80,
|
||||||
|
_column_81,
|
||||||
|
_column_82,
|
||||||
|
_column_83,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape18 storeEntity = Shape18(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'store_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(id)'],
|
||||||
|
columns: [_column_87, _column_88, _column_89],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape20 localTrashedAssetEntity = Shape20(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'local_trashed_asset_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(id)'],
|
||||||
|
columns: [_column_0, _column_36, _column_13, _column_1, _column_9],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
final i1.Index idxLatLng = i1.Index(
|
||||||
|
'idx_lat_lng',
|
||||||
|
'CREATE INDEX IF NOT EXISTS idx_lat_lng ON remote_exif_entity (latitude, longitude)',
|
||||||
|
);
|
||||||
|
final i1.Index idxLocalTrashedAssetChecksum = i1.Index(
|
||||||
|
'idx_local_trashed_asset_checksum',
|
||||||
|
'CREATE INDEX IF NOT EXISTS idx_local_trashed_asset_checksum ON local_trashed_asset_entity (checksum)',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Shape20 extends i0.VersionedTable {
|
||||||
|
Shape20({required super.source, required super.alias}) : super.aliased();
|
||||||
|
i1.GeneratedColumn<String> get id =>
|
||||||
|
columnsByName['id']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<String> get assetId =>
|
||||||
|
columnsByName['asset_id']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<String> get checksum =>
|
||||||
|
columnsByName['checksum']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<String> get name =>
|
||||||
|
columnsByName['name']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<DateTime> get createdAt =>
|
||||||
|
columnsByName['created_at']! as i1.GeneratedColumn<DateTime>;
|
||||||
|
}
|
||||||
|
|
||||||
i0.MigrationStepWithVersion migrationSteps({
|
i0.MigrationStepWithVersion migrationSteps({
|
||||||
required Future<void> Function(i1.Migrator m, Schema2 schema) from1To2,
|
required Future<void> Function(i1.Migrator m, Schema2 schema) from1To2,
|
||||||
required Future<void> Function(i1.Migrator m, Schema3 schema) from2To3,
|
required Future<void> Function(i1.Migrator m, Schema3 schema) from2To3,
|
||||||
|
|
@ -3829,6 +4217,7 @@ i0.MigrationStepWithVersion migrationSteps({
|
||||||
required Future<void> Function(i1.Migrator m, Schema7 schema) from6To7,
|
required Future<void> Function(i1.Migrator m, Schema7 schema) from6To7,
|
||||||
required Future<void> Function(i1.Migrator m, Schema8 schema) from7To8,
|
required Future<void> Function(i1.Migrator m, Schema8 schema) from7To8,
|
||||||
required Future<void> Function(i1.Migrator m, Schema9 schema) from8To9,
|
required Future<void> Function(i1.Migrator m, Schema9 schema) from8To9,
|
||||||
|
required Future<void> Function(i1.Migrator m, Schema10 schema) from9To10,
|
||||||
}) {
|
}) {
|
||||||
return (currentVersion, database) async {
|
return (currentVersion, database) async {
|
||||||
switch (currentVersion) {
|
switch (currentVersion) {
|
||||||
|
|
@ -3872,6 +4261,11 @@ i0.MigrationStepWithVersion migrationSteps({
|
||||||
final migrator = i1.Migrator(database, schema);
|
final migrator = i1.Migrator(database, schema);
|
||||||
await from8To9(migrator, schema);
|
await from8To9(migrator, schema);
|
||||||
return 9;
|
return 9;
|
||||||
|
case 9:
|
||||||
|
final schema = Schema10(database: database);
|
||||||
|
final migrator = i1.Migrator(database, schema);
|
||||||
|
await from9To10(migrator, schema);
|
||||||
|
return 10;
|
||||||
default:
|
default:
|
||||||
throw ArgumentError.value('Unknown migration from $currentVersion');
|
throw ArgumentError.value('Unknown migration from $currentVersion');
|
||||||
}
|
}
|
||||||
|
|
@ -3887,6 +4281,7 @@ i1.OnUpgrade stepByStep({
|
||||||
required Future<void> Function(i1.Migrator m, Schema7 schema) from6To7,
|
required Future<void> Function(i1.Migrator m, Schema7 schema) from6To7,
|
||||||
required Future<void> Function(i1.Migrator m, Schema8 schema) from7To8,
|
required Future<void> Function(i1.Migrator m, Schema8 schema) from7To8,
|
||||||
required Future<void> Function(i1.Migrator m, Schema9 schema) from8To9,
|
required Future<void> Function(i1.Migrator m, Schema9 schema) from8To9,
|
||||||
|
required Future<void> Function(i1.Migrator m, Schema10 schema) from9To10,
|
||||||
}) => i0.VersionedSchema.stepByStepHelper(
|
}) => i0.VersionedSchema.stepByStepHelper(
|
||||||
step: migrationSteps(
|
step: migrationSteps(
|
||||||
from1To2: from1To2,
|
from1To2: from1To2,
|
||||||
|
|
@ -3897,5 +4292,6 @@ i1.OnUpgrade stepByStep({
|
||||||
from6To7: from6To7,
|
from6To7: from6To7,
|
||||||
from7To8: from7To8,
|
from7To8: from7To8,
|
||||||
from8To9: from8To9,
|
from8To9: from8To9,
|
||||||
|
from9To10: from9To10,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,15 @@ import 'package:collection/collection.dart';
|
||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:immich_mobile/domain/models/album/local_album.model.dart';
|
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/domain/models/local_trashed_asset.model.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/local_asset.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/local_asset.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/local_asset.entity.drift.dart';
|
import 'package:immich_mobile/infrastructure/entities/local_asset.entity.drift.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/entities/local_trashed_asset.entity.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/entities/local_trashed_asset.entity.drift.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||||
|
|
||||||
|
typedef LocalRemoteIds = ({String localId, String remoteId});
|
||||||
|
|
||||||
class DriftLocalAssetRepository extends DriftDatabaseRepository {
|
class DriftLocalAssetRepository extends DriftDatabaseRepository {
|
||||||
final Drift _db;
|
final Drift _db;
|
||||||
|
|
||||||
|
|
@ -58,6 +63,31 @@ class DriftLocalAssetRepository extends DriftDatabaseRepository {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> trash(Iterable<LocalRemoteIds> ids) async {
|
||||||
|
if (ids.isEmpty) return;
|
||||||
|
|
||||||
|
final Map<String, String> idToRemote = {for (final e in ids) e.localId: e.remoteId};
|
||||||
|
|
||||||
|
final localRows = await (_db.localAssetEntity.select()..where((t) => t.id.isIn(idToRemote.keys))).get();
|
||||||
|
|
||||||
|
await _db.batch((batch) {
|
||||||
|
for (final row in localRows) {
|
||||||
|
final remoteId = idToRemote[row.id];
|
||||||
|
if (remoteId == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
batch.insert(
|
||||||
|
_db.localTrashedAssetEntity,
|
||||||
|
LocalTrashedAssetEntityCompanion(id: Value(row.id), remoteId: Value(remoteId)),
|
||||||
|
mode: InsertMode.insertOrReplace,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
for (final slice in idToRemote.keys.slices(32000)) {
|
||||||
|
batch.deleteWhere(_db.localAssetEntity, (e) => e.id.isIn(slice));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Future<LocalAsset?> getById(String id) {
|
Future<LocalAsset?> getById(String id) {
|
||||||
final query = _db.localAssetEntity.select()..where((lae) => lae.id.equals(id));
|
final query = _db.localAssetEntity.select()..where((lae) => lae.id.equals(id));
|
||||||
|
|
||||||
|
|
@ -90,4 +120,23 @@ class DriftLocalAssetRepository extends DriftDatabaseRepository {
|
||||||
..where((la) => la.checksum.isIn(checksums) & la.id.isInQuery(backedUpAssetIds));
|
..where((la) => la.checksum.isIn(checksums) & la.id.isInQuery(backedUpAssetIds));
|
||||||
return query.map((row) => row.toDto()).get();
|
return query.map((row) => row.toDto()).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<List<LocalTrashedAsset>> getLocalTrashedAssets(Iterable<String> remoteIds) {
|
||||||
|
if (remoteIds.isEmpty) {
|
||||||
|
return Future.value([]);
|
||||||
|
}
|
||||||
|
final query = _db.localTrashedAssetEntity.select()..where((t) => t.remoteId.isIn(remoteIds));
|
||||||
|
return query.map((row) => row.toDto()).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> deleteLocalTrashedAssets(Iterable<String> remoteIds) {
|
||||||
|
if (remoteIds.isEmpty) {
|
||||||
|
return Future.value();
|
||||||
|
}
|
||||||
|
return _db.batch((batch) {
|
||||||
|
for (final slice in remoteIds.slices(32000)) {
|
||||||
|
batch.deleteWhere(_db.localTrashedAssetEntity, (e) => e.remoteId.isIn(slice));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,10 @@ class LocalFilesManagerRepository {
|
||||||
return await _service.restoreFromTrash(fileName, type, checksum);
|
return await _service.restoreFromTrash(fileName, type, checksum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<bool> restoreFromTrashById(String mediaId, int type) async {
|
||||||
|
return await _service.restoreFromTrashById(mediaId, type);
|
||||||
|
}
|
||||||
|
|
||||||
Future<bool> requestManageMediaPermission() async {
|
Future<bool> requestManageMediaPermission() async {
|
||||||
return await _service.requestManageMediaPermission();
|
return await _service.requestManageMediaPermission();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,15 @@ class LocalFilesManagerService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<bool> restoreFromTrashById(String mediaId, int type) async {
|
||||||
|
try {
|
||||||
|
return await _channel.invokeMethod('restoreFromTrash', {'mediaId': mediaId, 'type': type});
|
||||||
|
} catch (e, s) {
|
||||||
|
_logger.warning('Error restore file from trash by Id', e, s);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<bool> requestManageMediaPermission() async {
|
Future<bool> requestManageMediaPermission() async {
|
||||||
try {
|
try {
|
||||||
return await _channel.invokeMethod('requestManageMediaPermission');
|
return await _channel.invokeMethod('requestManageMediaPermission');
|
||||||
|
|
|
||||||
5
mobile/test/drift/main/generated/schema.dart
generated
5
mobile/test/drift/main/generated/schema.dart
generated
|
|
@ -12,6 +12,7 @@ import 'schema_v6.dart' as v6;
|
||||||
import 'schema_v7.dart' as v7;
|
import 'schema_v7.dart' as v7;
|
||||||
import 'schema_v8.dart' as v8;
|
import 'schema_v8.dart' as v8;
|
||||||
import 'schema_v9.dart' as v9;
|
import 'schema_v9.dart' as v9;
|
||||||
|
import 'schema_v10.dart' as v10;
|
||||||
|
|
||||||
class GeneratedHelper implements SchemaInstantiationHelper {
|
class GeneratedHelper implements SchemaInstantiationHelper {
|
||||||
@override
|
@override
|
||||||
|
|
@ -35,10 +36,12 @@ class GeneratedHelper implements SchemaInstantiationHelper {
|
||||||
return v8.DatabaseAtV8(db);
|
return v8.DatabaseAtV8(db);
|
||||||
case 9:
|
case 9:
|
||||||
return v9.DatabaseAtV9(db);
|
return v9.DatabaseAtV9(db);
|
||||||
|
case 10:
|
||||||
|
return v10.DatabaseAtV10(db);
|
||||||
default:
|
default:
|
||||||
throw MissingSchemaException(version, versions);
|
throw MissingSchemaException(version, versions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const versions = const [1, 2, 3, 4, 5, 6, 7, 8, 9];
|
static const versions = const [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
7011
mobile/test/drift/main/generated/schema_v10.dart
generated
Normal file
7011
mobile/test/drift/main/generated/schema_v10.dart
generated
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue