pull/28141/merge
Peter Ombodi 2026-05-29 22:46:45 +02:00 committed by GitHub
commit 2c9eeb5ec4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 13965 additions and 110 deletions

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,7 @@ import 'stack.entity.dart';
import 'local_asset.entity.dart';
import 'local_album.entity.dart';
import 'local_album_asset.entity.dart';
import 'visible_stack_representative.drift';
mergedAsset:
SELECT
@ -32,14 +33,14 @@ SELECT
FROM
remote_asset_entity rae
LEFT JOIN
stack_entity se ON rae.stack_id = se.id
visible_stack_representative vsr ON rae.stack_id = vsr.stack_id AND rae.owner_id = vsr.owner_id
WHERE
rae.deleted_at IS NULL
AND rae.visibility = 0 -- timeline visibility
AND rae.owner_id IN :user_ids
AND (
rae.stack_id IS NULL
OR rae.id = se.primary_asset_id
OR rae.id = vsr.asset_id
)
UNION ALL
@ -106,14 +107,14 @@ FROM
FROM
remote_asset_entity rae
LEFT JOIN
stack_entity se ON rae.stack_id = se.id
visible_stack_representative vsr ON rae.stack_id = vsr.stack_id AND rae.owner_id = vsr.owner_id
WHERE
rae.deleted_at IS NULL
AND rae.visibility = 0 -- timeline visibility
AND rae.owner_id in :user_ids
AND (
rae.stack_id IS NULL
OR rae.id = se.primary_asset_id
OR rae.id = vsr.asset_id
)
UNION ALL
SELECT

View File

