From cc471806fe63f0eafe30d9a869527a4a395ff8ba Mon Sep 17 00:00:00 2001 From: Daimolean <92239625+wuzihao051119@users.noreply.github.com> Date: Mon, 7 Jul 2025 11:01:09 +0800 Subject: [PATCH] feat(mobile): stack sync (#19735) * feat(mobile): stack sync * fix: lint * Update mobile/lib/infrastructure/repositories/sync_api.repository.dart Co-authored-by: Alex --------- Co-authored-by: Alex --- .../drift_schemas/main/drift_schema_v1.json | 1332 +---------------- mobile/lib/domain/models/stack.model.dart | 84 ++ .../domain/services/sync_stream.service.dart | 19 + .../infrastructure/entities/stack.entity.dart | 22 + .../entities/stack.entity.drift.dart | 706 +++++++++ .../repositories/db.repository.dart | 2 + .../repositories/db.repository.drift.dart | 23 +- .../repositories/stack.repository.dart | 30 + .../repositories/sync_api.repository.dart | 7 + .../repositories/sync_stream.repository.dart | 106 +- .../pages/dev/feat_in_development.page.dart | 3 + .../pages/dev/media_stat.page.dart | 4 + mobile/lib/providers/stack.provider.dart | 7 + mobile/lib/repositories/auth.repository.dart | 3 + .../services/sync_stream_service_test.dart | 12 + 15 files changed, 992 insertions(+), 1368 deletions(-) create mode 100644 mobile/lib/domain/models/stack.model.dart create mode 100644 mobile/lib/infrastructure/entities/stack.entity.dart create mode 100644 mobile/lib/infrastructure/entities/stack.entity.drift.dart create mode 100644 mobile/lib/infrastructure/repositories/stack.repository.dart create mode 100644 mobile/lib/providers/stack.provider.dart diff --git a/mobile/drift_schemas/main/drift_schema_v1.json b/mobile/drift_schemas/main/drift_schema_v1.json index 32ba52e366..493a34cc94 100644 --- a/mobile/drift_schemas/main/drift_schema_v1.json +++ b/mobile/drift_schemas/main/drift_schema_v1.json @@ -1,1331 +1 @@ -{ - "_meta": { - "description": "This file contains a serialized version of schema entities for drift.", - "version": "1.2.0" - }, - "options": { "store_date_time_values_as_text": true }, - "entities": [ - { - "id": 0, - "references": [], - "type": "table", - "data": { - "name": "user_entity", - "was_declared_in_moor": false, - "columns": [ - { - "name": "id", - "getter_name": "id", - "moor_type": "string", - "nullable": false, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "name", - "getter_name": "name", - "moor_type": "string", - "nullable": false, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "is_admin", - "getter_name": "isAdmin", - "moor_type": "bool", - "nullable": false, - "customConstraints": null, - "defaultConstraints": "CHECK (\"is_admin\" IN (0, 1))", - "dialectAwareDefaultConstraints": { - "sqlite": "CHECK (\"is_admin\" IN (0, 1))" - }, - "default_dart": "const CustomExpression('0')", - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "email", - "getter_name": "email", - "moor_type": "string", - "nullable": false, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "profile_image_path", - "getter_name": "profileImagePath", - "moor_type": "string", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "updated_at", - "getter_name": "updatedAt", - "moor_type": "dateTime", - "nullable": false, - "customConstraints": null, - "default_dart": "const CustomExpression('CURRENT_TIMESTAMP')", - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "quota_size_in_bytes", - "getter_name": "quotaSizeInBytes", - "moor_type": "int", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "quota_usage_in_bytes", - "getter_name": "quotaUsageInBytes", - "moor_type": "int", - "nullable": false, - "customConstraints": null, - "default_dart": "const CustomExpression('0')", - "default_client_dart": null, - "dsl_features": [] - } - ], - "is_virtual": false, - "without_rowid": true, - "constraints": [], - "strict": true, - "explicit_pk": ["id"] - } - }, - { - "id": 1, - "references": [0], - "type": "table", - "data": { - "name": "remote_asset_entity", - "was_declared_in_moor": false, - "columns": [ - { - "name": "name", - "getter_name": "name", - "moor_type": "string", - "nullable": false, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "type", - "getter_name": "type", - "moor_type": "int", - "nullable": false, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [], - "type_converter": { - "dart_expr": "const EnumIndexConverter(AssetType.values)", - "dart_type_name": "AssetType" - } - }, - { - "name": "created_at", - "getter_name": "createdAt", - "moor_type": "dateTime", - "nullable": false, - "customConstraints": null, - "default_dart": "const CustomExpression('CURRENT_TIMESTAMP')", - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "updated_at", - "getter_name": "updatedAt", - "moor_type": "dateTime", - "nullable": false, - "customConstraints": null, - "default_dart": "const CustomExpression('CURRENT_TIMESTAMP')", - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "width", - "getter_name": "width", - "moor_type": "int", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "height", - "getter_name": "height", - "moor_type": "int", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "duration_in_seconds", - "getter_name": "durationInSeconds", - "moor_type": "int", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "id", - "getter_name": "id", - "moor_type": "string", - "nullable": false, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "checksum", - "getter_name": "checksum", - "moor_type": "string", - "nullable": false, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "is_favorite", - "getter_name": "isFavorite", - "moor_type": "bool", - "nullable": false, - "customConstraints": null, - "defaultConstraints": "CHECK (\"is_favorite\" IN (0, 1))", - "dialectAwareDefaultConstraints": { - "sqlite": "CHECK (\"is_favorite\" IN (0, 1))" - }, - "default_dart": "const CustomExpression('0')", - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "owner_id", - "getter_name": "ownerId", - "moor_type": "string", - "nullable": false, - "customConstraints": null, - "defaultConstraints": "REFERENCES user_entity (id) ON DELETE CASCADE", - "dialectAwareDefaultConstraints": { - "sqlite": "REFERENCES user_entity (id) ON DELETE CASCADE" - }, - "default_dart": null, - "default_client_dart": null, - "dsl_features": ["unknown"] - }, - { - "name": "local_date_time", - "getter_name": "localDateTime", - "moor_type": "dateTime", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "thumb_hash", - "getter_name": "thumbHash", - "moor_type": "string", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "deleted_at", - "getter_name": "deletedAt", - "moor_type": "dateTime", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "visibility", - "getter_name": "visibility", - "moor_type": "int", - "nullable": false, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [], - "type_converter": { - "dart_expr": "const EnumIndexConverter(AssetVisibility.values)", - "dart_type_name": "AssetVisibility" - } - } - ], - "is_virtual": false, - "without_rowid": true, - "constraints": [], - "strict": true, - "explicit_pk": ["id"] - } - }, - { - "id": 2, - "references": [], - "type": "table", - "data": { - "name": "local_asset_entity", - "was_declared_in_moor": false, - "columns": [ - { - "name": "name", - "getter_name": "name", - "moor_type": "string", - "nullable": false, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "type", - "getter_name": "type", - "moor_type": "int", - "nullable": false, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [], - "type_converter": { - "dart_expr": "const EnumIndexConverter(AssetType.values)", - "dart_type_name": "AssetType" - } - }, - { - "name": "created_at", - "getter_name": "createdAt", - "moor_type": "dateTime", - "nullable": false, - "customConstraints": null, - "default_dart": "const CustomExpression('CURRENT_TIMESTAMP')", - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "updated_at", - "getter_name": "updatedAt", - "moor_type": "dateTime", - "nullable": false, - "customConstraints": null, - "default_dart": "const CustomExpression('CURRENT_TIMESTAMP')", - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "width", - "getter_name": "width", - "moor_type": "int", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "height", - "getter_name": "height", - "moor_type": "int", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "duration_in_seconds", - "getter_name": "durationInSeconds", - "moor_type": "int", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "id", - "getter_name": "id", - "moor_type": "string", - "nullable": false, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "checksum", - "getter_name": "checksum", - "moor_type": "string", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "is_favorite", - "getter_name": "isFavorite", - "moor_type": "bool", - "nullable": false, - "customConstraints": null, - "defaultConstraints": "CHECK (\"is_favorite\" IN (0, 1))", - "dialectAwareDefaultConstraints": { - "sqlite": "CHECK (\"is_favorite\" IN (0, 1))" - }, - "default_dart": "const CustomExpression('0')", - "default_client_dart": null, - "dsl_features": [] - } - ], - "is_virtual": false, - "without_rowid": true, - "constraints": [], - "strict": true, - "explicit_pk": ["id"] - } - }, - { - "id": 3, - "references": [2], - "type": "index", - "data": { - "on": 2, - "name": "idx_local_asset_checksum", - "sql": null, - "unique": false, - "columns": ["checksum"] - } - }, - { - "id": 4, - "references": [1], - "type": "index", - "data": { - "on": 1, - "name": "UQ_remote_asset_owner_checksum", - "sql": null, - "unique": true, - "columns": ["checksum", "owner_id"] - } - }, - { - "id": 5, - "references": [1], - "type": "index", - "data": { - "on": 1, - "name": "idx_remote_asset_checksum", - "sql": null, - "unique": false, - "columns": ["checksum"] - } - }, - { - "id": 6, - "references": [0], - "type": "table", - "data": { - "name": "user_metadata_entity", - "was_declared_in_moor": false, - "columns": [ - { - "name": "user_id", - "getter_name": "userId", - "moor_type": "string", - "nullable": false, - "customConstraints": null, - "defaultConstraints": "REFERENCES user_entity (id) ON DELETE CASCADE", - "dialectAwareDefaultConstraints": { - "sqlite": "REFERENCES user_entity (id) ON DELETE CASCADE" - }, - "default_dart": null, - "default_client_dart": null, - "dsl_features": ["unknown"] - }, - { - "name": "preferences", - "getter_name": "preferences", - "moor_type": "string", - "nullable": false, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [], - "type_converter": { - "dart_expr": "userPreferenceConverter", - "dart_type_name": "UserPreferences" - } - } - ], - "is_virtual": false, - "without_rowid": true, - "constraints": [], - "strict": true, - "explicit_pk": ["user_id"] - } - }, - { - "id": 7, - "references": [0], - "type": "table", - "data": { - "name": "partner_entity", - "was_declared_in_moor": false, - "columns": [ - { - "name": "shared_by_id", - "getter_name": "sharedById", - "moor_type": "string", - "nullable": false, - "customConstraints": null, - "defaultConstraints": "REFERENCES user_entity (id) ON DELETE CASCADE", - "dialectAwareDefaultConstraints": { - "sqlite": "REFERENCES user_entity (id) ON DELETE CASCADE" - }, - "default_dart": null, - "default_client_dart": null, - "dsl_features": ["unknown"] - }, - { - "name": "shared_with_id", - "getter_name": "sharedWithId", - "moor_type": "string", - "nullable": false, - "customConstraints": null, - "defaultConstraints": "REFERENCES user_entity (id) ON DELETE CASCADE", - "dialectAwareDefaultConstraints": { - "sqlite": "REFERENCES user_entity (id) ON DELETE CASCADE" - }, - "default_dart": null, - "default_client_dart": null, - "dsl_features": ["unknown"] - }, - { - "name": "in_timeline", - "getter_name": "inTimeline", - "moor_type": "bool", - "nullable": false, - "customConstraints": null, - "defaultConstraints": "CHECK (\"in_timeline\" IN (0, 1))", - "dialectAwareDefaultConstraints": { - "sqlite": "CHECK (\"in_timeline\" IN (0, 1))" - }, - "default_dart": "const CustomExpression('0')", - "default_client_dart": null, - "dsl_features": [] - } - ], - "is_virtual": false, - "without_rowid": true, - "constraints": [], - "strict": true, - "explicit_pk": ["shared_by_id", "shared_with_id"] - } - }, - { - "id": 8, - "references": [], - "type": "table", - "data": { - "name": "local_album_entity", - "was_declared_in_moor": false, - "columns": [ - { - "name": "id", - "getter_name": "id", - "moor_type": "string", - "nullable": false, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "name", - "getter_name": "name", - "moor_type": "string", - "nullable": false, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "updated_at", - "getter_name": "updatedAt", - "moor_type": "dateTime", - "nullable": false, - "customConstraints": null, - "default_dart": "const CustomExpression('CURRENT_TIMESTAMP')", - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "backup_selection", - "getter_name": "backupSelection", - "moor_type": "int", - "nullable": false, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [], - "type_converter": { - "dart_expr": "const EnumIndexConverter(BackupSelection.values)", - "dart_type_name": "BackupSelection" - } - }, - { - "name": "is_ios_shared_album", - "getter_name": "isIosSharedAlbum", - "moor_type": "bool", - "nullable": false, - "customConstraints": null, - "defaultConstraints": "CHECK (\"is_ios_shared_album\" IN (0, 1))", - "dialectAwareDefaultConstraints": { - "sqlite": "CHECK (\"is_ios_shared_album\" IN (0, 1))" - }, - "default_dart": "const CustomExpression('0')", - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "marker", - "getter_name": "marker_", - "moor_type": "bool", - "nullable": true, - "customConstraints": null, - "defaultConstraints": "CHECK (\"marker\" IN (0, 1))", - "dialectAwareDefaultConstraints": { - "sqlite": "CHECK (\"marker\" IN (0, 1))" - }, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - } - ], - "is_virtual": false, - "without_rowid": true, - "constraints": [], - "strict": true, - "explicit_pk": ["id"] - } - }, - { - "id": 9, - "references": [2, 8], - "type": "table", - "data": { - "name": "local_album_asset_entity", - "was_declared_in_moor": false, - "columns": [ - { - "name": "asset_id", - "getter_name": "assetId", - "moor_type": "string", - "nullable": false, - "customConstraints": null, - "defaultConstraints": "REFERENCES local_asset_entity (id) ON DELETE CASCADE", - "dialectAwareDefaultConstraints": { - "sqlite": "REFERENCES local_asset_entity (id) ON DELETE CASCADE" - }, - "default_dart": null, - "default_client_dart": null, - "dsl_features": ["unknown"] - }, - { - "name": "album_id", - "getter_name": "albumId", - "moor_type": "string", - "nullable": false, - "customConstraints": null, - "defaultConstraints": "REFERENCES local_album_entity (id) ON DELETE CASCADE", - "dialectAwareDefaultConstraints": { - "sqlite": "REFERENCES local_album_entity (id) ON DELETE CASCADE" - }, - "default_dart": null, - "default_client_dart": null, - "dsl_features": ["unknown"] - } - ], - "is_virtual": false, - "without_rowid": true, - "constraints": [], - "strict": true, - "explicit_pk": ["asset_id", "album_id"] - } - }, - { - "id": 10, - "references": [1], - "type": "table", - "data": { - "name": "remote_exif_entity", - "was_declared_in_moor": false, - "columns": [ - { - "name": "asset_id", - "getter_name": "assetId", - "moor_type": "string", - "nullable": false, - "customConstraints": null, - "defaultConstraints": "REFERENCES remote_asset_entity (id) ON DELETE CASCADE", - "dialectAwareDefaultConstraints": { - "sqlite": "REFERENCES remote_asset_entity (id) ON DELETE CASCADE" - }, - "default_dart": null, - "default_client_dart": null, - "dsl_features": ["unknown"] - }, - { - "name": "city", - "getter_name": "city", - "moor_type": "string", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "state", - "getter_name": "state", - "moor_type": "string", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "country", - "getter_name": "country", - "moor_type": "string", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "date_time_original", - "getter_name": "dateTimeOriginal", - "moor_type": "dateTime", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "description", - "getter_name": "description", - "moor_type": "string", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "height", - "getter_name": "height", - "moor_type": "int", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "width", - "getter_name": "width", - "moor_type": "int", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "exposure_time", - "getter_name": "exposureTime", - "moor_type": "string", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "f_number", - "getter_name": "fNumber", - "moor_type": "double", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "file_size", - "getter_name": "fileSize", - "moor_type": "int", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "focal_length", - "getter_name": "focalLength", - "moor_type": "double", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "latitude", - "getter_name": "latitude", - "moor_type": "double", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "longitude", - "getter_name": "longitude", - "moor_type": "double", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "iso", - "getter_name": "iso", - "moor_type": "int", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "make", - "getter_name": "make", - "moor_type": "string", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "model", - "getter_name": "model", - "moor_type": "string", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "orientation", - "getter_name": "orientation", - "moor_type": "string", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "time_zone", - "getter_name": "timeZone", - "moor_type": "string", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "rating", - "getter_name": "rating", - "moor_type": "int", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "projection_type", - "getter_name": "projectionType", - "moor_type": "string", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - } - ], - "is_virtual": false, - "without_rowid": true, - "constraints": [], - "strict": true, - "explicit_pk": ["asset_id"] - } - }, - { - "id": 11, - "references": [0, 1], - "type": "table", - "data": { - "name": "remote_album_entity", - "was_declared_in_moor": false, - "columns": [ - { - "name": "id", - "getter_name": "id", - "moor_type": "string", - "nullable": false, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "name", - "getter_name": "name", - "moor_type": "string", - "nullable": false, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "description", - "getter_name": "description", - "moor_type": "string", - "nullable": false, - "customConstraints": null, - "default_dart": "const CustomExpression('\\'\\'')", - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "created_at", - "getter_name": "createdAt", - "moor_type": "dateTime", - "nullable": false, - "customConstraints": null, - "default_dart": "const CustomExpression('CURRENT_TIMESTAMP')", - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "updated_at", - "getter_name": "updatedAt", - "moor_type": "dateTime", - "nullable": false, - "customConstraints": null, - "default_dart": "const CustomExpression('CURRENT_TIMESTAMP')", - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "owner_id", - "getter_name": "ownerId", - "moor_type": "string", - "nullable": false, - "customConstraints": null, - "defaultConstraints": "REFERENCES user_entity (id) ON DELETE CASCADE", - "dialectAwareDefaultConstraints": { - "sqlite": "REFERENCES user_entity (id) ON DELETE CASCADE" - }, - "default_dart": null, - "default_client_dart": null, - "dsl_features": ["unknown"] - }, - { - "name": "thumbnail_asset_id", - "getter_name": "thumbnailAssetId", - "moor_type": "string", - "nullable": true, - "customConstraints": null, - "defaultConstraints": "REFERENCES remote_asset_entity (id) ON DELETE SET NULL", - "dialectAwareDefaultConstraints": { - "sqlite": "REFERENCES remote_asset_entity (id) ON DELETE SET NULL" - }, - "default_dart": null, - "default_client_dart": null, - "dsl_features": ["unknown"] - }, - { - "name": "is_activity_enabled", - "getter_name": "isActivityEnabled", - "moor_type": "bool", - "nullable": false, - "customConstraints": null, - "defaultConstraints": "CHECK (\"is_activity_enabled\" IN (0, 1))", - "dialectAwareDefaultConstraints": { - "sqlite": "CHECK (\"is_activity_enabled\" IN (0, 1))" - }, - "default_dart": "const CustomExpression('1')", - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "order", - "getter_name": "order", - "moor_type": "int", - "nullable": false, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [], - "type_converter": { - "dart_expr": "const EnumIndexConverter(AlbumAssetOrder.values)", - "dart_type_name": "AlbumAssetOrder" - } - } - ], - "is_virtual": false, - "without_rowid": true, - "constraints": [], - "strict": true, - "explicit_pk": ["id"] - } - }, - { - "id": 12, - "references": [1, 11], - "type": "table", - "data": { - "name": "remote_album_asset_entity", - "was_declared_in_moor": false, - "columns": [ - { - "name": "asset_id", - "getter_name": "assetId", - "moor_type": "string", - "nullable": false, - "customConstraints": null, - "defaultConstraints": "REFERENCES remote_asset_entity (id) ON DELETE CASCADE", - "dialectAwareDefaultConstraints": { - "sqlite": "REFERENCES remote_asset_entity (id) ON DELETE CASCADE" - }, - "default_dart": null, - "default_client_dart": null, - "dsl_features": ["unknown"] - }, - { - "name": "album_id", - "getter_name": "albumId", - "moor_type": "string", - "nullable": false, - "customConstraints": null, - "defaultConstraints": "REFERENCES remote_album_entity (id) ON DELETE CASCADE", - "dialectAwareDefaultConstraints": { - "sqlite": "REFERENCES remote_album_entity (id) ON DELETE CASCADE" - }, - "default_dart": null, - "default_client_dart": null, - "dsl_features": ["unknown"] - } - ], - "is_virtual": false, - "without_rowid": true, - "constraints": [], - "strict": true, - "explicit_pk": ["asset_id", "album_id"] - } - }, - { - "id": 13, - "references": [11, 0], - "type": "table", - "data": { - "name": "remote_album_user_entity", - "was_declared_in_moor": false, - "columns": [ - { - "name": "album_id", - "getter_name": "albumId", - "moor_type": "string", - "nullable": false, - "customConstraints": null, - "defaultConstraints": "REFERENCES remote_album_entity (id) ON DELETE CASCADE", - "dialectAwareDefaultConstraints": { - "sqlite": "REFERENCES remote_album_entity (id) ON DELETE CASCADE" - }, - "default_dart": null, - "default_client_dart": null, - "dsl_features": ["unknown"] - }, - { - "name": "user_id", - "getter_name": "userId", - "moor_type": "string", - "nullable": false, - "customConstraints": null, - "defaultConstraints": "REFERENCES user_entity (id) ON DELETE CASCADE", - "dialectAwareDefaultConstraints": { - "sqlite": "REFERENCES user_entity (id) ON DELETE CASCADE" - }, - "default_dart": null, - "default_client_dart": null, - "dsl_features": ["unknown"] - }, - { - "name": "role", - "getter_name": "role", - "moor_type": "int", - "nullable": false, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [], - "type_converter": { - "dart_expr": "const EnumIndexConverter(AlbumUserRole.values)", - "dart_type_name": "AlbumUserRole" - } - } - ], - "is_virtual": false, - "without_rowid": true, - "constraints": [], - "strict": true, - "explicit_pk": ["album_id", "user_id"] - } - }, - { - "id": 14, - "references": [0], - "type": "table", - "data": { - "name": "memory_entity", - "was_declared_in_moor": false, - "columns": [ - { - "name": "id", - "getter_name": "id", - "moor_type": "string", - "nullable": false, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "created_at", - "getter_name": "createdAt", - "moor_type": "dateTime", - "nullable": false, - "customConstraints": null, - "default_dart": "const CustomExpression('CURRENT_TIMESTAMP')", - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "updated_at", - "getter_name": "updatedAt", - "moor_type": "dateTime", - "nullable": false, - "customConstraints": null, - "default_dart": "const CustomExpression('CURRENT_TIMESTAMP')", - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "deleted_at", - "getter_name": "deletedAt", - "moor_type": "dateTime", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "owner_id", - "getter_name": "ownerId", - "moor_type": "string", - "nullable": false, - "customConstraints": null, - "defaultConstraints": "REFERENCES user_entity (id) ON DELETE CASCADE", - "dialectAwareDefaultConstraints": { - "sqlite": "REFERENCES user_entity (id) ON DELETE CASCADE" - }, - "default_dart": null, - "default_client_dart": null, - "dsl_features": ["unknown"] - }, - { - "name": "type", - "getter_name": "type", - "moor_type": "int", - "nullable": false, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [], - "type_converter": { - "dart_expr": "const EnumIndexConverter(MemoryType.values)", - "dart_type_name": "MemoryType" - } - }, - { - "name": "data", - "getter_name": "data", - "moor_type": "string", - "nullable": false, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "is_saved", - "getter_name": "isSaved", - "moor_type": "bool", - "nullable": false, - "customConstraints": null, - "defaultConstraints": "CHECK (\"is_saved\" IN (0, 1))", - "dialectAwareDefaultConstraints": { - "sqlite": "CHECK (\"is_saved\" IN (0, 1))" - }, - "default_dart": "const CustomExpression('0')", - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "memory_at", - "getter_name": "memoryAt", - "moor_type": "dateTime", - "nullable": false, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "seen_at", - "getter_name": "seenAt", - "moor_type": "dateTime", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "show_at", - "getter_name": "showAt", - "moor_type": "dateTime", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - }, - { - "name": "hide_at", - "getter_name": "hideAt", - "moor_type": "dateTime", - "nullable": true, - "customConstraints": null, - "default_dart": null, - "default_client_dart": null, - "dsl_features": [] - } - ], - "is_virtual": false, - "without_rowid": true, - "constraints": [], - "strict": true, - "explicit_pk": ["id"] - } - }, - { - "id": 15, - "references": [1, 14], - "type": "table", - "data": { - "name": "memory_asset_entity", - "was_declared_in_moor": false, - "columns": [ - { - "name": "asset_id", - "getter_name": "assetId", - "moor_type": "string", - "nullable": false, - "customConstraints": null, - "defaultConstraints": "REFERENCES remote_asset_entity (id) ON DELETE CASCADE", - "dialectAwareDefaultConstraints": { - "sqlite": "REFERENCES remote_asset_entity (id) ON DELETE CASCADE" - }, - "default_dart": null, - "default_client_dart": null, - "dsl_features": ["unknown"] - }, - { - "name": "memory_id", - "getter_name": "memoryId", - "moor_type": "string", - "nullable": false, - "customConstraints": null, - "defaultConstraints": "REFERENCES memory_entity (id) ON DELETE CASCADE", - "dialectAwareDefaultConstraints": { - "sqlite": "REFERENCES memory_entity (id) ON DELETE CASCADE" - }, - "default_dart": null, - "default_client_dart": null, - "dsl_features": ["unknown"] - } - ], - "is_virtual": false, - "without_rowid": true, - "constraints": [], - "strict": true, - "explicit_pk": ["asset_id", "memory_id"] - } - } - ] -} +{"_meta":{"description":"This file contains a serialized version of schema entities for drift.","version":"1.2.0"},"options":{"store_date_time_values_as_text":true},"entities":[{"id":0,"references":[],"type":"table","data":{"name":"user_entity","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"name","getter_name":"name","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"is_admin","getter_name":"isAdmin","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"is_admin\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"is_admin\" IN (0, 1))"},"default_dart":"const CustomExpression('0')","default_client_dart":null,"dsl_features":[]},{"name":"email","getter_name":"email","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"profile_image_path","getter_name":"profileImagePath","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"updated_at","getter_name":"updatedAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"quota_size_in_bytes","getter_name":"quotaSizeInBytes","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"quota_usage_in_bytes","getter_name":"quotaUsageInBytes","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('0')","default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["id"]}},{"id":1,"references":[0],"type":"table","data":{"name":"remote_asset_entity","was_declared_in_moor":false,"columns":[{"name":"name","getter_name":"name","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"type","getter_name":"type","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumIndexConverter(AssetType.values)","dart_type_name":"AssetType"}},{"name":"created_at","getter_name":"createdAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"updated_at","getter_name":"updatedAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"width","getter_name":"width","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"height","getter_name":"height","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"duration_in_seconds","getter_name":"durationInSeconds","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"id","getter_name":"id","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"checksum","getter_name":"checksum","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"is_favorite","getter_name":"isFavorite","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"is_favorite\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"is_favorite\" IN (0, 1))"},"default_dart":"const CustomExpression('0')","default_client_dart":null,"dsl_features":[]},{"name":"owner_id","getter_name":"ownerId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES user_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES user_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"local_date_time","getter_name":"localDateTime","moor_type":"dateTime","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"thumb_hash","getter_name":"thumbHash","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"deleted_at","getter_name":"deletedAt","moor_type":"dateTime","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"visibility","getter_name":"visibility","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumIndexConverter(AssetVisibility.values)","dart_type_name":"AssetVisibility"}}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["id"]}},{"id":2,"references":[],"type":"table","data":{"name":"local_asset_entity","was_declared_in_moor":false,"columns":[{"name":"name","getter_name":"name","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"type","getter_name":"type","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumIndexConverter(AssetType.values)","dart_type_name":"AssetType"}},{"name":"created_at","getter_name":"createdAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"updated_at","getter_name":"updatedAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"width","getter_name":"width","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"height","getter_name":"height","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"duration_in_seconds","getter_name":"durationInSeconds","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"id","getter_name":"id","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"checksum","getter_name":"checksum","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"is_favorite","getter_name":"isFavorite","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"is_favorite\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"is_favorite\" IN (0, 1))"},"default_dart":"const CustomExpression('0')","default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["id"]}},{"id":3,"references":[2],"type":"index","data":{"on":2,"name":"idx_local_asset_checksum","sql":null,"unique":false,"columns":["checksum"]}},{"id":4,"references":[1],"type":"index","data":{"on":1,"name":"UQ_remote_asset_owner_checksum","sql":null,"unique":true,"columns":["checksum","owner_id"]}},{"id":5,"references":[1],"type":"index","data":{"on":1,"name":"idx_remote_asset_checksum","sql":null,"unique":false,"columns":["checksum"]}},{"id":6,"references":[0],"type":"table","data":{"name":"user_metadata_entity","was_declared_in_moor":false,"columns":[{"name":"user_id","getter_name":"userId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES user_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES user_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"preferences","getter_name":"preferences","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"userPreferenceConverter","dart_type_name":"UserPreferences"}}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["user_id"]}},{"id":7,"references":[0],"type":"table","data":{"name":"partner_entity","was_declared_in_moor":false,"columns":[{"name":"shared_by_id","getter_name":"sharedById","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES user_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES user_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"shared_with_id","getter_name":"sharedWithId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES user_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES user_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"in_timeline","getter_name":"inTimeline","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"in_timeline\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"in_timeline\" IN (0, 1))"},"default_dart":"const CustomExpression('0')","default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["shared_by_id","shared_with_id"]}},{"id":8,"references":[],"type":"table","data":{"name":"local_album_entity","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"name","getter_name":"name","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"updated_at","getter_name":"updatedAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"backup_selection","getter_name":"backupSelection","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumIndexConverter(BackupSelection.values)","dart_type_name":"BackupSelection"}},{"name":"is_ios_shared_album","getter_name":"isIosSharedAlbum","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"is_ios_shared_album\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"is_ios_shared_album\" IN (0, 1))"},"default_dart":"const CustomExpression('0')","default_client_dart":null,"dsl_features":[]},{"name":"marker","getter_name":"marker_","moor_type":"bool","nullable":true,"customConstraints":null,"defaultConstraints":"CHECK (\"marker\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"marker\" IN (0, 1))"},"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["id"]}},{"id":9,"references":[2,8],"type":"table","data":{"name":"local_album_asset_entity","was_declared_in_moor":false,"columns":[{"name":"asset_id","getter_name":"assetId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES local_asset_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES local_asset_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"album_id","getter_name":"albumId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES local_album_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES local_album_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["asset_id","album_id"]}},{"id":10,"references":[1],"type":"table","data":{"name":"remote_exif_entity","was_declared_in_moor":false,"columns":[{"name":"asset_id","getter_name":"assetId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES remote_asset_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES remote_asset_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"city","getter_name":"city","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"state","getter_name":"state","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"country","getter_name":"country","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"date_time_original","getter_name":"dateTimeOriginal","moor_type":"dateTime","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"description","getter_name":"description","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"height","getter_name":"height","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"width","getter_name":"width","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"exposure_time","getter_name":"exposureTime","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"f_number","getter_name":"fNumber","moor_type":"double","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"file_size","getter_name":"fileSize","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"focal_length","getter_name":"focalLength","moor_type":"double","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"latitude","getter_name":"latitude","moor_type":"double","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"longitude","getter_name":"longitude","moor_type":"double","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"iso","getter_name":"iso","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"make","getter_name":"make","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"model","getter_name":"model","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"lens","getter_name":"lens","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"orientation","getter_name":"orientation","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"time_zone","getter_name":"timeZone","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"rating","getter_name":"rating","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"projection_type","getter_name":"projectionType","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["asset_id"]}},{"id":11,"references":[0,1],"type":"table","data":{"name":"remote_album_entity","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"name","getter_name":"name","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"description","getter_name":"description","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('\\'\\'')","default_client_dart":null,"dsl_features":[]},{"name":"created_at","getter_name":"createdAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"updated_at","getter_name":"updatedAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"owner_id","getter_name":"ownerId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES user_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES user_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"thumbnail_asset_id","getter_name":"thumbnailAssetId","moor_type":"string","nullable":true,"customConstraints":null,"defaultConstraints":"REFERENCES remote_asset_entity (id) ON DELETE SET NULL","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES remote_asset_entity (id) ON DELETE SET NULL"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"is_activity_enabled","getter_name":"isActivityEnabled","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"is_activity_enabled\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"is_activity_enabled\" IN (0, 1))"},"default_dart":"const CustomExpression('1')","default_client_dart":null,"dsl_features":[]},{"name":"order","getter_name":"order","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumIndexConverter(AlbumAssetOrder.values)","dart_type_name":"AlbumAssetOrder"}}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["id"]}},{"id":12,"references":[1,11],"type":"table","data":{"name":"remote_album_asset_entity","was_declared_in_moor":false,"columns":[{"name":"asset_id","getter_name":"assetId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES remote_asset_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES remote_asset_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"album_id","getter_name":"albumId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES remote_album_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES remote_album_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["asset_id","album_id"]}},{"id":13,"references":[11,0],"type":"table","data":{"name":"remote_album_user_entity","was_declared_in_moor":false,"columns":[{"name":"album_id","getter_name":"albumId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES remote_album_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES remote_album_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"user_id","getter_name":"userId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES user_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES user_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"role","getter_name":"role","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumIndexConverter(AlbumUserRole.values)","dart_type_name":"AlbumUserRole"}}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["album_id","user_id"]}},{"id":14,"references":[0],"type":"table","data":{"name":"memory_entity","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"created_at","getter_name":"createdAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"updated_at","getter_name":"updatedAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"deleted_at","getter_name":"deletedAt","moor_type":"dateTime","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"owner_id","getter_name":"ownerId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES user_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES user_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"type","getter_name":"type","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumIndexConverter(MemoryTypeEnum.values)","dart_type_name":"MemoryTypeEnum"}},{"name":"data","getter_name":"data","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"is_saved","getter_name":"isSaved","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"is_saved\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"is_saved\" IN (0, 1))"},"default_dart":"const CustomExpression('0')","default_client_dart":null,"dsl_features":[]},{"name":"memory_at","getter_name":"memoryAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"seen_at","getter_name":"seenAt","moor_type":"dateTime","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"show_at","getter_name":"showAt","moor_type":"dateTime","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"hide_at","getter_name":"hideAt","moor_type":"dateTime","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["id"]}},{"id":15,"references":[1,14],"type":"table","data":{"name":"memory_asset_entity","was_declared_in_moor":false,"columns":[{"name":"asset_id","getter_name":"assetId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES remote_asset_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES remote_asset_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"memory_id","getter_name":"memoryId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES memory_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES memory_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["asset_id","memory_id"]}},{"id":16,"references":[0,1],"type":"table","data":{"name":"stack_entity","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"created_at","getter_name":"createdAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"updated_at","getter_name":"updatedAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"owner_id","getter_name":"ownerId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES user_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES user_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"primary_asset_id","getter_name":"primaryAssetId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES remote_asset_entity (id)","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES remote_asset_entity (id)"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["id"]}}]} \ No newline at end of file diff --git a/mobile/lib/domain/models/stack.model.dart b/mobile/lib/domain/models/stack.model.dart new file mode 100644 index 0000000000..5404eb8f42 --- /dev/null +++ b/mobile/lib/domain/models/stack.model.dart @@ -0,0 +1,84 @@ +import 'dart:convert'; + +// Model for a stack stored in the server +class Stack { + final String id; + final DateTime createdAt; + final DateTime updatedAt; + final String ownerId; + final String primaryAssetId; + + const Stack({ + required this.id, + required this.createdAt, + required this.updatedAt, + required this.ownerId, + required this.primaryAssetId, + }); + + Stack copyWith({ + String? id, + DateTime? createdAt, + DateTime? updatedAt, + String? ownerId, + String? primaryAssetId, + }) { + return Stack( + id: id ?? this.id, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + ownerId: ownerId ?? this.ownerId, + primaryAssetId: primaryAssetId ?? this.primaryAssetId, + ); + } + + Map toMap() { + return { + 'id': id, + 'createdAt': createdAt.millisecondsSinceEpoch, + 'updatedAt': updatedAt.millisecondsSinceEpoch, + 'ownerId': ownerId, + 'primaryAssetId': primaryAssetId, + }; + } + + factory Stack.fromMap(Map map) { + return Stack( + id: map['id'] as String, + createdAt: DateTime.fromMillisecondsSinceEpoch(map['createdAt'] as int), + updatedAt: DateTime.fromMillisecondsSinceEpoch(map['updatedAt'] as int), + ownerId: map['ownerId'] as String, + primaryAssetId: map['primaryAssetId'] as String, + ); + } + + String toJson() => json.encode(toMap()); + + factory Stack.fromJson(String source) => + Stack.fromMap(json.decode(source) as Map); + + @override + String toString() { + return 'Stack(id: $id, createdAt: $createdAt, updatedAt: $updatedAt, ownerId: $ownerId, primaryAssetId: $primaryAssetId)'; + } + + @override + bool operator ==(covariant Stack other) { + if (identical(this, other)) return true; + + return other.id == id && + other.createdAt == createdAt && + other.updatedAt == updatedAt && + other.ownerId == ownerId && + other.primaryAssetId == primaryAssetId; + } + + @override + int get hashCode { + return id.hashCode ^ + createdAt.hashCode ^ + updatedAt.hashCode ^ + ownerId.hashCode ^ + primaryAssetId.hashCode; + } +} diff --git a/mobile/lib/domain/services/sync_stream.service.dart b/mobile/lib/domain/services/sync_stream.service.dart index c4e40726b5..ee0ec6c44f 100644 --- a/mobile/lib/domain/services/sync_stream.service.dart +++ b/mobile/lib/domain/services/sync_stream.service.dart @@ -154,6 +154,25 @@ class SyncStreamService { return _syncStreamRepository.updateMemoryAssetsV1(data.cast()); case SyncEntityType.memoryToAssetDeleteV1: return _syncStreamRepository.deleteMemoryAssetsV1(data.cast()); + case SyncEntityType.stackV1: + return _syncStreamRepository.updateStacksV1(data.cast()); + case SyncEntityType.stackDeleteV1: + return _syncStreamRepository.deleteStacksV1(data.cast()); + case SyncEntityType.partnerStackV1: + return _syncStreamRepository.updateStacksV1( + data.cast(), + debugLabel: 'partner', + ); + case SyncEntityType.partnerStackBackfillV1: + return _syncStreamRepository.updateStacksV1( + data.cast(), + debugLabel: 'partner backfill', + ); + case SyncEntityType.partnerStackDeleteV1: + return _syncStreamRepository.deleteStacksV1( + data.cast(), + debugLabel: 'partner', + ); default: _logger.warning("Unknown sync data type: $type"); } diff --git a/mobile/lib/infrastructure/entities/stack.entity.dart b/mobile/lib/infrastructure/entities/stack.entity.dart new file mode 100644 index 0000000000..92375f19db --- /dev/null +++ b/mobile/lib/infrastructure/entities/stack.entity.dart @@ -0,0 +1,22 @@ +import 'package:drift/drift.dart'; +import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.dart'; +import 'package:immich_mobile/infrastructure/entities/user.entity.dart'; +import 'package:immich_mobile/infrastructure/utils/drift_default.mixin.dart'; + +class StackEntity extends Table with DriftDefaultsMixin { + const StackEntity(); + + TextColumn get id => text()(); + + DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)(); + + DateTimeColumn get updatedAt => dateTime().withDefault(currentDateAndTime)(); + + TextColumn get ownerId => + text().references(UserEntity, #id, onDelete: KeyAction.cascade)(); + + TextColumn get primaryAssetId => text().references(RemoteAssetEntity, #id)(); + + @override + Set get primaryKey => {id}; +} diff --git a/mobile/lib/infrastructure/entities/stack.entity.drift.dart b/mobile/lib/infrastructure/entities/stack.entity.drift.dart new file mode 100644 index 0000000000..c0d000e02a --- /dev/null +++ b/mobile/lib/infrastructure/entities/stack.entity.drift.dart @@ -0,0 +1,706 @@ +// dart format width=80 +// ignore_for_file: type=lint +import 'package:drift/drift.dart' as i0; +import 'package:immich_mobile/infrastructure/entities/stack.entity.drift.dart' + as i1; +import 'package:immich_mobile/infrastructure/entities/stack.entity.dart' as i2; +import 'package:drift/src/runtime/query_builder/query_builder.dart' as i3; +import 'package:immich_mobile/infrastructure/entities/user.entity.drift.dart' + as i4; +import 'package:drift/internal/modular.dart' as i5; +import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.drift.dart' + as i6; + +typedef $$StackEntityTableCreateCompanionBuilder = i1.StackEntityCompanion + Function({ + required String id, + i0.Value createdAt, + i0.Value updatedAt, + required String ownerId, + required String primaryAssetId, +}); +typedef $$StackEntityTableUpdateCompanionBuilder = i1.StackEntityCompanion + Function({ + i0.Value id, + i0.Value createdAt, + i0.Value updatedAt, + i0.Value ownerId, + i0.Value primaryAssetId, +}); + +final class $$StackEntityTableReferences extends i0.BaseReferences< + i0.GeneratedDatabase, i1.$StackEntityTable, i1.StackEntityData> { + $$StackEntityTableReferences(super.$_db, super.$_table, super.$_typedResult); + + static i4.$UserEntityTable _ownerIdTable(i0.GeneratedDatabase db) => + i5.ReadDatabaseContainer(db) + .resultSet('user_entity') + .createAlias(i0.$_aliasNameGenerator( + i5.ReadDatabaseContainer(db) + .resultSet('stack_entity') + .ownerId, + i5.ReadDatabaseContainer(db) + .resultSet('user_entity') + .id)); + + i4.$$UserEntityTableProcessedTableManager get ownerId { + final $_column = $_itemColumn('owner_id')!; + + final manager = i4 + .$$UserEntityTableTableManager( + $_db, + i5.ReadDatabaseContainer($_db) + .resultSet('user_entity')) + .filter((f) => f.id.sqlEquals($_column)); + final item = $_typedResult.readTableOrNull(_ownerIdTable($_db)); + if (item == null) return manager; + return i0.ProcessedTableManager( + manager.$state.copyWith(prefetchedData: [item])); + } + + static i6.$RemoteAssetEntityTable _primaryAssetIdTable( + i0.GeneratedDatabase db) => + i5.ReadDatabaseContainer(db) + .resultSet('remote_asset_entity') + .createAlias(i0.$_aliasNameGenerator( + i5.ReadDatabaseContainer(db) + .resultSet('stack_entity') + .primaryAssetId, + i5.ReadDatabaseContainer(db) + .resultSet('remote_asset_entity') + .id)); + + i6.$$RemoteAssetEntityTableProcessedTableManager get primaryAssetId { + final $_column = $_itemColumn('primary_asset_id')!; + + final manager = i6 + .$$RemoteAssetEntityTableTableManager( + $_db, + i5.ReadDatabaseContainer($_db) + .resultSet('remote_asset_entity')) + .filter((f) => f.id.sqlEquals($_column)); + final item = $_typedResult.readTableOrNull(_primaryAssetIdTable($_db)); + if (item == null) return manager; + return i0.ProcessedTableManager( + manager.$state.copyWith(prefetchedData: [item])); + } +} + +class $$StackEntityTableFilterComposer + extends i0.Composer { + $$StackEntityTableFilterComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + i0.ColumnFilters get id => $composableBuilder( + column: $table.id, builder: (column) => i0.ColumnFilters(column)); + + i0.ColumnFilters get createdAt => $composableBuilder( + column: $table.createdAt, builder: (column) => i0.ColumnFilters(column)); + + i0.ColumnFilters get updatedAt => $composableBuilder( + column: $table.updatedAt, builder: (column) => i0.ColumnFilters(column)); + + i4.$$UserEntityTableFilterComposer get ownerId { + final i4.$$UserEntityTableFilterComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.ownerId, + referencedTable: i5.ReadDatabaseContainer($db) + .resultSet('user_entity'), + getReferencedColumn: (t) => t.id, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + i4.$$UserEntityTableFilterComposer( + $db: $db, + $table: i5.ReadDatabaseContainer($db) + .resultSet('user_entity'), + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return composer; + } + + i6.$$RemoteAssetEntityTableFilterComposer get primaryAssetId { + final i6.$$RemoteAssetEntityTableFilterComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.primaryAssetId, + referencedTable: i5.ReadDatabaseContainer($db) + .resultSet('remote_asset_entity'), + getReferencedColumn: (t) => t.id, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + i6.$$RemoteAssetEntityTableFilterComposer( + $db: $db, + $table: i5.ReadDatabaseContainer($db) + .resultSet('remote_asset_entity'), + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return composer; + } +} + +class $$StackEntityTableOrderingComposer + extends i0.Composer { + $$StackEntityTableOrderingComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + i0.ColumnOrderings get id => $composableBuilder( + column: $table.id, builder: (column) => i0.ColumnOrderings(column)); + + i0.ColumnOrderings get createdAt => $composableBuilder( + column: $table.createdAt, + builder: (column) => i0.ColumnOrderings(column)); + + i0.ColumnOrderings get updatedAt => $composableBuilder( + column: $table.updatedAt, + builder: (column) => i0.ColumnOrderings(column)); + + i4.$$UserEntityTableOrderingComposer get ownerId { + final i4.$$UserEntityTableOrderingComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.ownerId, + referencedTable: i5.ReadDatabaseContainer($db) + .resultSet('user_entity'), + getReferencedColumn: (t) => t.id, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + i4.$$UserEntityTableOrderingComposer( + $db: $db, + $table: i5.ReadDatabaseContainer($db) + .resultSet('user_entity'), + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return composer; + } + + i6.$$RemoteAssetEntityTableOrderingComposer get primaryAssetId { + final i6.$$RemoteAssetEntityTableOrderingComposer composer = + $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.primaryAssetId, + referencedTable: i5.ReadDatabaseContainer($db) + .resultSet('remote_asset_entity'), + getReferencedColumn: (t) => t.id, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + i6.$$RemoteAssetEntityTableOrderingComposer( + $db: $db, + $table: i5.ReadDatabaseContainer($db) + .resultSet( + 'remote_asset_entity'), + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return composer; + } +} + +class $$StackEntityTableAnnotationComposer + extends i0.Composer { + $$StackEntityTableAnnotationComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + i0.GeneratedColumn get id => + $composableBuilder(column: $table.id, builder: (column) => column); + + i0.GeneratedColumn get createdAt => + $composableBuilder(column: $table.createdAt, builder: (column) => column); + + i0.GeneratedColumn get updatedAt => + $composableBuilder(column: $table.updatedAt, builder: (column) => column); + + i4.$$UserEntityTableAnnotationComposer get ownerId { + final i4.$$UserEntityTableAnnotationComposer composer = $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.ownerId, + referencedTable: i5.ReadDatabaseContainer($db) + .resultSet('user_entity'), + getReferencedColumn: (t) => t.id, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + i4.$$UserEntityTableAnnotationComposer( + $db: $db, + $table: i5.ReadDatabaseContainer($db) + .resultSet('user_entity'), + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return composer; + } + + i6.$$RemoteAssetEntityTableAnnotationComposer get primaryAssetId { + final i6.$$RemoteAssetEntityTableAnnotationComposer composer = + $composerBuilder( + composer: this, + getCurrentColumn: (t) => t.primaryAssetId, + referencedTable: i5.ReadDatabaseContainer($db) + .resultSet('remote_asset_entity'), + getReferencedColumn: (t) => t.id, + builder: (joinBuilder, + {$addJoinBuilderToRootComposer, + $removeJoinBuilderFromRootComposer}) => + i6.$$RemoteAssetEntityTableAnnotationComposer( + $db: $db, + $table: i5.ReadDatabaseContainer($db) + .resultSet( + 'remote_asset_entity'), + $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, + joinBuilder: joinBuilder, + $removeJoinBuilderFromRootComposer: + $removeJoinBuilderFromRootComposer, + )); + return composer; + } +} + +class $$StackEntityTableTableManager extends i0.RootTableManager< + i0.GeneratedDatabase, + i1.$StackEntityTable, + i1.StackEntityData, + i1.$$StackEntityTableFilterComposer, + i1.$$StackEntityTableOrderingComposer, + i1.$$StackEntityTableAnnotationComposer, + $$StackEntityTableCreateCompanionBuilder, + $$StackEntityTableUpdateCompanionBuilder, + (i1.StackEntityData, i1.$$StackEntityTableReferences), + i1.StackEntityData, + i0.PrefetchHooks Function({bool ownerId, bool primaryAssetId})> { + $$StackEntityTableTableManager( + i0.GeneratedDatabase db, i1.$StackEntityTable table) + : super(i0.TableManagerState( + db: db, + table: table, + createFilteringComposer: () => + i1.$$StackEntityTableFilterComposer($db: db, $table: table), + createOrderingComposer: () => + i1.$$StackEntityTableOrderingComposer($db: db, $table: table), + createComputedFieldComposer: () => + i1.$$StackEntityTableAnnotationComposer($db: db, $table: table), + updateCompanionCallback: ({ + i0.Value id = const i0.Value.absent(), + i0.Value createdAt = const i0.Value.absent(), + i0.Value updatedAt = const i0.Value.absent(), + i0.Value ownerId = const i0.Value.absent(), + i0.Value primaryAssetId = const i0.Value.absent(), + }) => + i1.StackEntityCompanion( + id: id, + createdAt: createdAt, + updatedAt: updatedAt, + ownerId: ownerId, + primaryAssetId: primaryAssetId, + ), + createCompanionCallback: ({ + required String id, + i0.Value createdAt = const i0.Value.absent(), + i0.Value updatedAt = const i0.Value.absent(), + required String ownerId, + required String primaryAssetId, + }) => + i1.StackEntityCompanion.insert( + id: id, + createdAt: createdAt, + updatedAt: updatedAt, + ownerId: ownerId, + primaryAssetId: primaryAssetId, + ), + withReferenceMapper: (p0) => p0 + .map((e) => ( + e.readTable(table), + i1.$$StackEntityTableReferences(db, table, e) + )) + .toList(), + prefetchHooksCallback: ({ownerId = false, primaryAssetId = 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 (ownerId) { + state = state.withJoin( + currentTable: table, + currentColumn: table.ownerId, + referencedTable: + i1.$$StackEntityTableReferences._ownerIdTable(db), + referencedColumn: + i1.$$StackEntityTableReferences._ownerIdTable(db).id, + ) as T; + } + if (primaryAssetId) { + state = state.withJoin( + currentTable: table, + currentColumn: table.primaryAssetId, + referencedTable: i1.$$StackEntityTableReferences + ._primaryAssetIdTable(db), + referencedColumn: i1.$$StackEntityTableReferences + ._primaryAssetIdTable(db) + .id, + ) as T; + } + + return state; + }, + getPrefetchedDataCallback: (items) async { + return []; + }, + ); + }, + )); +} + +typedef $$StackEntityTableProcessedTableManager = i0.ProcessedTableManager< + i0.GeneratedDatabase, + i1.$StackEntityTable, + i1.StackEntityData, + i1.$$StackEntityTableFilterComposer, + i1.$$StackEntityTableOrderingComposer, + i1.$$StackEntityTableAnnotationComposer, + $$StackEntityTableCreateCompanionBuilder, + $$StackEntityTableUpdateCompanionBuilder, + (i1.StackEntityData, i1.$$StackEntityTableReferences), + i1.StackEntityData, + i0.PrefetchHooks Function({bool ownerId, bool primaryAssetId})>; + +class $StackEntityTable extends i2.StackEntity + with i0.TableInfo<$StackEntityTable, i1.StackEntityData> { + @override + final i0.GeneratedDatabase attachedDatabase; + final String? _alias; + $StackEntityTable(this.attachedDatabase, [this._alias]); + static const i0.VerificationMeta _idMeta = const i0.VerificationMeta('id'); + @override + late final i0.GeneratedColumn id = i0.GeneratedColumn( + 'id', aliasedName, false, + type: i0.DriftSqlType.string, requiredDuringInsert: true); + static const i0.VerificationMeta _createdAtMeta = + const i0.VerificationMeta('createdAt'); + @override + late final i0.GeneratedColumn createdAt = + i0.GeneratedColumn('created_at', aliasedName, false, + type: i0.DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: i3.currentDateAndTime); + static const i0.VerificationMeta _updatedAtMeta = + const i0.VerificationMeta('updatedAt'); + @override + late final i0.GeneratedColumn updatedAt = + i0.GeneratedColumn('updated_at', aliasedName, false, + type: i0.DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: i3.currentDateAndTime); + static const i0.VerificationMeta _ownerIdMeta = + const i0.VerificationMeta('ownerId'); + @override + late final i0.GeneratedColumn ownerId = i0.GeneratedColumn( + 'owner_id', aliasedName, false, + type: i0.DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: i0.GeneratedColumn.constraintIsAlways( + 'REFERENCES user_entity (id) ON DELETE CASCADE')); + static const i0.VerificationMeta _primaryAssetIdMeta = + const i0.VerificationMeta('primaryAssetId'); + @override + late final i0.GeneratedColumn primaryAssetId = + i0.GeneratedColumn( + 'primary_asset_id', aliasedName, false, + type: i0.DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: i0.GeneratedColumn.constraintIsAlways( + 'REFERENCES remote_asset_entity (id)')); + @override + List get $columns => + [id, createdAt, updatedAt, ownerId, primaryAssetId]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'stack_entity'; + @override + i0.VerificationContext validateIntegrity( + i0.Insertable 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('created_at')) { + context.handle(_createdAtMeta, + createdAt.isAcceptableOrUnknown(data['created_at']!, _createdAtMeta)); + } + if (data.containsKey('updated_at')) { + context.handle(_updatedAtMeta, + updatedAt.isAcceptableOrUnknown(data['updated_at']!, _updatedAtMeta)); + } + if (data.containsKey('owner_id')) { + context.handle(_ownerIdMeta, + ownerId.isAcceptableOrUnknown(data['owner_id']!, _ownerIdMeta)); + } else if (isInserting) { + context.missing(_ownerIdMeta); + } + if (data.containsKey('primary_asset_id')) { + context.handle( + _primaryAssetIdMeta, + primaryAssetId.isAcceptableOrUnknown( + data['primary_asset_id']!, _primaryAssetIdMeta)); + } else if (isInserting) { + context.missing(_primaryAssetIdMeta); + } + return context; + } + + @override + Set get $primaryKey => {id}; + @override + i1.StackEntityData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return i1.StackEntityData( + id: attachedDatabase.typeMapping + .read(i0.DriftSqlType.string, data['${effectivePrefix}id'])!, + createdAt: attachedDatabase.typeMapping.read( + i0.DriftSqlType.dateTime, data['${effectivePrefix}created_at'])!, + updatedAt: attachedDatabase.typeMapping.read( + i0.DriftSqlType.dateTime, data['${effectivePrefix}updated_at'])!, + ownerId: attachedDatabase.typeMapping + .read(i0.DriftSqlType.string, data['${effectivePrefix}owner_id'])!, + primaryAssetId: attachedDatabase.typeMapping.read( + i0.DriftSqlType.string, data['${effectivePrefix}primary_asset_id'])!, + ); + } + + @override + $StackEntityTable createAlias(String alias) { + return $StackEntityTable(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class StackEntityData extends i0.DataClass + implements i0.Insertable { + final String id; + final DateTime createdAt; + final DateTime updatedAt; + final String ownerId; + final String primaryAssetId; + const StackEntityData( + {required this.id, + required this.createdAt, + required this.updatedAt, + required this.ownerId, + required this.primaryAssetId}); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = i0.Variable(id); + map['created_at'] = i0.Variable(createdAt); + map['updated_at'] = i0.Variable(updatedAt); + map['owner_id'] = i0.Variable(ownerId); + map['primary_asset_id'] = i0.Variable(primaryAssetId); + return map; + } + + factory StackEntityData.fromJson(Map json, + {i0.ValueSerializer? serializer}) { + serializer ??= i0.driftRuntimeOptions.defaultSerializer; + return StackEntityData( + id: serializer.fromJson(json['id']), + createdAt: serializer.fromJson(json['createdAt']), + updatedAt: serializer.fromJson(json['updatedAt']), + ownerId: serializer.fromJson(json['ownerId']), + primaryAssetId: serializer.fromJson(json['primaryAssetId']), + ); + } + @override + Map toJson({i0.ValueSerializer? serializer}) { + serializer ??= i0.driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'createdAt': serializer.toJson(createdAt), + 'updatedAt': serializer.toJson(updatedAt), + 'ownerId': serializer.toJson(ownerId), + 'primaryAssetId': serializer.toJson(primaryAssetId), + }; + } + + i1.StackEntityData copyWith( + {String? id, + DateTime? createdAt, + DateTime? updatedAt, + String? ownerId, + String? primaryAssetId}) => + i1.StackEntityData( + id: id ?? this.id, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + ownerId: ownerId ?? this.ownerId, + primaryAssetId: primaryAssetId ?? this.primaryAssetId, + ); + StackEntityData copyWithCompanion(i1.StackEntityCompanion data) { + return StackEntityData( + id: data.id.present ? data.id.value : this.id, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt, + ownerId: data.ownerId.present ? data.ownerId.value : this.ownerId, + primaryAssetId: data.primaryAssetId.present + ? data.primaryAssetId.value + : this.primaryAssetId, + ); + } + + @override + String toString() { + return (StringBuffer('StackEntityData(') + ..write('id: $id, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('ownerId: $ownerId, ') + ..write('primaryAssetId: $primaryAssetId') + ..write(')')) + .toString(); + } + + @override + int get hashCode => + Object.hash(id, createdAt, updatedAt, ownerId, primaryAssetId); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is i1.StackEntityData && + other.id == this.id && + other.createdAt == this.createdAt && + other.updatedAt == this.updatedAt && + other.ownerId == this.ownerId && + other.primaryAssetId == this.primaryAssetId); +} + +class StackEntityCompanion extends i0.UpdateCompanion { + final i0.Value id; + final i0.Value createdAt; + final i0.Value updatedAt; + final i0.Value ownerId; + final i0.Value primaryAssetId; + const StackEntityCompanion({ + this.id = const i0.Value.absent(), + this.createdAt = const i0.Value.absent(), + this.updatedAt = const i0.Value.absent(), + this.ownerId = const i0.Value.absent(), + this.primaryAssetId = const i0.Value.absent(), + }); + StackEntityCompanion.insert({ + required String id, + this.createdAt = const i0.Value.absent(), + this.updatedAt = const i0.Value.absent(), + required String ownerId, + required String primaryAssetId, + }) : id = i0.Value(id), + ownerId = i0.Value(ownerId), + primaryAssetId = i0.Value(primaryAssetId); + static i0.Insertable custom({ + i0.Expression? id, + i0.Expression? createdAt, + i0.Expression? updatedAt, + i0.Expression? ownerId, + i0.Expression? primaryAssetId, + }) { + return i0.RawValuesInsertable({ + if (id != null) 'id': id, + if (createdAt != null) 'created_at': createdAt, + if (updatedAt != null) 'updated_at': updatedAt, + if (ownerId != null) 'owner_id': ownerId, + if (primaryAssetId != null) 'primary_asset_id': primaryAssetId, + }); + } + + i1.StackEntityCompanion copyWith( + {i0.Value? id, + i0.Value? createdAt, + i0.Value? updatedAt, + i0.Value? ownerId, + i0.Value? primaryAssetId}) { + return i1.StackEntityCompanion( + id: id ?? this.id, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + ownerId: ownerId ?? this.ownerId, + primaryAssetId: primaryAssetId ?? this.primaryAssetId, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = i0.Variable(id.value); + } + if (createdAt.present) { + map['created_at'] = i0.Variable(createdAt.value); + } + if (updatedAt.present) { + map['updated_at'] = i0.Variable(updatedAt.value); + } + if (ownerId.present) { + map['owner_id'] = i0.Variable(ownerId.value); + } + if (primaryAssetId.present) { + map['primary_asset_id'] = i0.Variable(primaryAssetId.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('StackEntityCompanion(') + ..write('id: $id, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('ownerId: $ownerId, ') + ..write('primaryAssetId: $primaryAssetId') + ..write(')')) + .toString(); + } +} diff --git a/mobile/lib/infrastructure/repositories/db.repository.dart b/mobile/lib/infrastructure/repositories/db.repository.dart index e71598a999..a7920cf7b2 100644 --- a/mobile/lib/infrastructure/repositories/db.repository.dart +++ b/mobile/lib/infrastructure/repositories/db.repository.dart @@ -14,6 +14,7 @@ import 'package:immich_mobile/infrastructure/entities/remote_album.entity.dart'; import 'package:immich_mobile/infrastructure/entities/remote_album_asset.entity.dart'; import 'package:immich_mobile/infrastructure/entities/remote_album_user.entity.dart'; import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.dart'; +import 'package:immich_mobile/infrastructure/entities/stack.entity.dart'; import 'package:immich_mobile/infrastructure/entities/user.entity.dart'; import 'package:immich_mobile/infrastructure/entities/user_metadata.entity.dart'; import 'package:isar/isar.dart'; @@ -50,6 +51,7 @@ class IsarDatabaseRepository implements IDatabaseRepository { RemoteAlbumUserEntity, MemoryEntity, MemoryAssetEntity, + StackEntity, ], include: { 'package:immich_mobile/infrastructure/entities/merged_asset.drift', diff --git a/mobile/lib/infrastructure/repositories/db.repository.drift.dart b/mobile/lib/infrastructure/repositories/db.repository.drift.dart index 925591def8..15d445d226 100644 --- a/mobile/lib/infrastructure/repositories/db.repository.drift.dart +++ b/mobile/lib/infrastructure/repositories/db.repository.drift.dart @@ -27,9 +27,11 @@ import 'package:immich_mobile/infrastructure/entities/memory.entity.drift.dart' as i12; import 'package:immich_mobile/infrastructure/entities/memory_asset.entity.drift.dart' as i13; -import 'package:immich_mobile/infrastructure/entities/merged_asset.drift.dart' +import 'package:immich_mobile/infrastructure/entities/stack.entity.drift.dart' as i14; -import 'package:drift/internal/modular.dart' as i15; +import 'package:immich_mobile/infrastructure/entities/merged_asset.drift.dart' + as i15; +import 'package:drift/internal/modular.dart' as i16; abstract class $Drift extends i0.GeneratedDatabase { $Drift(i0.QueryExecutor e) : super(e); @@ -58,8 +60,9 @@ abstract class $Drift extends i0.GeneratedDatabase { late final i12.$MemoryEntityTable memoryEntity = i12.$MemoryEntityTable(this); late final i13.$MemoryAssetEntityTable memoryAssetEntity = i13.$MemoryAssetEntityTable(this); - i14.MergedAssetDrift get mergedAssetDrift => i15.ReadDatabaseContainer(this) - .accessor(i14.MergedAssetDrift.new); + late final i14.$StackEntityTable stackEntity = i14.$StackEntityTable(this); + i15.MergedAssetDrift get mergedAssetDrift => i16.ReadDatabaseContainer(this) + .accessor(i15.MergedAssetDrift.new); @override Iterable> get allTables => allSchemaEntities.whereType>(); @@ -80,7 +83,8 @@ abstract class $Drift extends i0.GeneratedDatabase { remoteAlbumAssetEntity, remoteAlbumUserEntity, memoryEntity, - memoryAssetEntity + memoryAssetEntity, + stackEntity ]; @override i0.StreamQueryUpdateRules get streamUpdateRules => @@ -205,6 +209,13 @@ abstract class $Drift extends i0.GeneratedDatabase { i0.TableUpdate('memory_asset_entity', kind: i0.UpdateKind.delete), ], ), + i0.WritePropagation( + on: i0.TableUpdateQuery.onTableName('user_entity', + limitUpdateKind: i0.UpdateKind.delete), + result: [ + i0.TableUpdate('stack_entity', kind: i0.UpdateKind.delete), + ], + ), ], ); @override @@ -242,4 +253,6 @@ class $DriftManager { i12.$$MemoryEntityTableTableManager(_db, _db.memoryEntity); i13.$$MemoryAssetEntityTableTableManager get memoryAssetEntity => i13.$$MemoryAssetEntityTableTableManager(_db, _db.memoryAssetEntity); + i14.$$StackEntityTableTableManager get stackEntity => + i14.$$StackEntityTableTableManager(_db, _db.stackEntity); } diff --git a/mobile/lib/infrastructure/repositories/stack.repository.dart b/mobile/lib/infrastructure/repositories/stack.repository.dart new file mode 100644 index 0000000000..7f97f3d9ae --- /dev/null +++ b/mobile/lib/infrastructure/repositories/stack.repository.dart @@ -0,0 +1,30 @@ +import 'package:drift/drift.dart'; +import 'package:immich_mobile/domain/models/stack.model.dart'; +import 'package:immich_mobile/infrastructure/entities/stack.entity.drift.dart'; +import 'package:immich_mobile/infrastructure/repositories/db.repository.dart'; + +class DriftStackRepository extends DriftDatabaseRepository { + final Drift _db; + const DriftStackRepository(this._db) : super(_db); + + Future> getAll(String userId) { + final query = _db.stackEntity.select() + ..where((e) => e.ownerId.equals(userId)); + + return query.map((stack) { + return stack.toDto(); + }).get(); + } +} + +extension on StackEntityData { + Stack toDto() { + return Stack( + id: id, + createdAt: createdAt, + updatedAt: updatedAt, + ownerId: ownerId, + primaryAssetId: primaryAssetId, + ); + } +} diff --git a/mobile/lib/infrastructure/repositories/sync_api.repository.dart b/mobile/lib/infrastructure/repositories/sync_api.repository.dart index 99199a7fc6..d43f786a29 100644 --- a/mobile/lib/infrastructure/repositories/sync_api.repository.dart +++ b/mobile/lib/infrastructure/repositories/sync_api.repository.dart @@ -54,6 +54,8 @@ class SyncApiRepository { SyncRequestType.albumToAssetsV1, SyncRequestType.memoriesV1, SyncRequestType.memoryToAssetsV1, + SyncRequestType.stacksV1, + SyncRequestType.partnerStacksV1, ], ).toJson(), ); @@ -163,6 +165,11 @@ const _kResponseMap = { SyncEntityType.memoryDeleteV1: SyncMemoryDeleteV1.fromJson, SyncEntityType.memoryToAssetV1: SyncMemoryAssetV1.fromJson, SyncEntityType.memoryToAssetDeleteV1: SyncMemoryAssetDeleteV1.fromJson, + SyncEntityType.stackV1: SyncStackV1.fromJson, + SyncEntityType.stackDeleteV1: SyncStackDeleteV1.fromJson, + SyncEntityType.partnerStackV1: SyncStackV1.fromJson, + SyncEntityType.partnerStackBackfillV1: SyncStackV1.fromJson, + SyncEntityType.partnerStackDeleteV1: SyncStackDeleteV1.fromJson, }; class _SyncAckV1 { diff --git a/mobile/lib/infrastructure/repositories/sync_stream.repository.dart b/mobile/lib/infrastructure/repositories/sync_stream.repository.dart index b88083aa02..89f5c2f59a 100644 --- a/mobile/lib/infrastructure/repositories/sync_stream.repository.dart +++ b/mobile/lib/infrastructure/repositories/sync_stream.repository.dart @@ -12,6 +12,7 @@ import 'package:immich_mobile/infrastructure/entities/remote_album_asset.entity. import 'package:immich_mobile/infrastructure/entities/remote_album_user.entity.drift.dart'; import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.drift.dart'; import 'package:immich_mobile/infrastructure/entities/memory.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'; import 'package:logging/logging.dart'; @@ -69,8 +70,8 @@ class SyncStreamRepository extends DriftDatabaseRepository { ); } }); - } catch (error, stackTrace) { - _logger.severe('Error: SyncPartnerDeleteV1', error, stackTrace); + } catch (error, stack) { + _logger.severe('Error: SyncPartnerDeleteV1', error, stack); rethrow; } } @@ -92,8 +93,8 @@ class SyncStreamRepository extends DriftDatabaseRepository { ); } }); - } catch (error, stackTrace) { - _logger.severe('Error: SyncPartnerV1', error, stackTrace); + } catch (error, stack) { + _logger.severe('Error: SyncPartnerV1', error, stack); rethrow; } } @@ -104,10 +105,10 @@ class SyncStreamRepository extends DriftDatabaseRepository { }) async { try { await _db.remoteAssetEntity.deleteWhere( - (row) => row.id.isIn(data.map((error) => error.assetId)), + (row) => row.id.isIn(data.map((e) => e.assetId)), ); - } catch (error, stackTrace) { - _logger.severe('Error: deleteAssetsV1 - $debugLabel', error, stackTrace); + } catch (error, stack) { + _logger.severe('Error: deleteAssetsV1 - $debugLabel', error, stack); rethrow; } } @@ -142,8 +143,8 @@ class SyncStreamRepository extends DriftDatabaseRepository { ); } }); - } catch (error, stackTrace) { - _logger.severe('Error: updateAssetsV1 - $debugLabel', error, stackTrace); + } catch (error, stack) { + _logger.severe('Error: updateAssetsV1 - $debugLabel', error, stack); rethrow; } } @@ -186,11 +187,11 @@ class SyncStreamRepository extends DriftDatabaseRepository { ); } }); - } catch (error, stackTrace) { + } catch (error, stack) { _logger.severe( 'Error: updateAssetsExifV1 - $debugLabel', error, - stackTrace, + stack, ); rethrow; } @@ -201,8 +202,8 @@ class SyncStreamRepository extends DriftDatabaseRepository { await _db.remoteAlbumEntity.deleteWhere( (row) => row.id.isIn(data.map((e) => e.albumId)), ); - } catch (error, stackTrace) { - _logger.severe('Error: deleteAlbumsV1', error, stackTrace); + } catch (error, stack) { + _logger.severe('Error: deleteAlbumsV1', error, stack); rethrow; } } @@ -229,8 +230,8 @@ class SyncStreamRepository extends DriftDatabaseRepository { ); } }); - } catch (error, stackTrace) { - _logger.severe('Error: updateAlbumsV1', error, stackTrace); + } catch (error, stack) { + _logger.severe('Error: updateAlbumsV1', error, stack); rethrow; } } @@ -248,8 +249,8 @@ class SyncStreamRepository extends DriftDatabaseRepository { ); } }); - } catch (error, stackTrace) { - _logger.severe('Error: deleteAlbumUsersV1', error, stackTrace); + } catch (error, stack) { + _logger.severe('Error: deleteAlbumUsersV1', error, stack); rethrow; } } @@ -275,11 +276,11 @@ class SyncStreamRepository extends DriftDatabaseRepository { ); } }); - } catch (error, stackTrace) { + } catch (error, stack) { _logger.severe( 'Error: updateAlbumUsersV1 - $debugLabel', error, - stackTrace, + stack, ); rethrow; } @@ -300,8 +301,8 @@ class SyncStreamRepository extends DriftDatabaseRepository { ); } }); - } catch (error, stackTrace) { - _logger.severe('Error: deleteAlbumToAssetsV1', error, stackTrace); + } catch (error, stack) { + _logger.severe('Error: deleteAlbumToAssetsV1', error, stack); rethrow; } } @@ -325,11 +326,11 @@ class SyncStreamRepository extends DriftDatabaseRepository { ); } }); - } catch (error, stackTrace) { + } catch (error, stack) { _logger.severe( 'Error: updateAlbumToAssetsV1 - $debugLabel', error, - stackTrace, + stack, ); rethrow; } @@ -359,8 +360,8 @@ class SyncStreamRepository extends DriftDatabaseRepository { ); } }); - } catch (error, stackTrace) { - _logger.severe('Error: updateMemoriesV1', error, stackTrace); + } catch (error, stack) { + _logger.severe('Error: updateMemoriesV1', error, stack); rethrow; } } @@ -370,8 +371,8 @@ class SyncStreamRepository extends DriftDatabaseRepository { await _db.memoryEntity.deleteWhere( (row) => row.id.isIn(data.map((e) => e.memoryId)), ); - } catch (error, stackTrace) { - _logger.severe('Error: deleteMemoriesV1', error, stackTrace); + } catch (error, stack) { + _logger.severe('Error: deleteMemoriesV1', error, stack); rethrow; } } @@ -392,8 +393,8 @@ class SyncStreamRepository extends DriftDatabaseRepository { ); } }); - } catch (error, stackTrace) { - _logger.severe('Error: updateMemoryAssetsV1', error, stackTrace); + } catch (error, stack) { + _logger.severe('Error: updateMemoryAssetsV1', error, stack); rethrow; } } @@ -413,8 +414,49 @@ class SyncStreamRepository extends DriftDatabaseRepository { ); } }); - } catch (error, stackTrace) { - _logger.severe('Error: deleteMemoryAssetsV1', error, stackTrace); + } catch (error, stack) { + _logger.severe('Error: deleteMemoryAssetsV1', error, stack); + rethrow; + } + } + + Future updateStacksV1( + Iterable data, { + String debugLabel = 'user', + }) async { + try { + await _db.batch((batch) { + for (final stack in data) { + final companion = StackEntityCompanion( + createdAt: Value(stack.createdAt), + updatedAt: Value(stack.updatedAt), + ownerId: Value(stack.ownerId), + primaryAssetId: Value(stack.primaryAssetId), + ); + + batch.insert( + _db.stackEntity, + companion.copyWith(id: Value(stack.id)), + onConflict: DoUpdate((_) => companion), + ); + } + }); + } catch (error, stack) { + _logger.severe('Error: updateStacksV1 - $debugLabel', error, stack); + rethrow; + } + } + + Future deleteStacksV1( + Iterable data, { + String debugLabel = 'user', + }) async { + try { + await _db.stackEntity.deleteWhere( + (row) => row.id.isIn(data.map((e) => e.stackId)), + ); + } catch (error, stack) { + _logger.severe('Error: deleteStacksV1 - $debugLabel', error, stack); rethrow; } } @@ -467,7 +509,7 @@ extension on String { Duration? toDuration() { try { final parts = split(':') - .map((error) => double.parse(error).toInt()) + .map((e) => double.parse(e).toInt()) .toList(growable: false); return Duration(hours: parts[0], minutes: parts[1], seconds: parts[2]); diff --git a/mobile/lib/presentation/pages/dev/feat_in_development.page.dart b/mobile/lib/presentation/pages/dev/feat_in_development.page.dart index f10c042e10..e487d644e9 100644 --- a/mobile/lib/presentation/pages/dev/feat_in_development.page.dart +++ b/mobile/lib/presentation/pages/dev/feat_in_development.page.dart @@ -66,6 +66,9 @@ final _features = [ await db.remoteAlbumEntity.deleteAll(); await db.remoteAlbumUserEntity.deleteAll(); await db.remoteAlbumAssetEntity.deleteAll(); + await db.memoryEntity.deleteAll(); + await db.memoryAssetEntity.deleteAll(); + await db.stackEntity.deleteAll(); }, ), _Feature( diff --git a/mobile/lib/presentation/pages/dev/media_stat.page.dart b/mobile/lib/presentation/pages/dev/media_stat.page.dart index f0a648fd5a..e5745fa629 100644 --- a/mobile/lib/presentation/pages/dev/media_stat.page.dart +++ b/mobile/lib/presentation/pages/dev/media_stat.page.dart @@ -162,6 +162,10 @@ final _remoteStats = [ name: 'Memories Assets', load: (db) => db.managers.memoryAssetEntity.count(), ), + _Stat( + name: 'Stacks', + load: (db) => db.managers.stackEntity.count(), + ), ]; @RoutePage() diff --git a/mobile/lib/providers/stack.provider.dart b/mobile/lib/providers/stack.provider.dart new file mode 100644 index 0000000000..71abd1e87a --- /dev/null +++ b/mobile/lib/providers/stack.provider.dart @@ -0,0 +1,7 @@ +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:immich_mobile/infrastructure/repositories/stack.repository.dart'; +import 'package:immich_mobile/providers/infrastructure/db.provider.dart'; + +final driftStackProvider = Provider( + (ref) => DriftStackRepository(ref.watch(driftProvider)), +); diff --git a/mobile/lib/repositories/auth.repository.dart b/mobile/lib/repositories/auth.repository.dart index 3ad8e34580..4ee4d8c131 100644 --- a/mobile/lib/repositories/auth.repository.dart +++ b/mobile/lib/repositories/auth.repository.dart @@ -40,6 +40,9 @@ class AuthRepository extends DatabaseRepository { _drift.remoteAlbumEntity.deleteAll(), _drift.remoteAlbumAssetEntity.deleteAll(), _drift.remoteAlbumUserEntity.deleteAll(), + _drift.memoryEntity.deleteAll(), + _drift.memoryAssetEntity.deleteAll(), + _drift.stackEntity.deleteAll(), ]); }); } diff --git a/mobile/test/domain/services/sync_stream_service_test.dart b/mobile/test/domain/services/sync_stream_service_test.dart index 28288422fd..27cd8c5b21 100644 --- a/mobile/test/domain/services/sync_stream_service_test.dart +++ b/mobile/test/domain/services/sync_stream_service_test.dart @@ -89,6 +89,18 @@ void main() { .thenAnswer(successHandler); when(() => mockSyncStreamRepo.deleteMemoryAssetsV1(any())) .thenAnswer(successHandler); + when( + () => mockSyncStreamRepo.updateStacksV1( + any(), + debugLabel: any(named: 'debugLabel'), + ), + ).thenAnswer(successHandler); + when( + () => mockSyncStreamRepo.deleteStacksV1( + any(), + debugLabel: any(named: 'debugLabel'), + ), + ).thenAnswer(successHandler); sut = SyncStreamService( syncApiRepository: mockSyncApiRepo,