@ -7,12 +7,14 @@ import 'package:immich_mobile/infrastructure/entities/local_asset.entity.drift.d
as i3;
import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.drift.dart'
as i4;
import 'package:immich_mobile/infrastructure/entities/stack.entity.drift.dart'
import 'package:immich_mobile/infrastructure/entities/visible_stack_representative.drift.dart'
as i5;
import 'package:immich_mobile/infrastructure/entities/local_album_asset.entity.drift.dart'
as i6;
import 'package:immich_mobile/infrastructure/entities/local_album.entity.drift.dart'
as i7;
import 'package:immich_mobile/infrastructure/entities/stack.entity.drift.dart'
as i8;
class MergedAssetDrift extends i1.ModularAccessor {
MergedAssetDrift(i0.GeneratedDatabase db) : super(db);
@ -29,7 +31,7 @@ class MergedAssetDrift extends i1.ModularAccessor {
);
$arrayStartIndex += generatedlimit.amountOfVariables;
return customSelect(
'SELECT rae.id AS remote_id, (SELECT lae.id FROM local_asset_entity AS lae WHERE lae.checksum = rae.checksum LIMIT 1) AS local_id, rae.name, rae.type, rae.created_at AS created_at, rae.updated_at, rae.width, rae.height, rae.duration_ms, rae.is_favorite, rae.thumb_hash, rae.checksum, rae.owner_id, rae.live_photo_video_id, 0 AS orientation, rae.stack_id, NULL AS i_cloud_id, NULL AS latitude, NULL AS longitude, NULL AS adjustmentTime, rae.is_edited, 0 AS playback_style, rae.uploaded_at FROM remote_asset_entity AS rae LEFT JOIN stack_entity AS se ON rae.stack_id = se.id WHERE rae.deleted_at IS NULL AND rae.visibility = 0 AND rae.owner_id IN ($expandeduserIds) AND(rae.stack_id IS NULL OR rae.id = se.primary_asset_id)UNION ALL SELECT NULL AS remote_id, lae.id AS local_id, lae.name, lae.type, lae.created_at AS created_at, lae.updated_at, lae.width, lae.height, lae.duration_ms, lae.is_favorite, NULL AS thumb_hash, lae.checksum, NULL AS owner_id, NULL AS live_photo_video_id, lae.orientation, NULL AS stack_id, lae.i_cloud_id, lae.latitude, lae.longitude, lae.adjustment_time, 0 AS is_edited, lae.playback_style, NULL AS uploaded_at FROM local_asset_entity AS lae WHERE NOT EXISTS (SELECT 1 FROM remote_asset_entity AS rae WHERE rae.checksum = lae.checksum AND rae.owner_id IN ($expandeduserIds)) AND EXISTS (SELECT 1 FROM local_album_asset_entity AS laa INNER JOIN local_album_entity AS la ON laa.album_id = la.id WHERE laa.asset_id = lae.id AND la.backup_selection = 0) AND NOT EXISTS (SELECT 1 FROM local_album_asset_entity AS laa INNER JOIN local_album_entity AS la ON laa.album_id = la.id WHERE laa.asset_id = lae.id AND la.backup_selection = 2) ORDER BY created_at DESC ${generatedlimit.sql}',
'SELECT rae.id AS remote_id, (SELECT lae.id FROM local_asset_entity AS lae WHERE lae.checksum = rae.checksum LIMIT 1) AS local_id, rae.name, rae.type, rae.created_at AS created_at, rae.updated_at, rae.width, rae.height, rae.duration_ms, rae.is_favorite, rae.thumb_hash, rae.checksum, rae.owner_id, rae.live_photo_video_id, 0 AS orientation, rae.stack_id, NULL AS i_cloud_id, NULL AS latitude, NULL AS longitude, NULL AS adjustmentTime, rae.is_edited, 0 AS playback_style, rae.uploaded_at FROM remote_asset_entity AS rae LEFT JOIN visible_stack_representative AS vsr ON rae.stack_id = vsr.stack_id AND rae.owner_id = vsr.owner_id WHERE rae.deleted_at IS NULL AND rae.visibility = 0 AND rae.owner_id IN ($expandeduserIds) AND(rae.stack_id IS NULL OR rae.id = vsr.asset_id)UNION ALL SELECT NULL AS remote_id, lae.id AS local_id, lae.name, lae.type, lae.created_at AS created_at, lae.updated_at, lae.width, lae.height, lae.duration_ms, lae.is_favorite, NULL AS thumb_hash, lae.checksum, NULL AS owner_id, NULL AS live_photo_video_id, lae.orientation, NULL AS stack_id, lae.i_cloud_id, lae.latitude, lae.longitude, lae.adjustment_time, 0 AS is_edited, lae.playback_style, NULL AS uploaded_at FROM local_asset_entity AS lae WHERE NOT EXISTS (SELECT 1 FROM remote_asset_entity AS rae WHERE rae.checksum = lae.checksum AND rae.owner_id IN ($expandeduserIds)) AND EXISTS (SELECT 1 FROM local_album_asset_entity AS laa INNER JOIN local_album_entity AS la ON laa.album_id = la.id WHERE laa.asset_id = lae.id AND la.backup_selection = 0) AND NOT EXISTS (SELECT 1 FROM local_album_asset_entity AS laa INNER JOIN local_album_entity AS la ON laa.album_id = la.id WHERE laa.asset_id = lae.id AND la.backup_selection = 2) ORDER BY created_at DESC ${generatedlimit.sql}',
variables: [
for (var $ in userIds) i0.Variable<String>($),
...generatedlimit.introducedVariables,
@ -37,9 +39,9 @@ class MergedAssetDrift extends i1.ModularAccessor {
readsFrom: {
remoteAssetEntity,
localAssetEntity,
stackEntity,
localAlbumAssetEntity,
localAlbumEntity,
stackEntity,
...generatedlimit.watchedTables,
},
).map(
@ -81,17 +83,17 @@ class MergedAssetDrift extends i1.ModularAccessor {
final expandeduserIds = $expandVar($arrayStartIndex, userIds.length);
$arrayStartIndex += userIds.length;
return customSelect(
'SELECT COUNT(*) AS asset_count, bucket_date FROM (SELECT CASE WHEN ?1 = 0 THEN COALESCE(STRFTIME(\'%Y-%m-%d\', rae.local_date_time), STRFTIME(\'%Y-%m-%d\', rae.created_at, \'localtime\')) WHEN ?1 = 1 THEN COALESCE(STRFTIME(\'%Y-%m\', rae.local_date_time), STRFTIME(\'%Y-%m\', rae.created_at, \'localtime\')) END AS bucket_date FROM remote_asset_entity AS rae LEFT JOIN stack_entity AS se ON rae.stack_id = se.id WHERE rae.deleted_at IS NULL AND rae.visibility = 0 AND rae.owner_id IN ($expandeduserIds) AND(rae.stack_id IS NULL OR rae.id = se.primary_asset_id)UNION ALL SELECT CASE WHEN ?1 = 0 THEN STRFTIME(\'%Y-%m-%d\', lae.created_at, \'localtime\') WHEN ?1 = 1 THEN STRFTIME(\'%Y-%m\', lae.created_at, \'localtime\') END AS bucket_date FROM local_asset_entity AS lae WHERE NOT EXISTS (SELECT 1 FROM remote_asset_entity AS rae WHERE rae.checksum = lae.checksum AND rae.owner_id IN ($expandeduserIds)) AND EXISTS (SELECT 1 FROM local_album_asset_entity AS laa INNER JOIN local_album_entity AS la ON laa.album_id = la.id WHERE laa.asset_id = lae.id AND la.backup_selection = 0) AND NOT EXISTS (SELECT 1 FROM local_album_asset_entity AS laa INNER JOIN local_album_entity AS la ON laa.album_id = la.id WHERE laa.asset_id = lae.id AND la.backup_selection = 2)) GROUP BY bucket_date ORDER BY bucket_date DESC',
'SELECT COUNT(*) AS asset_count, bucket_date FROM (SELECT CASE WHEN ?1 = 0 THEN COALESCE(STRFTIME(\'%Y-%m-%d\', rae.local_date_time), STRFTIME(\'%Y-%m-%d\', rae.created_at, \'localtime\')) WHEN ?1 = 1 THEN COALESCE(STRFTIME(\'%Y-%m\', rae.local_date_time), STRFTIME(\'%Y-%m\', rae.created_at, \'localtime\')) END AS bucket_date FROM remote_asset_entity AS rae LEFT JOIN visible_stack_representative AS vsr ON rae.stack_id = vsr.stack_id AND rae.owner_id = vsr.owner_id WHERE rae.deleted_at IS NULL AND rae.visibility = 0 AND rae.owner_id IN ($expandeduserIds) AND(rae.stack_id IS NULL OR rae.id = vsr.asset_id)UNION ALL SELECT CASE WHEN ?1 = 0 THEN STRFTIME(\'%Y-%m-%d\', lae.created_at, \'localtime\') WHEN ?1 = 1 THEN STRFTIME(\'%Y-%m\', lae.created_at, \'localtime\') END AS bucket_date FROM local_asset_entity AS lae WHERE NOT EXISTS (SELECT 1 FROM remote_asset_entity AS rae WHERE rae.checksum = lae.checksum AND rae.owner_id IN ($expandeduserIds)) AND EXISTS (SELECT 1 FROM local_album_asset_entity AS laa INNER JOIN local_album_entity AS la ON laa.album_id = la.id WHERE laa.asset_id = lae.id AND la.backup_selection = 0) AND NOT EXISTS (SELECT 1 FROM local_album_asset_entity AS laa INNER JOIN local_album_entity AS la ON laa.album_id = la.id WHERE laa.asset_id = lae.id AND la.backup_selection = 2)) GROUP BY bucket_date ORDER BY bucket_date DESC',
variables: [
i0.Variable<int>(groupBy),
for (var $ in userIds) i0.Variable<String>($),
],
readsFrom: {
remoteAssetEntity,
stackEntity,
localAssetEntity,
localAlbumAssetEntity,
localAlbumEntity,
stackEntity,
},
).map(
(i0.QueryRow row) => MergedBucketResult(
@ -104,9 +106,12 @@ class MergedAssetDrift extends i1.ModularAccessor {
i4.$RemoteAssetEntityTable get remoteAssetEntity => i1.ReadDatabaseContainer(
attachedDatabase,
).resultSet<i4.$RemoteAssetEntityTable>('remote_asset_entity');
i5.$StackEntityTable get stackEntity => i1.ReadDatabaseContainer(
attachedDatabase,
).resultSet<i5.$StackEntityTable>('stack_entity');
i5.VisibleStackRepresentative get visibleStackRepresentative =>
i1.ReadDatabaseContainer(
attachedDatabase,
).resultSet<i5.VisibleStackRepresentative>(
'visible_stack_representative',
);
i3.$LocalAssetEntityTable get localAssetEntity => i1.ReadDatabaseContainer(
attachedDatabase,
).resultSet<i3.$LocalAssetEntityTable>('local_asset_entity');
@ -117,6 +122,9 @@ class MergedAssetDrift extends i1.ModularAccessor {
i7.$LocalAlbumEntityTable get localAlbumEntity => i1.ReadDatabaseContainer(
attachedDatabase,
).resultSet<i7.$LocalAlbumEntityTable>('local_album_entity');
i8.$StackEntityTable get stackEntity => i1.ReadDatabaseContainer(
attachedDatabase,
).resultSet<i8.$StackEntityTable>('stack_entity');
}
class MergedAssetResult {

View File

@ -18,6 +18,11 @@ WHERE (library_id IS NOT NULL);
@TableIndex.sql('CREATE INDEX IF NOT EXISTS idx_remote_asset_checksum ON remote_asset_entity (checksum)')
@TableIndex.sql('CREATE INDEX IF NOT EXISTS idx_remote_asset_stack_id ON remote_asset_entity (stack_id)')
@TableIndex.sql('''
CREATE INDEX IF NOT EXISTS idx_remote_asset_visible_stack
ON remote_asset_entity (stack_id, owner_id, created_at DESC, id)
WHERE deleted_at IS NULL AND visibility = 0;
''')
@TableIndex.sql('''
CREATE INDEX IF NOT EXISTS idx_remote_asset_owner_visibility_deleted_created
ON remote_asset_entity (owner_id, visibility, deleted_at, created_at DESC)
''')

View File

@ -1775,6 +1775,10 @@ i0.Index get idxRemoteAssetStackId => i0.Index(
'idx_remote_asset_stack_id',
'CREATE INDEX IF NOT EXISTS idx_remote_asset_stack_id ON remote_asset_entity (stack_id)',
);
i0.Index get idxRemoteAssetVisibleStack => i0.Index(
'idx_remote_asset_visible_stack',
'CREATE INDEX IF NOT EXISTS idx_remote_asset_visible_stack ON remote_asset_entity (stack_id, owner_id, created_at DESC, id) WHERE deleted_at IS NULL AND visibility = 0',
);
i0.Index get idxRemoteAssetOwnerVisibilityDeletedCreated => i0.Index(
'idx_remote_asset_owner_visibility_deleted_created',
'CREATE INDEX IF NOT EXISTS idx_remote_asset_owner_visibility_deleted_created ON remote_asset_entity (owner_id, visibility, deleted_at, created_at DESC)',

View File

@ -0,0 +1,33 @@
import 'remote_asset.entity.dart';
import 'stack.entity.dart';
CREATE VIEW visible_stack_representative AS
SELECT
se.id AS stack_id,
se.owner_id,
COALESCE(
(
SELECT primary_asset.id
FROM remote_asset_entity primary_asset
WHERE
primary_asset.id = se.primary_asset_id
AND primary_asset.deleted_at IS NULL
AND primary_asset.visibility = 0 -- timeline visibility
AND primary_asset.owner_id = se.owner_id
LIMIT 1
),
(
SELECT candidate.id
FROM remote_asset_entity candidate
WHERE
candidate.stack_id = se.id
AND candidate.deleted_at IS NULL
AND candidate.visibility = 0 -- timeline visibility
AND candidate.owner_id = se.owner_id
ORDER BY
candidate.created_at DESC,
candidate.id ASC
LIMIT 1
)
) AS asset_id
FROM stack_entity se;

View File

@ -0,0 +1,140 @@
// dart format width=80
// ignore_for_file: type=lint
import 'package:drift/drift.dart' as i0;
import 'package:immich_mobile/infrastructure/entities/visible_stack_representative.drift.dart'
as i1;
class VisibleStackRepresentativeData extends i0.DataClass {
final String stackId;
final String ownerId;
final String? assetId;
const VisibleStackRepresentativeData({
required this.stackId,
required this.ownerId,
this.assetId,
});
factory VisibleStackRepresentativeData.fromJson(
Map<String, dynamic> json, {
i0.ValueSerializer? serializer,
}) {
serializer ??= i0.driftRuntimeOptions.defaultSerializer;
return VisibleStackRepresentativeData(
stackId: serializer.fromJson<String>(json['stack_id']),
ownerId: serializer.fromJson<String>(json['owner_id']),
assetId: serializer.fromJson<String?>(json['asset_id']),
);
}
@override
Map<String, dynamic> toJson({i0.ValueSerializer? serializer}) {
serializer ??= i0.driftRuntimeOptions.defaultSerializer;
return <String, dynamic>{
'stack_id': serializer.toJson<String>(stackId),
'owner_id': serializer.toJson<String>(ownerId),
'asset_id': serializer.toJson<String?>(assetId),
};
}
i1.VisibleStackRepresentativeData copyWith({
String? stackId,
String? ownerId,
i0.Value<String?> assetId = const i0.Value.absent(),
}) => i1.VisibleStackRepresentativeData(
stackId: stackId ?? this.stackId,
ownerId: ownerId ?? this.ownerId,
assetId: assetId.present ? assetId.value : this.assetId,
);
@override
String toString() {
return (StringBuffer('VisibleStackRepresentativeData(')
..write('stackId: $stackId, ')
..write('ownerId: $ownerId, ')
..write('assetId: $assetId')
..write(')'))
.toString();
}
@override
int get hashCode => Object.hash(stackId, ownerId, assetId);
@override
bool operator ==(Object other) =>
identical(this, other) ||
(other is i1.VisibleStackRepresentativeData &&
other.stackId == this.stackId &&
other.ownerId == this.ownerId &&
other.assetId == this.assetId);
}
class VisibleStackRepresentative
extends
i0.ViewInfo<
i1.VisibleStackRepresentative,
i1.VisibleStackRepresentativeData
>
implements i0.HasResultSet {
final String? _alias;
@override
final i0.GeneratedDatabase attachedDatabase;
VisibleStackRepresentative(this.attachedDatabase, [this._alias]);
@override
List<i0.GeneratedColumn> get $columns => [stackId, ownerId, assetId];
@override
String get aliasedName => _alias ?? entityName;
@override
String get entityName => 'visible_stack_representative';
@override
Map<i0.SqlDialect, String> get createViewStatements => {
i0.SqlDialect.sqlite:
'CREATE VIEW visible_stack_representative AS SELECT se.id AS stack_id, se.owner_id, COALESCE((SELECT primary_asset.id FROM remote_asset_entity AS primary_asset WHERE primary_asset.id = se.primary_asset_id AND primary_asset.deleted_at IS NULL AND primary_asset.visibility = 0 AND primary_asset.owner_id = se.owner_id LIMIT 1), (SELECT candidate.id FROM remote_asset_entity AS candidate WHERE candidate.stack_id = se.id AND candidate.deleted_at IS NULL AND candidate.visibility = 0 AND candidate.owner_id = se.owner_id ORDER BY candidate.created_at DESC, candidate.id ASC LIMIT 1)) AS asset_id FROM stack_entity AS se',
};
@override
VisibleStackRepresentative get asDslTable => this;
@override
i1.VisibleStackRepresentativeData map(
Map<String, dynamic> data, {
String? tablePrefix,
}) {
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
return i1.VisibleStackRepresentativeData(
stackId: attachedDatabase.typeMapping.read(
i0.DriftSqlType.string,
data['${effectivePrefix}stack_id'],
)!,
ownerId: attachedDatabase.typeMapping.read(
i0.DriftSqlType.string,
data['${effectivePrefix}owner_id'],
)!,
assetId: attachedDatabase.typeMapping.read(
i0.DriftSqlType.string,
data['${effectivePrefix}asset_id'],
),
);
}
late final i0.GeneratedColumn<String> stackId = i0.GeneratedColumn<String>(
'stack_id',
aliasedName,
false,
type: i0.DriftSqlType.string,
);
late final i0.GeneratedColumn<String> ownerId = i0.GeneratedColumn<String>(
'owner_id',
aliasedName,
false,
type: i0.DriftSqlType.string,
);
late final i0.GeneratedColumn<String> assetId = i0.GeneratedColumn<String>(
'asset_id',
aliasedName,
true,
type: i0.DriftSqlType.string,
);
@override
VisibleStackRepresentative createAlias(String alias) {
return VisibleStackRepresentative(attachedDatabase, alias);
}
@override
i0.Query? get query => null;
@override
Set<String> get readTables => const {'stack_entity', 'remote_asset_entity'};
}

View File

@ -98,7 +98,7 @@ class Drift extends $Drift {
}
@override
int get schemaVersion => 26;
int get schemaVersion => 27;
@override
MigrationStrategy get migration => MigrationStrategy(
@ -276,6 +276,10 @@ class Drift extends $Drift {
from25To26: (m, v26) async {
await m.addColumn(v26.remoteAssetEntity, v26.remoteAssetEntity.uploadedAt);
},
from26To27: (m, v27) async {
await m.createIndex(v27.idxRemoteAssetVisibleStack);
await m.create(v27.visibleStackRepresentative);
},
),
);

View File

@ -7,47 +7,49 @@ import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.drift.
as i2;
import 'package:immich_mobile/infrastructure/entities/stack.entity.drift.dart'
as i3;
import 'package:immich_mobile/infrastructure/entities/local_asset.entity.drift.dart'
import 'package:immich_mobile/infrastructure/entities/visible_stack_representative.drift.dart'
as i4;
import 'package:immich_mobile/infrastructure/entities/remote_album.entity.drift.dart'
import 'package:immich_mobile/infrastructure/entities/local_asset.entity.drift.dart'
as i5;
import 'package:immich_mobile/infrastructure/entities/local_album.entity.drift.dart'
import 'package:immich_mobile/infrastructure/entities/remote_album.entity.drift.dart'
as i6;
import 'package:immich_mobile/infrastructure/entities/local_album_asset.entity.drift.dart'
import 'package:immich_mobile/infrastructure/entities/local_album.entity.drift.dart'
as i7;
import 'package:immich_mobile/infrastructure/entities/auth_user.entity.drift.dart'
import 'package:immich_mobile/infrastructure/entities/local_album_asset.entity.drift.dart'
as i8;
import 'package:immich_mobile/infrastructure/entities/user_metadata.entity.drift.dart'
import 'package:immich_mobile/infrastructure/entities/auth_user.entity.drift.dart'
as i9;
import 'package:immich_mobile/infrastructure/entities/partner.entity.drift.dart'
import 'package:immich_mobile/infrastructure/entities/user_metadata.entity.drift.dart'
as i10;
import 'package:immich_mobile/infrastructure/entities/exif.entity.drift.dart'
import 'package:immich_mobile/infrastructure/entities/partner.entity.drift.dart'
as i11;
import 'package:immich_mobile/infrastructure/entities/remote_album_asset.entity.drift.dart'
import 'package:immich_mobile/infrastructure/entities/exif.entity.drift.dart'
as i12;
import 'package:immich_mobile/infrastructure/entities/remote_album_user.entity.drift.dart'
import 'package:immich_mobile/infrastructure/entities/remote_album_asset.entity.drift.dart'
as i13;
import 'package:immich_mobile/infrastructure/entities/remote_asset_cloud_id.entity.drift.dart'
import 'package:immich_mobile/infrastructure/entities/remote_album_user.entity.drift.dart'
as i14;
import 'package:immich_mobile/infrastructure/entities/memory.entity.drift.dart'
import 'package:immich_mobile/infrastructure/entities/remote_asset_cloud_id.entity.drift.dart'
as i15;
import 'package:immich_mobile/infrastructure/entities/memory_asset.entity.drift.dart'
import 'package:immich_mobile/infrastructure/entities/memory.entity.drift.dart'
as i16;
import 'package:immich_mobile/infrastructure/entities/person.entity.drift.dart'
import 'package:immich_mobile/infrastructure/entities/memory_asset.entity.drift.dart'
as i17;
import 'package:immich_mobile/infrastructure/entities/asset_face.entity.drift.dart'
import 'package:immich_mobile/infrastructure/entities/person.entity.drift.dart'
as i18;
import 'package:immich_mobile/infrastructure/entities/store.entity.drift.dart'
import 'package:immich_mobile/infrastructure/entities/asset_face.entity.drift.dart'
as i19;
import 'package:immich_mobile/infrastructure/entities/trashed_local_asset.entity.drift.dart'
import 'package:immich_mobile/infrastructure/entities/store.entity.drift.dart'
as i20;
import 'package:immich_mobile/infrastructure/entities/asset_edit.entity.drift.dart'
import 'package:immich_mobile/infrastructure/entities/trashed_local_asset.entity.drift.dart'
as i21;
import 'package:immich_mobile/infrastructure/entities/metadata.entity.drift.dart'
import 'package:immich_mobile/infrastructure/entities/asset_edit.entity.drift.dart'
as i22;
import 'package:immich_mobile/infrastructure/entities/merged_asset.drift.dart'
import 'package:immich_mobile/infrastructure/entities/metadata.entity.drift.dart'
as i23;
import 'package:drift/internal/modular.dart' as i24;
import 'package:immich_mobile/infrastructure/entities/merged_asset.drift.dart'
as i24;
import 'package:drift/internal/modular.dart' as i25;
abstract class $Drift extends i0.GeneratedDatabase {
$Drift(i0.QueryExecutor e) : super(e);
@ -56,47 +58,49 @@ abstract class $Drift extends i0.GeneratedDatabase {
late final i2.$RemoteAssetEntityTable remoteAssetEntity = i2
.$RemoteAssetEntityTable(this);
late final i3.$StackEntityTable stackEntity = i3.$StackEntityTable(this);
late final i4.$LocalAssetEntityTable localAssetEntity = i4
late final i4.VisibleStackRepresentative visibleStackRepresentative =
i4.VisibleStackRepresentative(this);
late final i5.$LocalAssetEntityTable localAssetEntity = i5
.$LocalAssetEntityTable(this);
late final i5.$RemoteAlbumEntityTable remoteAlbumEntity = i5
late final i6.$RemoteAlbumEntityTable remoteAlbumEntity = i6
.$RemoteAlbumEntityTable(this);
late final i6.$LocalAlbumEntityTable localAlbumEntity = i6
late final i7.$LocalAlbumEntityTable localAlbumEntity = i7
.$LocalAlbumEntityTable(this);
late final i7.$LocalAlbumAssetEntityTable localAlbumAssetEntity = i7
late final i8.$LocalAlbumAssetEntityTable localAlbumAssetEntity = i8
.$LocalAlbumAssetEntityTable(this);
late final i8.$AuthUserEntityTable authUserEntity = i8.$AuthUserEntityTable(
late final i9.$AuthUserEntityTable authUserEntity = i9.$AuthUserEntityTable(
this,
);
late final i9.$UserMetadataEntityTable userMetadataEntity = i9
late final i10.$UserMetadataEntityTable userMetadataEntity = i10
.$UserMetadataEntityTable(this);
late final i10.$PartnerEntityTable partnerEntity = i10.$PartnerEntityTable(
late final i11.$PartnerEntityTable partnerEntity = i11.$PartnerEntityTable(
this,
);
late final i11.$RemoteExifEntityTable remoteExifEntity = i11
late final i12.$RemoteExifEntityTable remoteExifEntity = i12
.$RemoteExifEntityTable(this);
late final i12.$RemoteAlbumAssetEntityTable remoteAlbumAssetEntity = i12
late final i13.$RemoteAlbumAssetEntityTable remoteAlbumAssetEntity = i13
.$RemoteAlbumAssetEntityTable(this);
late final i13.$RemoteAlbumUserEntityTable remoteAlbumUserEntity = i13
late final i14.$RemoteAlbumUserEntityTable remoteAlbumUserEntity = i14
.$RemoteAlbumUserEntityTable(this);
late final i14.$RemoteAssetCloudIdEntityTable remoteAssetCloudIdEntity = i14
late final i15.$RemoteAssetCloudIdEntityTable remoteAssetCloudIdEntity = i15
.$RemoteAssetCloudIdEntityTable(this);
late final i15.$MemoryEntityTable memoryEntity = i15.$MemoryEntityTable(this);
late final i16.$MemoryAssetEntityTable memoryAssetEntity = i16
late final i16.$MemoryEntityTable memoryEntity = i16.$MemoryEntityTable(this);
late final i17.$MemoryAssetEntityTable memoryAssetEntity = i17
.$MemoryAssetEntityTable(this);
late final i17.$PersonEntityTable personEntity = i17.$PersonEntityTable(this);
late final i18.$AssetFaceEntityTable assetFaceEntity = i18
late final i18.$PersonEntityTable personEntity = i18.$PersonEntityTable(this);
late final i19.$AssetFaceEntityTable assetFaceEntity = i19
.$AssetFaceEntityTable(this);
late final i19.$StoreEntityTable storeEntity = i19.$StoreEntityTable(this);
late final i20.$TrashedLocalAssetEntityTable trashedLocalAssetEntity = i20
late final i20.$StoreEntityTable storeEntity = i20.$StoreEntityTable(this);
late final i21.$TrashedLocalAssetEntityTable trashedLocalAssetEntity = i21
.$TrashedLocalAssetEntityTable(this);
late final i21.$AssetEditEntityTable assetEditEntity = i21
late final i22.$AssetEditEntityTable assetEditEntity = i22
.$AssetEditEntityTable(this);
late final i22.$MetadataEntityTable metadataEntity = i22.$MetadataEntityTable(
late final i23.$MetadataEntityTable metadataEntity = i23.$MetadataEntityTable(
this,
);
i23.MergedAssetDrift get mergedAssetDrift => i24.ReadDatabaseContainer(
i24.MergedAssetDrift get mergedAssetDrift => i25.ReadDatabaseContainer(
this,
).accessor<i23.MergedAssetDrift>(i23.MergedAssetDrift.new);
).accessor<i24.MergedAssetDrift>(i24.MergedAssetDrift.new);
@override
Iterable<i0.TableInfo<i0.Table, Object?>> get allTables =>
allSchemaEntities.whereType<i0.TableInfo<i0.Table, Object?>>();
@ -105,18 +109,20 @@ abstract class $Drift extends i0.GeneratedDatabase {
userEntity,
remoteAssetEntity,
stackEntity,
visibleStackRepresentative,
localAssetEntity,
remoteAlbumEntity,
localAlbumEntity,
localAlbumAssetEntity,
i7.idxLocalAlbumAssetAlbumAsset,
i4.idxLocalAssetChecksum,
i4.idxLocalAssetCloudId,
i8.idxLocalAlbumAssetAlbumAsset,
i5.idxLocalAssetChecksum,
i5.idxLocalAssetCloudId,
i3.idxStackPrimaryAssetId,
i2.uQRemoteAssetsOwnerChecksum,
i2.uQRemoteAssetsOwnerLibraryChecksum,
i2.idxRemoteAssetChecksum,
i2.idxRemoteAssetStackId,
i2.idxRemoteAssetVisibleStack,
i2.idxRemoteAssetOwnerVisibilityDeletedCreated,
authUserEntity,
userMetadataEntity,
@ -133,18 +139,18 @@ abstract class $Drift extends i0.GeneratedDatabase {
trashedLocalAssetEntity,
assetEditEntity,
metadataEntity,
i10.idxPartnerSharedWithId,
i11.idxLatLng,
i11.idxRemoteExifCity,
i12.idxRemoteAlbumAssetAlbumAsset,
i14.idxRemoteAssetCloudId,
i17.idxPersonOwnerId,
i18.idxAssetFacePersonId,
i18.idxAssetFaceAssetId,
i18.idxAssetFaceVisiblePerson,
i20.idxTrashedLocalAssetChecksum,
i20.idxTrashedLocalAssetAlbum,
i21.idxAssetEditAssetId,
i11.idxPartnerSharedWithId,
i12.idxLatLng,
i12.idxRemoteExifCity,
i13.idxRemoteAlbumAssetAlbumAsset,
i15.idxRemoteAssetCloudId,
i18.idxPersonOwnerId,
i19.idxAssetFacePersonId,
i19.idxAssetFaceAssetId,
i19.idxAssetFaceVisiblePerson,
i21.idxTrashedLocalAssetChecksum,
i21.idxTrashedLocalAssetAlbum,
i22.idxAssetEditAssetId,
];
@override
i0.StreamQueryUpdateRules
@ -349,52 +355,52 @@ class $DriftManager {
i2.$$RemoteAssetEntityTableTableManager(_db, _db.remoteAssetEntity);
i3.$$StackEntityTableTableManager get stackEntity =>
i3.$$StackEntityTableTableManager(_db, _db.stackEntity);
i4.$$LocalAssetEntityTableTableManager get localAssetEntity =>
i4.$$LocalAssetEntityTableTableManager(_db, _db.localAssetEntity);
i5.$$RemoteAlbumEntityTableTableManager get remoteAlbumEntity =>
i5.$$RemoteAlbumEntityTableTableManager(_db, _db.remoteAlbumEntity);
i6.$$LocalAlbumEntityTableTableManager get localAlbumEntity =>
i6.$$LocalAlbumEntityTableTableManager(_db, _db.localAlbumEntity);
i7.$$LocalAlbumAssetEntityTableTableManager get localAlbumAssetEntity => i7
i5.$$LocalAssetEntityTableTableManager get localAssetEntity =>
i5.$$LocalAssetEntityTableTableManager(_db, _db.localAssetEntity);
i6.$$RemoteAlbumEntityTableTableManager get remoteAlbumEntity =>
i6.$$RemoteAlbumEntityTableTableManager(_db, _db.remoteAlbumEntity);
i7.$$LocalAlbumEntityTableTableManager get localAlbumEntity =>
i7.$$LocalAlbumEntityTableTableManager(_db, _db.localAlbumEntity);
i8.$$LocalAlbumAssetEntityTableTableManager get localAlbumAssetEntity => i8
.$$LocalAlbumAssetEntityTableTableManager(_db, _db.localAlbumAssetEntity);
i8.$$AuthUserEntityTableTableManager get authUserEntity =>
i8.$$AuthUserEntityTableTableManager(_db, _db.authUserEntity);
i9.$$UserMetadataEntityTableTableManager get userMetadataEntity =>
i9.$$UserMetadataEntityTableTableManager(_db, _db.userMetadataEntity);
i10.$$PartnerEntityTableTableManager get partnerEntity =>
i10.$$PartnerEntityTableTableManager(_db, _db.partnerEntity);
i11.$$RemoteExifEntityTableTableManager get remoteExifEntity =>
i11.$$RemoteExifEntityTableTableManager(_db, _db.remoteExifEntity);
i12.$$RemoteAlbumAssetEntityTableTableManager get remoteAlbumAssetEntity =>
i12.$$RemoteAlbumAssetEntityTableTableManager(
i9.$$AuthUserEntityTableTableManager get authUserEntity =>
i9.$$AuthUserEntityTableTableManager(_db, _db.authUserEntity);
i10.$$UserMetadataEntityTableTableManager get userMetadataEntity =>
i10.$$UserMetadataEntityTableTableManager(_db, _db.userMetadataEntity);
i11.$$PartnerEntityTableTableManager get partnerEntity =>
i11.$$PartnerEntityTableTableManager(_db, _db.partnerEntity);
i12.$$RemoteExifEntityTableTableManager get remoteExifEntity =>
i12.$$RemoteExifEntityTableTableManager(_db, _db.remoteExifEntity);
i13.$$RemoteAlbumAssetEntityTableTableManager get remoteAlbumAssetEntity =>
i13.$$RemoteAlbumAssetEntityTableTableManager(
_db,
_db.remoteAlbumAssetEntity,
);
i13.$$RemoteAlbumUserEntityTableTableManager get remoteAlbumUserEntity => i13
i14.$$RemoteAlbumUserEntityTableTableManager get remoteAlbumUserEntity => i14
.$$RemoteAlbumUserEntityTableTableManager(_db, _db.remoteAlbumUserEntity);
i14.$$RemoteAssetCloudIdEntityTableTableManager
i15.$$RemoteAssetCloudIdEntityTableTableManager
get remoteAssetCloudIdEntity =>
i14.$$RemoteAssetCloudIdEntityTableTableManager(
i15.$$RemoteAssetCloudIdEntityTableTableManager(
_db,
_db.remoteAssetCloudIdEntity,
);
i15.$$MemoryEntityTableTableManager get memoryEntity =>
i15.$$MemoryEntityTableTableManager(_db, _db.memoryEntity);
i16.$$MemoryAssetEntityTableTableManager get memoryAssetEntity =>
i16.$$MemoryAssetEntityTableTableManager(_db, _db.memoryAssetEntity);
i17.$$PersonEntityTableTableManager get personEntity =>
i17.$$PersonEntityTableTableManager(_db, _db.personEntity);
i18.$$AssetFaceEntityTableTableManager get assetFaceEntity =>
i18.$$AssetFaceEntityTableTableManager(_db, _db.assetFaceEntity);
i19.$$StoreEntityTableTableManager get storeEntity =>
i19.$$StoreEntityTableTableManager(_db, _db.storeEntity);
i20.$$TrashedLocalAssetEntityTableTableManager get trashedLocalAssetEntity =>
i20.$$TrashedLocalAssetEntityTableTableManager(
i16.$$MemoryEntityTableTableManager get memoryEntity =>
i16.$$MemoryEntityTableTableManager(_db, _db.memoryEntity);
i17.$$MemoryAssetEntityTableTableManager get memoryAssetEntity =>
i17.$$MemoryAssetEntityTableTableManager(_db, _db.memoryAssetEntity);
i18.$$PersonEntityTableTableManager get personEntity =>
i18.$$PersonEntityTableTableManager(_db, _db.personEntity);
i19.$$AssetFaceEntityTableTableManager get assetFaceEntity =>
i19.$$AssetFaceEntityTableTableManager(_db, _db.assetFaceEntity);
i20.$$StoreEntityTableTableManager get storeEntity =>
i20.$$StoreEntityTableTableManager(_db, _db.storeEntity);
i21.$$TrashedLocalAssetEntityTableTableManager get trashedLocalAssetEntity =>
i21.$$TrashedLocalAssetEntityTableTableManager(
_db,
_db.trashedLocalAssetEntity,
);
i21.$$AssetEditEntityTableTableManager get assetEditEntity =>
i21.$$AssetEditEntityTableTableManager(_db, _db.assetEditEntity);
i22.$$MetadataEntityTableTableManager get metadataEntity =>
i22.$$MetadataEntityTableTableManager(_db, _db.metadataEntity);
i22.$$AssetEditEntityTableTableManager get assetEditEntity =>
i22.$$AssetEditEntityTableTableManager(_db, _db.assetEditEntity);
i23.$$MetadataEntityTableTableManager get metadataEntity =>
i23.$$MetadataEntityTableTableManager(_db, _db.metadataEntity);
}

View File

@ -13539,6 +13539,597 @@ i1.GeneratedColumn<String> _column_212(String aliasedName) =>
type: i1.DriftSqlType.string,
$customConstraints: 'NULL',
);
final class Schema27 extends i0.VersionedSchema {
Schema27({required super.database}) : super(version: 27);
@override
late final List<i1.DatabaseSchemaEntity> entities = [
userEntity,
remoteAssetEntity,
stackEntity,
visibleStackRepresentative,
localAssetEntity,
remoteAlbumEntity,
localAlbumEntity,
localAlbumAssetEntity,
idxLocalAlbumAssetAlbumAsset,
idxLocalAssetChecksum,
idxLocalAssetCloudId,
idxStackPrimaryAssetId,
uQRemoteAssetsOwnerChecksum,
uQRemoteAssetsOwnerLibraryChecksum,
idxRemoteAssetChecksum,
idxRemoteAssetStackId,
idxRemoteAssetVisibleStack,
idxRemoteAssetOwnerVisibilityDeletedCreated,
authUserEntity,
userMetadataEntity,
partnerEntity,
remoteExifEntity,
remoteAlbumAssetEntity,
remoteAlbumUserEntity,
remoteAssetCloudIdEntity,
memoryEntity,
memoryAssetEntity,
personEntity,
assetFaceEntity,
storeEntity,
trashedLocalAssetEntity,
assetEditEntity,
metadata,
idxPartnerSharedWithId,
idxLatLng,
idxRemoteExifCity,
idxRemoteAlbumAssetAlbumAsset,
idxRemoteAssetCloudId,
idxPersonOwnerId,
idxAssetFacePersonId,
idxAssetFaceAssetId,
idxAssetFaceVisiblePerson,
idxTrashedLocalAssetChecksum,
idxTrashedLocalAssetAlbum,
idxAssetEditAssetId,
];
late final Shape33 userEntity = Shape33(
source: i0.VersionedTable(
entityName: 'user_entity',
withoutRowId: true,
isStrict: true,
tableConstraints: ['PRIMARY KEY(id)'],
columns: [
_column_107,
_column_108,
_column_109,
_column_110,
_column_111,
_column_112,
],
attachedDatabase: database,
),
alias: null,
);
late final Shape50 remoteAssetEntity = Shape50(
source: i0.VersionedTable(
entityName: 'remote_asset_entity',
withoutRowId: true,
isStrict: true,
tableConstraints: ['PRIMARY KEY(id)'],
columns: [
_column_108,
_column_113,
_column_114,
_column_115,
_column_116,
_column_117,
_column_118,
_column_107,
_column_119,
_column_120,
_column_121,
_column_122,
_column_123,
_column_124,
_column_212,
_column_125,
_column_126,
_column_127,
_column_128,
_column_129,
],
attachedDatabase: database,
),
alias: null,
);
late final Shape35 stackEntity = Shape35(
source: i0.VersionedTable(
entityName: 'stack_entity',
withoutRowId: true,
isStrict: true,
tableConstraints: ['PRIMARY KEY(id)'],
columns: [
_column_107,
_column_114,
_column_115,
_column_121,
_column_130,
],
attachedDatabase: database,
),
alias: null,
);
late final Shape51 visibleStackRepresentative = Shape51(
source: i0.VersionedView(
entityName: 'visible_stack_representative',
createViewStmt:
'CREATE VIEW visible_stack_representative AS SELECT se.id AS stack_id, se.owner_id, COALESCE((SELECT primary_asset.id FROM remote_asset_entity AS primary_asset WHERE primary_asset.id = se.primary_asset_id AND primary_asset.deleted_at IS NULL AND primary_asset.visibility = 0 AND primary_asset.owner_id = se.owner_id LIMIT 1), (SELECT candidate.id FROM remote_asset_entity AS candidate WHERE candidate.stack_id = se.id AND candidate.deleted_at IS NULL AND candidate.visibility = 0 AND candidate.owner_id = se.owner_id ORDER BY candidate.created_at DESC, candidate.id ASC LIMIT 1)) AS asset_id FROM stack_entity AS se;',
columns: [_column_213, _column_214, _column_215],
attachedDatabase: database,
),
alias: null,
);
late final Shape36 localAssetEntity = Shape36(
source: i0.VersionedTable(
entityName: 'local_asset_entity',
withoutRowId: true,
isStrict: true,
tableConstraints: ['PRIMARY KEY(id)'],
columns: [
_column_108,
_column_113,
_column_114,
_column_115,
_column_116,
_column_117,
_column_118,
_column_107,
_column_131,
_column_120,
_column_132,
_column_133,
_column_134,
_column_135,
_column_136,
_column_137,
],
attachedDatabase: database,
),
alias: null,
);
late final Shape48 remoteAlbumEntity = Shape48(
source: i0.VersionedTable(
entityName: 'remote_album_entity',
withoutRowId: true,
isStrict: true,
tableConstraints: ['PRIMARY KEY(id)'],
columns: [
_column_107,
_column_108,
_column_138,
_column_114,
_column_115,
_column_139,
_column_140,
_column_141,
],
attachedDatabase: database,
),
alias: null,
);
late final Shape38 localAlbumEntity = Shape38(
source: i0.VersionedTable(
entityName: 'local_album_entity',
withoutRowId: true,
isStrict: true,
tableConstraints: ['PRIMARY KEY(id)'],
columns: [
_column_107,
_column_108,
_column_115,
_column_142,
_column_143,
_column_144,
_column_145,
],
attachedDatabase: database,
),
alias: null,
);
late final Shape39 localAlbumAssetEntity = Shape39(
source: i0.VersionedTable(
entityName: 'local_album_asset_entity',
withoutRowId: true,
isStrict: true,
tableConstraints: ['PRIMARY KEY(asset_id, album_id)'],
columns: [_column_146, _column_147, _column_145],
attachedDatabase: database,
),
alias: null,
);
final i1.Index idxLocalAlbumAssetAlbumAsset = i1.Index(
'idx_local_album_asset_album_asset',
'CREATE INDEX IF NOT EXISTS idx_local_album_asset_album_asset ON local_album_asset_entity (album_id, asset_id)',
);
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 idxLocalAssetCloudId = i1.Index(
'idx_local_asset_cloud_id',
'CREATE INDEX IF NOT EXISTS idx_local_asset_cloud_id ON local_asset_entity (i_cloud_id)',
);
final i1.Index idxStackPrimaryAssetId = i1.Index(
'idx_stack_primary_asset_id',
'CREATE INDEX IF NOT EXISTS idx_stack_primary_asset_id ON stack_entity (primary_asset_id)',
);
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)',
);
final i1.Index idxRemoteAssetStackId = i1.Index(
'idx_remote_asset_stack_id',
'CREATE INDEX IF NOT EXISTS idx_remote_asset_stack_id ON remote_asset_entity (stack_id)',
);
final i1.Index idxRemoteAssetVisibleStack = i1.Index(
'idx_remote_asset_visible_stack',
'CREATE INDEX IF NOT EXISTS idx_remote_asset_visible_stack ON remote_asset_entity (stack_id, owner_id, created_at DESC, id) WHERE deleted_at IS NULL AND visibility = 0',
);
final i1.Index idxRemoteAssetOwnerVisibilityDeletedCreated = i1.Index(
'idx_remote_asset_owner_visibility_deleted_created',
'CREATE INDEX IF NOT EXISTS idx_remote_asset_owner_visibility_deleted_created ON remote_asset_entity (owner_id, visibility, deleted_at, created_at DESC)',
);
late final Shape40 authUserEntity = Shape40(
source: i0.VersionedTable(
entityName: 'auth_user_entity',
withoutRowId: true,
isStrict: true,
tableConstraints: ['PRIMARY KEY(id)'],
columns: [
_column_107,
_column_108,
_column_109,
_column_148,
_column_110,
_column_111,
_column_149,
_column_150,
_column_151,
_column_152,
],
attachedDatabase: database,
),
alias: null,
);
late final Shape4 userMetadataEntity = Shape4(
source: i0.VersionedTable(
entityName: 'user_metadata_entity',
withoutRowId: true,
isStrict: true,
tableConstraints: ['PRIMARY KEY(user_id, "key")'],
columns: [_column_153, _column_154, _column_155],
attachedDatabase: database,
),
alias: null,
);
late final Shape41 partnerEntity = Shape41(
source: i0.VersionedTable(
entityName: 'partner_entity',
withoutRowId: true,
isStrict: true,
tableConstraints: ['PRIMARY KEY(shared_by_id, shared_with_id)'],
columns: [_column_156, _column_157, _column_158],
attachedDatabase: database,
),
alias: null,
);
late final Shape42 remoteExifEntity = Shape42(
source: i0.VersionedTable(
entityName: 'remote_exif_entity',
withoutRowId: true,
isStrict: true,
tableConstraints: ['PRIMARY KEY(asset_id)'],
columns: [
_column_159,
_column_160,
_column_161,
_column_162,
_column_163,
_column_164,
_column_117,
_column_116,
_column_165,
_column_166,
_column_167,
_column_168,
_column_135,
_column_136,
_column_169,
_column_170,
_column_171,
_column_172,
_column_173,
_column_174,
_column_175,
_column_176,
],
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_159, _column_177],
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_177, _column_153, _column_178],
attachedDatabase: database,
),
alias: null,
);
late final Shape43 remoteAssetCloudIdEntity = Shape43(
source: i0.VersionedTable(
entityName: 'remote_asset_cloud_id_entity',
withoutRowId: true,
isStrict: true,
tableConstraints: ['PRIMARY KEY(asset_id)'],
columns: [
_column_159,
_column_179,
_column_180,
_column_134,
_column_135,
_column_136,
],
attachedDatabase: database,
),
alias: null,
);
late final Shape44 memoryEntity = Shape44(
source: i0.VersionedTable(
entityName: 'memory_entity',
withoutRowId: true,
isStrict: true,
tableConstraints: ['PRIMARY KEY(id)'],
columns: [
_column_107,
_column_114,
_column_115,
_column_124,
_column_121,
_column_113,
_column_181,
_column_182,
_column_183,
_column_184,
_column_185,
_column_186,
],
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_159, _column_187],
attachedDatabase: database,
),
alias: null,
);
late final Shape45 personEntity = Shape45(
source: i0.VersionedTable(
entityName: 'person_entity',
withoutRowId: true,
isStrict: true,
tableConstraints: ['PRIMARY KEY(id)'],
columns: [
_column_107,
_column_114,
_column_115,
_column_121,
_column_108,
_column_188,
_column_189,
_column_190,
_column_191,
_column_192,
],
attachedDatabase: database,
),
alias: null,
);
late final Shape46 assetFaceEntity = Shape46(
source: i0.VersionedTable(
entityName: 'asset_face_entity',
withoutRowId: true,
isStrict: true,
tableConstraints: ['PRIMARY KEY(id)'],
columns: [
_column_107,
_column_159,
_column_193,
_column_194,
_column_195,
_column_196,
_column_197,
_column_198,
_column_199,
_column_200,
_column_201,
_column_124,
],
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_202, _column_203, _column_204],
attachedDatabase: database,
),
alias: null,
);
late final Shape47 trashedLocalAssetEntity = Shape47(
source: i0.VersionedTable(
entityName: 'trashed_local_asset_entity',
withoutRowId: true,
isStrict: true,
tableConstraints: ['PRIMARY KEY(id, album_id)'],
columns: [
_column_108,
_column_113,
_column_114,
_column_115,
_column_116,
_column_117,
_column_118,
_column_107,
_column_205,
_column_131,
_column_120,
_column_132,
_column_206,
_column_137,
],
attachedDatabase: database,
),
alias: null,
);
late final Shape32 assetEditEntity = Shape32(
source: i0.VersionedTable(
entityName: 'asset_edit_entity',
withoutRowId: true,
isStrict: true,
tableConstraints: ['PRIMARY KEY(id)'],
columns: [
_column_107,
_column_159,
_column_207,
_column_208,
_column_209,
],
attachedDatabase: database,
),
alias: null,
);
late final Shape49 metadata = Shape49(
source: i0.VersionedTable(
entityName: 'metadata',
withoutRowId: true,
isStrict: true,
tableConstraints: ['PRIMARY KEY("key")'],
columns: [_column_210, _column_211, _column_115],
attachedDatabase: database,
),
alias: null,
);
final i1.Index idxPartnerSharedWithId = i1.Index(
'idx_partner_shared_with_id',
'CREATE INDEX IF NOT EXISTS idx_partner_shared_with_id ON partner_entity (shared_with_id)',
);
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 idxRemoteExifCity = i1.Index(
'idx_remote_exif_city',
'CREATE INDEX IF NOT EXISTS idx_remote_exif_city ON remote_exif_entity (city) WHERE city IS NOT NULL',
);
final i1.Index idxRemoteAlbumAssetAlbumAsset = i1.Index(
'idx_remote_album_asset_album_asset',
'CREATE INDEX IF NOT EXISTS idx_remote_album_asset_album_asset ON remote_album_asset_entity (album_id, asset_id)',
);
final i1.Index idxRemoteAssetCloudId = i1.Index(
'idx_remote_asset_cloud_id',
'CREATE INDEX IF NOT EXISTS idx_remote_asset_cloud_id ON remote_asset_cloud_id_entity (cloud_id)',
);
final i1.Index idxPersonOwnerId = i1.Index(
'idx_person_owner_id',
'CREATE INDEX IF NOT EXISTS idx_person_owner_id ON person_entity (owner_id)',
);
final i1.Index idxAssetFacePersonId = i1.Index(
'idx_asset_face_person_id',
'CREATE INDEX IF NOT EXISTS idx_asset_face_person_id ON asset_face_entity (person_id)',
);
final i1.Index idxAssetFaceAssetId = i1.Index(
'idx_asset_face_asset_id',
'CREATE INDEX IF NOT EXISTS idx_asset_face_asset_id ON asset_face_entity (asset_id)',
);
final i1.Index idxAssetFaceVisiblePerson = i1.Index(
'idx_asset_face_visible_person',
'CREATE INDEX IF NOT EXISTS idx_asset_face_visible_person ON asset_face_entity (person_id, asset_id) WHERE is_visible = 1 AND deleted_at IS NULL',
);
final i1.Index idxTrashedLocalAssetChecksum = i1.Index(
'idx_trashed_local_asset_checksum',
'CREATE INDEX IF NOT EXISTS idx_trashed_local_asset_checksum ON trashed_local_asset_entity (checksum)',
);
final i1.Index idxTrashedLocalAssetAlbum = i1.Index(
'idx_trashed_local_asset_album',
'CREATE INDEX IF NOT EXISTS idx_trashed_local_asset_album ON trashed_local_asset_entity (album_id)',
);
final i1.Index idxAssetEditAssetId = i1.Index(
'idx_asset_edit_asset_id',
'CREATE INDEX IF NOT EXISTS idx_asset_edit_asset_id ON asset_edit_entity (asset_id)',
);
}
class Shape51 extends i0.VersionedView {
Shape51({required super.source, required super.alias}) : super.aliased();
i1.GeneratedColumn<String> get stackId =>
columnsByName['stack_id']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get ownerId =>
columnsByName['owner_id']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get assetId =>
columnsByName['asset_id']! as i1.GeneratedColumn<String>;
}
i1.GeneratedColumn<String> _column_213(String aliasedName) =>
i1.GeneratedColumn<String>(
'stack_id',
aliasedName,
false,
type: i1.DriftSqlType.string,
);
i1.GeneratedColumn<String> _column_214(String aliasedName) =>
i1.GeneratedColumn<String>(
'owner_id',
aliasedName,
false,
type: i1.DriftSqlType.string,
);
i1.GeneratedColumn<String> _column_215(String aliasedName) =>
i1.GeneratedColumn<String>(
'asset_id',
aliasedName,
true,
type: i1.DriftSqlType.string,
);
i0.MigrationStepWithVersion migrationSteps({
required Future<void> Function(i1.Migrator m, Schema2 schema) from1To2,
required Future<void> Function(i1.Migrator m, Schema3 schema) from2To3,
@ -13565,6 +14156,7 @@ i0.MigrationStepWithVersion migrationSteps({
required Future<void> Function(i1.Migrator m, Schema24 schema) from23To24,
required Future<void> Function(i1.Migrator m, Schema25 schema) from24To25,
required Future<void> Function(i1.Migrator m, Schema26 schema) from25To26,
required Future<void> Function(i1.Migrator m, Schema27 schema) from26To27,
}) {
return (currentVersion, database) async {
switch (currentVersion) {
@ -13693,6 +14285,11 @@ i0.MigrationStepWithVersion migrationSteps({
final migrator = i1.Migrator(database, schema);
await from25To26(migrator, schema);
return 26;
case 26:
final schema = Schema27(database: database);
final migrator = i1.Migrator(database, schema);
await from26To27(migrator, schema);
return 27;
default:
throw ArgumentError.value('Unknown migration from $currentVersion');
}
@ -13725,6 +14322,7 @@ i1.OnUpgrade stepByStep({
required Future<void> Function(i1.Migrator m, Schema24 schema) from23To24,
required Future<void> Function(i1.Migrator m, Schema25 schema) from24To25,
required Future<void> Function(i1.Migrator m, Schema26 schema) from25To26,
required Future<void> Function(i1.Migrator m, Schema27 schema) from26To27,
}) => i0.VersionedSchema.stepByStepHelper(
step: migrationSteps(
from1To2: from1To2,
@ -13752,5 +14350,6 @@ i1.OnUpgrade stepByStep({
from23To24: from23To24,
from24To25: from24To25,
from25To26: from25To26,
from26To27: from26To27,
),
);

View File

@ -71,7 +71,7 @@ class RemoteAssetRepository extends DriftDatabaseRepository {
}
final query = _db.remoteAssetEntity.select()
..where((row) => row.stackId.equals(stackId) & row.id.equals(asset.id).not())
..where((row) => row.stackId.equals(stackId) & row.id.equals(asset.id).not() & row.deletedAt.isNull())
..orderBy([(row) => OrderingTerm.desc(row.createdAt)]);
return query.map((row) => row.toDto()).get();

View File

@ -30,6 +30,7 @@ import 'schema_v23.dart' as v23;
import 'schema_v24.dart' as v24;
import 'schema_v25.dart' as v25;
import 'schema_v26.dart' as v26;
import 'schema_v27.dart' as v27;
class GeneratedHelper implements SchemaInstantiationHelper {
@override
@ -87,6 +88,8 @@ class GeneratedHelper implements SchemaInstantiationHelper {
return v25.DatabaseAtV25(db);
case 26:
return v26.DatabaseAtV26(db);
case 27:
return v27.DatabaseAtV27(db);
default:
throw MissingSchemaException(version, versions);
}
@ -119,5 +122,6 @@ class GeneratedHelper implements SchemaInstantiationHelper {
24,
25,
26,
27,
];
}

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,7 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
import 'package:immich_mobile/domain/models/timeline.model.dart';
import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.drift.dart';
import 'package:immich_mobile/infrastructure/entities/stack.entity.drift.dart';
import 'package:immich_mobile/infrastructure/entities/user.entity.drift.dart';
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
@ -18,13 +19,43 @@ void main() {
await db.close();
});
Future<void> insertUser(String userId) {
return db
.into(db.userEntity)
.insert(UserEntityCompanion.insert(id: userId, email: '$userId@test.dev', name: 'User $userId'));
}
Future<void> insertRemoteAsset({
required String id,
required String userId,
required DateTime createdAt,
String? stackId,
DateTime? deletedAt,
}) {
return db
.into(db.remoteAssetEntity)
.insert(
RemoteAssetEntityCompanion.insert(
id: id,
name: '$id.jpg',
type: AssetType.image,
checksum: 'checksum-$id',
ownerId: userId,
visibility: AssetVisibility.timeline,
createdAt: Value(createdAt),
updatedAt: Value(createdAt),
deletedAt: Value(deletedAt),
stackId: Value(stackId),
localDateTime: Value(createdAt),
),
);
}
test('mergedBucket falls back to createdAt when localDateTime is null', () async {
const userId = 'user-1';
final createdAt = DateTime(2024, 1, 1, 12);
await db
.into(db.userEntity)
.insert(UserEntityCompanion.insert(id: userId, email: 'user-1@test.dev', name: 'User 1'));
await insertUser(userId);
await db
.into(db.remoteAssetEntity)
@ -49,4 +80,56 @@ void main() {
expect(buckets.single.assetCount, 1);
expect(buckets.single.bucketDate, isNotEmpty);
});
test('mergedAsset uses a visible stack child when the primary asset is deleted', () async {
const userId = 'user-1';
const stackId = 'stack-1';
final primaryCreatedAt = DateTime(2024, 1, 1, 12);
final childCreatedAt = DateTime(2024, 1, 2, 12);
await insertUser(userId);
await insertRemoteAsset(
id: 'primary',
userId: userId,
createdAt: primaryCreatedAt,
stackId: stackId,
deletedAt: DateTime(2024, 1, 3),
);
await insertRemoteAsset(id: 'child', userId: userId, createdAt: childCreatedAt, stackId: stackId);
await db
.into(db.stackEntity)
.insert(StackEntityCompanion.insert(id: stackId, ownerId: userId, primaryAssetId: 'primary'));
final assets = await db.mergedAssetDrift.mergedAsset(userIds: [userId], limit: (_) => Limit(10, 0)).get();
expect(assets, hasLength(1));
expect(assets.single.remoteId, 'child');
expect(assets.single.stackId, stackId);
});
test('mergedBucket counts a stack when only a non-primary child is visible', () async {
const userId = 'user-1';
const stackId = 'stack-1';
final primaryCreatedAt = DateTime(2024, 1, 1, 12);
final childCreatedAt = DateTime(2024, 1, 2, 12);
await insertUser(userId);
await insertRemoteAsset(
id: 'primary',
userId: userId,
createdAt: primaryCreatedAt,
stackId: stackId,
deletedAt: DateTime(2024, 1, 3),
);
await insertRemoteAsset(id: 'child', userId: userId, createdAt: childCreatedAt, stackId: stackId);
await db
.into(db.stackEntity)
.insert(StackEntityCompanion.insert(id: stackId, ownerId: userId, primaryAssetId: 'primary'));
final buckets = await db.mergedAssetDrift.mergedBucket(groupBy: GroupAssetsBy.day.index, userIds: [userId]).get();
expect(buckets, hasLength(1));
expect(buckets.single.assetCount, 1);
expect(buckets.single.bucketDate, '2024-01-02');
});
}