diff --git a/mobile/drift_schemas/main/drift_schema_v1.json b/mobile/drift_schemas/main/drift_schema_v1.json index 9fc7d17d56..03656ce0b4 100644 --- a/mobile/drift_schemas/main/drift_schema_v1.json +++ b/mobile/drift_schemas/main/drift_schema_v1.json @@ -1 +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":"live_photo_video_id","getter_name":"livePhotoVideoId","moor_type":"string","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":[]},{"name":"orientation","getter_name":"orientation","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":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 +{"_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":[]},{"name":"orientation","getter_name":"orientation","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":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":"key","getter_name":"key","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumIndexConverter(UserMetadataKey.values)","dart_type_name":"UserMetadataKey"}},{"name":"value","getter_name":"value","moor_type":"blob","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"userMetadataConverter","dart_type_name":"Map"}}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["user_id","key"]}},{"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/user_metadata.model.dart b/mobile/lib/domain/models/user_metadata.model.dart index 1586384422..c5c63cad5e 100644 --- a/mobile/lib/domain/models/user_metadata.model.dart +++ b/mobile/lib/domain/models/user_metadata.model.dart @@ -1,5 +1,12 @@ import 'dart:ui'; +enum UserMetadataKey { + // do not change this order! + onboarding, + preferences, + license, +} + enum AvatarColor { // do not change this order or reuse indices for other purposes, adding is OK primary("primary"), @@ -31,7 +38,45 @@ enum AvatarColor { }; } -class UserPreferences { +class Onboarding { + final bool isOnboarded; + + const Onboarding({required this.isOnboarded}); + + Onboarding copyWith({bool? isOnboarded}) { + return Onboarding(isOnboarded: isOnboarded ?? this.isOnboarded); + } + + Map toMap() { + final onboarding = {}; + onboarding["isOnboarded"] = isOnboarded; + return onboarding; + } + + factory Onboarding.fromMap(Map map) { + return Onboarding(isOnboarded: map["isOnboarded"] as bool); + } + + @override + String toString() { + return '''Onboarding { +isOnboarded: $isOnboarded, +}'''; + } + + @override + bool operator ==(covariant Onboarding other) { + if (identical(this, other)) return true; + + return isOnboarded == other.isOnboarded; + } + + @override + int get hashCode => isOnboarded.hashCode; +} + +// TODO: wait to be overwritten +class Preferences { final bool foldersEnabled; final bool memoriesEnabled; final bool peopleEnabled; @@ -41,7 +86,7 @@ class UserPreferences { final AvatarColor userAvatarColor; final bool showSupportBadge; - const UserPreferences({ + const Preferences({ this.foldersEnabled = false, this.memoriesEnabled = true, this.peopleEnabled = true, @@ -52,7 +97,7 @@ class UserPreferences { this.showSupportBadge = true, }); - UserPreferences copyWith({ + Preferences copyWith({ bool? foldersEnabled, bool? memoriesEnabled, bool? peopleEnabled, @@ -62,7 +107,7 @@ class UserPreferences { AvatarColor? userAvatarColor, bool? showSupportBadge, }) { - return UserPreferences( + return Preferences( foldersEnabled: foldersEnabled ?? this.foldersEnabled, memoriesEnabled: memoriesEnabled ?? this.memoriesEnabled, peopleEnabled: peopleEnabled ?? this.peopleEnabled, @@ -87,8 +132,8 @@ class UserPreferences { return preferences; } - factory UserPreferences.fromMap(Map map) { - return UserPreferences( + factory Preferences.fromMap(Map map) { + return Preferences( foldersEnabled: map["folders-Enabled"] as bool? ?? false, memoriesEnabled: map["memories-Enabled"] as bool? ?? true, peopleEnabled: map["people-Enabled"] as bool? ?? true, @@ -102,4 +147,173 @@ class UserPreferences { showSupportBadge: map["purchase-ShowSupportBadge"] as bool? ?? true, ); } + + @override + String toString() { + return '''Preferences: { +foldersEnabled: $foldersEnabled, +memoriesEnabled: $memoriesEnabled, +peopleEnabled: $peopleEnabled, +ratingsEnabled: $ratingsEnabled, +sharedLinksEnabled: $sharedLinksEnabled, +tagsEnabled: $tagsEnabled, +userAvatarColor: $userAvatarColor, +showSupportBadge: $showSupportBadge, +}'''; + } + + @override + bool operator ==(covariant Preferences other) { + if (identical(this, other)) return true; + + return other.foldersEnabled == foldersEnabled && + other.memoriesEnabled == memoriesEnabled && + other.peopleEnabled == peopleEnabled && + other.ratingsEnabled == ratingsEnabled && + other.sharedLinksEnabled == sharedLinksEnabled && + other.tagsEnabled == tagsEnabled && + other.userAvatarColor == userAvatarColor && + other.showSupportBadge == showSupportBadge; + } + + @override + int get hashCode { + return foldersEnabled.hashCode ^ + memoriesEnabled.hashCode ^ + peopleEnabled.hashCode ^ + ratingsEnabled.hashCode ^ + sharedLinksEnabled.hashCode ^ + tagsEnabled.hashCode ^ + userAvatarColor.hashCode ^ + showSupportBadge.hashCode; + } +} + +class License { + final DateTime activatedAt; + final String activationKey; + final String licenseKey; + + const License({ + required this.activatedAt, + required this.activationKey, + required this.licenseKey, + }); + + License copyWith({ + DateTime? activatedAt, + String? activationKey, + String? licenseKey, + }) { + return License( + activatedAt: activatedAt ?? this.activatedAt, + activationKey: activationKey ?? this.activationKey, + licenseKey: licenseKey ?? this.licenseKey, + ); + } + + Map toMap() { + final license = {}; + license["activatedAt"] = activatedAt; + license["activationKey"] = activationKey; + license["licenseKey"] = licenseKey; + return license; + } + + factory License.fromMap(Map map) { + return License( + activatedAt: map["activatedAt"] as DateTime, + activationKey: map["activationKey"] as String, + licenseKey: map["licenseKey"] as String, + ); + } + + @override + String toString() { + return '''License { +activatedAt: $activatedAt, +activationKey: $activationKey, +licenseKey: $licenseKey, +}'''; + } + + @override + bool operator ==(covariant License other) { + if (identical(this, other)) return true; + + return activatedAt == other.activatedAt && + activationKey == other.activationKey && + licenseKey == other.licenseKey; + } + + @override + int get hashCode => + activatedAt.hashCode ^ activationKey.hashCode ^ licenseKey.hashCode; +} + +// Model for a user metadata stored in the server +class UserMetadata { + final String userId; + final UserMetadataKey key; + final Onboarding? onboarding; + final Preferences? preferences; + final License? license; + + const UserMetadata({ + required this.userId, + required this.key, + this.onboarding, + this.preferences, + this.license, + }) : assert( + onboarding != null || preferences != null || license != null, + 'One of onboarding, preferences and license must be provided', + ); + + UserMetadata copyWith({ + String? userId, + UserMetadataKey? key, + Onboarding? onboarding, + Preferences? preferences, + License? license, + }) { + return UserMetadata( + userId: userId ?? this.userId, + key: key ?? this.key, + onboarding: onboarding ?? this.onboarding, + preferences: preferences ?? this.preferences, + license: license ?? this.license, + ); + } + + @override + String toString() { + return '''UserMetadata: { +userId: $userId, +key: $key, +onboarding: ${onboarding ?? ""}, +preferences: ${preferences ?? ""}, +license: ${license ?? ""}, +}'''; + } + + @override + bool operator ==(covariant UserMetadata other) { + if (identical(this, other)) return true; + + return other.userId == userId && + other.key == key && + other.onboarding == onboarding && + other.preferences == preferences && + other.license == license; + } + + @override + int get hashCode { + return userId.hashCode ^ + key.hashCode ^ + onboarding.hashCode ^ + preferences.hashCode ^ + license.hashCode; + } } diff --git a/mobile/lib/domain/services/sync_stream.service.dart b/mobile/lib/domain/services/sync_stream.service.dart index 29066195f2..48cf318a8b 100644 --- a/mobile/lib/domain/services/sync_stream.service.dart +++ b/mobile/lib/domain/services/sync_stream.service.dart @@ -179,6 +179,14 @@ class SyncStreamService { data.cast(), debugLabel: 'partner', ); + case SyncEntityType.userMetadataV1: + return _syncStreamRepository.updateUserMetadatasV1( + data.cast(), + ); + case SyncEntityType.userMetadataDeleteV1: + return _syncStreamRepository.deleteUserMetadatasV1( + data.cast(), + ); default: _logger.warning("Unknown sync data type: $type"); } diff --git a/mobile/lib/infrastructure/entities/user_metadata.entity.dart b/mobile/lib/infrastructure/entities/user_metadata.entity.dart index 302a9ffce1..f9a411e3de 100644 --- a/mobile/lib/infrastructure/entities/user_metadata.entity.dart +++ b/mobile/lib/infrastructure/entities/user_metadata.entity.dart @@ -8,14 +8,16 @@ class UserMetadataEntity extends Table with DriftDefaultsMixin { TextColumn get userId => text().references(UserEntity, #id, onDelete: KeyAction.cascade)(); - TextColumn get preferences => text().map(userPreferenceConverter)(); + + IntColumn get key => intEnum()(); + + BlobColumn get value => blob().map(userMetadataConverter)(); @override - Set get primaryKey => {userId}; + Set get primaryKey => {userId, key}; } -final JsonTypeConverter2 - userPreferenceConverter = TypeConverter.json2( - fromJson: (json) => UserPreferences.fromMap(json as Map), - toJson: (pref) => pref.toMap(), +final JsonTypeConverter2, Uint8List, Object?> + userMetadataConverter = TypeConverter.jsonb( + fromJson: (json) => json as Map, ); diff --git a/mobile/lib/infrastructure/entities/user_metadata.entity.drift.dart b/mobile/lib/infrastructure/entities/user_metadata.entity.drift.dart index 95ab63ebf6..a13ea5c04e 100644 --- a/mobile/lib/infrastructure/entities/user_metadata.entity.drift.dart +++ b/mobile/lib/infrastructure/entities/user_metadata.entity.drift.dart @@ -4,21 +4,24 @@ import 'package:drift/drift.dart' as i0; import 'package:immich_mobile/infrastructure/entities/user_metadata.entity.drift.dart' as i1; import 'package:immich_mobile/domain/models/user_metadata.model.dart' as i2; +import 'dart:typed_data' as i3; import 'package:immich_mobile/infrastructure/entities/user_metadata.entity.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/user.entity.drift.dart' + as i5; +import 'package:drift/internal/modular.dart' as i6; typedef $$UserMetadataEntityTableCreateCompanionBuilder = i1.UserMetadataEntityCompanion Function({ required String userId, - required i2.UserPreferences preferences, + required i2.UserMetadataKey key, + required Map value, }); typedef $$UserMetadataEntityTableUpdateCompanionBuilder = i1.UserMetadataEntityCompanion Function({ i0.Value userId, - i0.Value preferences, + i0.Value key, + i0.Value> value, }); final class $$UserMetadataEntityTableReferences extends i0.BaseReferences< @@ -28,26 +31,26 @@ final class $$UserMetadataEntityTableReferences extends i0.BaseReferences< $$UserMetadataEntityTableReferences( super.$_db, super.$_table, super.$_typedResult); - static i4.$UserEntityTable _userIdTable(i0.GeneratedDatabase db) => - i5.ReadDatabaseContainer(db) - .resultSet('user_entity') + static i5.$UserEntityTable _userIdTable(i0.GeneratedDatabase db) => + i6.ReadDatabaseContainer(db) + .resultSet('user_entity') .createAlias(i0.$_aliasNameGenerator( - i5.ReadDatabaseContainer(db) + i6.ReadDatabaseContainer(db) .resultSet( 'user_metadata_entity') .userId, - i5.ReadDatabaseContainer(db) - .resultSet('user_entity') + i6.ReadDatabaseContainer(db) + .resultSet('user_entity') .id)); - i4.$$UserEntityTableProcessedTableManager get userId { + i5.$$UserEntityTableProcessedTableManager get userId { final $_column = $_itemColumn('user_id')!; - final manager = i4 + final manager = i5 .$$UserEntityTableTableManager( $_db, - i5.ReadDatabaseContainer($_db) - .resultSet('user_entity')) + i6.ReadDatabaseContainer($_db) + .resultSet('user_entity')) .filter((f) => f.id.sqlEquals($_column)); final item = $_typedResult.readTableOrNull(_userIdTable($_db)); if (item == null) return manager; @@ -65,26 +68,31 @@ class $$UserMetadataEntityTableFilterComposer super.$addJoinBuilderToRootComposer, super.$removeJoinBuilderFromRootComposer, }); - i0.ColumnWithTypeConverterFilters - get preferences => $composableBuilder( - column: $table.preferences, + i0.ColumnWithTypeConverterFilters + get key => $composableBuilder( + column: $table.key, builder: (column) => i0.ColumnWithTypeConverterFilters(column)); - i4.$$UserEntityTableFilterComposer get userId { - final i4.$$UserEntityTableFilterComposer composer = $composerBuilder( + i0.ColumnWithTypeConverterFilters, Map, + i3.Uint8List> + get value => $composableBuilder( + column: $table.value, + builder: (column) => i0.ColumnWithTypeConverterFilters(column)); + + i5.$$UserEntityTableFilterComposer get userId { + final i5.$$UserEntityTableFilterComposer composer = $composerBuilder( composer: this, getCurrentColumn: (t) => t.userId, - referencedTable: i5.ReadDatabaseContainer($db) - .resultSet('user_entity'), + referencedTable: i6.ReadDatabaseContainer($db) + .resultSet('user_entity'), getReferencedColumn: (t) => t.id, builder: (joinBuilder, {$addJoinBuilderToRootComposer, $removeJoinBuilderFromRootComposer}) => - i4.$$UserEntityTableFilterComposer( + i5.$$UserEntityTableFilterComposer( $db: $db, - $table: i5.ReadDatabaseContainer($db) - .resultSet('user_entity'), + $table: i6.ReadDatabaseContainer($db) + .resultSet('user_entity'), $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, joinBuilder: joinBuilder, $removeJoinBuilderFromRootComposer: @@ -103,24 +111,26 @@ class $$UserMetadataEntityTableOrderingComposer super.$addJoinBuilderToRootComposer, super.$removeJoinBuilderFromRootComposer, }); - i0.ColumnOrderings get preferences => $composableBuilder( - column: $table.preferences, - builder: (column) => i0.ColumnOrderings(column)); + i0.ColumnOrderings get key => $composableBuilder( + column: $table.key, builder: (column) => i0.ColumnOrderings(column)); - i4.$$UserEntityTableOrderingComposer get userId { - final i4.$$UserEntityTableOrderingComposer composer = $composerBuilder( + i0.ColumnOrderings get value => $composableBuilder( + column: $table.value, builder: (column) => i0.ColumnOrderings(column)); + + i5.$$UserEntityTableOrderingComposer get userId { + final i5.$$UserEntityTableOrderingComposer composer = $composerBuilder( composer: this, getCurrentColumn: (t) => t.userId, - referencedTable: i5.ReadDatabaseContainer($db) - .resultSet('user_entity'), + referencedTable: i6.ReadDatabaseContainer($db) + .resultSet('user_entity'), getReferencedColumn: (t) => t.id, builder: (joinBuilder, {$addJoinBuilderToRootComposer, $removeJoinBuilderFromRootComposer}) => - i4.$$UserEntityTableOrderingComposer( + i5.$$UserEntityTableOrderingComposer( $db: $db, - $table: i5.ReadDatabaseContainer($db) - .resultSet('user_entity'), + $table: i6.ReadDatabaseContainer($db) + .resultSet('user_entity'), $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, joinBuilder: joinBuilder, $removeJoinBuilderFromRootComposer: @@ -139,24 +149,27 @@ class $$UserMetadataEntityTableAnnotationComposer super.$addJoinBuilderToRootComposer, super.$removeJoinBuilderFromRootComposer, }); - i0.GeneratedColumnWithTypeConverter - get preferences => $composableBuilder( - column: $table.preferences, builder: (column) => column); + i0.GeneratedColumnWithTypeConverter get key => + $composableBuilder(column: $table.key, builder: (column) => column); - i4.$$UserEntityTableAnnotationComposer get userId { - final i4.$$UserEntityTableAnnotationComposer composer = $composerBuilder( + i0.GeneratedColumnWithTypeConverter, i3.Uint8List> + get value => + $composableBuilder(column: $table.value, builder: (column) => column); + + i5.$$UserEntityTableAnnotationComposer get userId { + final i5.$$UserEntityTableAnnotationComposer composer = $composerBuilder( composer: this, getCurrentColumn: (t) => t.userId, - referencedTable: i5.ReadDatabaseContainer($db) - .resultSet('user_entity'), + referencedTable: i6.ReadDatabaseContainer($db) + .resultSet('user_entity'), getReferencedColumn: (t) => t.id, builder: (joinBuilder, {$addJoinBuilderToRootComposer, $removeJoinBuilderFromRootComposer}) => - i4.$$UserEntityTableAnnotationComposer( + i5.$$UserEntityTableAnnotationComposer( $db: $db, - $table: i5.ReadDatabaseContainer($db) - .resultSet('user_entity'), + $table: i6.ReadDatabaseContainer($db) + .resultSet('user_entity'), $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, joinBuilder: joinBuilder, $removeJoinBuilderFromRootComposer: @@ -193,19 +206,23 @@ class $$UserMetadataEntityTableTableManager extends i0.RootTableManager< $db: db, $table: table), updateCompanionCallback: ({ i0.Value userId = const i0.Value.absent(), - i0.Value preferences = const i0.Value.absent(), + i0.Value key = const i0.Value.absent(), + i0.Value> value = const i0.Value.absent(), }) => i1.UserMetadataEntityCompanion( userId: userId, - preferences: preferences, + key: key, + value: value, ), createCompanionCallback: ({ required String userId, - required i2.UserPreferences preferences, + required i2.UserMetadataKey key, + required Map value, }) => i1.UserMetadataEntityCompanion.insert( userId: userId, - preferences: preferences, + key: key, + value: value, ), withReferenceMapper: (p0) => p0 .map((e) => ( @@ -266,7 +283,7 @@ typedef $$UserMetadataEntityTableProcessedTableManager i1.UserMetadataEntityData, i0.PrefetchHooks Function({bool userId})>; -class $UserMetadataEntityTable extends i3.UserMetadataEntity +class $UserMetadataEntityTable extends i4.UserMetadataEntity with i0.TableInfo<$UserMetadataEntityTable, i1.UserMetadataEntityData> { @override final i0.GeneratedDatabase attachedDatabase; @@ -282,14 +299,20 @@ class $UserMetadataEntityTable extends i3.UserMetadataEntity defaultConstraints: i0.GeneratedColumn.constraintIsAlways( 'REFERENCES user_entity (id) ON DELETE CASCADE')); @override - late final i0.GeneratedColumnWithTypeConverter - preferences = i0.GeneratedColumn( - 'preferences', aliasedName, false, - type: i0.DriftSqlType.string, requiredDuringInsert: true) - .withConverter( - i1.$UserMetadataEntityTable.$converterpreferences); + late final i0.GeneratedColumnWithTypeConverter key = + i0.GeneratedColumn('key', aliasedName, false, + type: i0.DriftSqlType.int, requiredDuringInsert: true) + .withConverter( + i1.$UserMetadataEntityTable.$converterkey); @override - List get $columns => [userId, preferences]; + late final i0 + .GeneratedColumnWithTypeConverter, i3.Uint8List> + value = i0.GeneratedColumn('value', aliasedName, false, + type: i0.DriftSqlType.blob, requiredDuringInsert: true) + .withConverter>( + i1.$UserMetadataEntityTable.$convertervalue); + @override + List get $columns => [userId, key, value]; @override String get aliasedName => _alias ?? actualTableName; @override @@ -311,7 +334,7 @@ class $UserMetadataEntityTable extends i3.UserMetadataEntity } @override - Set get $primaryKey => {userId}; + Set get $primaryKey => {userId, key}; @override i1.UserMetadataEntityData map(Map data, {String? tablePrefix}) { @@ -319,9 +342,12 @@ class $UserMetadataEntityTable extends i3.UserMetadataEntity return i1.UserMetadataEntityData( userId: attachedDatabase.typeMapping .read(i0.DriftSqlType.string, data['${effectivePrefix}user_id'])!, - preferences: i1.$UserMetadataEntityTable.$converterpreferences.fromSql( - attachedDatabase.typeMapping.read( - i0.DriftSqlType.string, data['${effectivePrefix}preferences'])!), + key: i1.$UserMetadataEntityTable.$converterkey.fromSql(attachedDatabase + .typeMapping + .read(i0.DriftSqlType.int, data['${effectivePrefix}key'])!), + value: i1.$UserMetadataEntityTable.$convertervalue.fromSql( + attachedDatabase.typeMapping + .read(i0.DriftSqlType.blob, data['${effectivePrefix}value'])!), ); } @@ -330,8 +356,11 @@ class $UserMetadataEntityTable extends i3.UserMetadataEntity return $UserMetadataEntityTable(attachedDatabase, alias); } - static i0.JsonTypeConverter2 - $converterpreferences = i3.userPreferenceConverter; + static i0.JsonTypeConverter2 $converterkey = + const i0.EnumIndexConverter( + i2.UserMetadataKey.values); + static i0.JsonTypeConverter2, i3.Uint8List, Object?> + $convertervalue = i4.userMetadataConverter; @override bool get withoutRowId => true; @override @@ -341,16 +370,21 @@ class $UserMetadataEntityTable extends i3.UserMetadataEntity class UserMetadataEntityData extends i0.DataClass implements i0.Insertable { final String userId; - final i2.UserPreferences preferences; + final i2.UserMetadataKey key; + final Map value; const UserMetadataEntityData( - {required this.userId, required this.preferences}); + {required this.userId, required this.key, required this.value}); @override Map toColumns(bool nullToAbsent) { final map = {}; map['user_id'] = i0.Variable(userId); { - map['preferences'] = i0.Variable( - i1.$UserMetadataEntityTable.$converterpreferences.toSql(preferences)); + map['key'] = i0.Variable( + i1.$UserMetadataEntityTable.$converterkey.toSql(key)); + } + { + map['value'] = i0.Variable( + i1.$UserMetadataEntityTable.$convertervalue.toSql(value)); } return map; } @@ -360,8 +394,10 @@ class UserMetadataEntityData extends i0.DataClass serializer ??= i0.driftRuntimeOptions.defaultSerializer; return UserMetadataEntityData( userId: serializer.fromJson(json['userId']), - preferences: i1.$UserMetadataEntityTable.$converterpreferences - .fromJson(serializer.fromJson(json['preferences'])), + key: i1.$UserMetadataEntityTable.$converterkey + .fromJson(serializer.fromJson(json['key'])), + value: i1.$UserMetadataEntityTable.$convertervalue + .fromJson(serializer.fromJson(json['value'])), ); } @override @@ -369,24 +405,28 @@ class UserMetadataEntityData extends i0.DataClass serializer ??= i0.driftRuntimeOptions.defaultSerializer; return { 'userId': serializer.toJson(userId), - 'preferences': serializer.toJson(i1 - .$UserMetadataEntityTable.$converterpreferences - .toJson(preferences)), + 'key': serializer + .toJson(i1.$UserMetadataEntityTable.$converterkey.toJson(key)), + 'value': serializer.toJson( + i1.$UserMetadataEntityTable.$convertervalue.toJson(value)), }; } i1.UserMetadataEntityData copyWith( - {String? userId, i2.UserPreferences? preferences}) => + {String? userId, + i2.UserMetadataKey? key, + Map? value}) => i1.UserMetadataEntityData( userId: userId ?? this.userId, - preferences: preferences ?? this.preferences, + key: key ?? this.key, + value: value ?? this.value, ); UserMetadataEntityData copyWithCompanion( i1.UserMetadataEntityCompanion data) { return UserMetadataEntityData( userId: data.userId.present ? data.userId.value : this.userId, - preferences: - data.preferences.present ? data.preferences.value : this.preferences, + key: data.key.present ? data.key.value : this.key, + value: data.value.present ? data.value.value : this.value, ); } @@ -394,49 +434,60 @@ class UserMetadataEntityData extends i0.DataClass String toString() { return (StringBuffer('UserMetadataEntityData(') ..write('userId: $userId, ') - ..write('preferences: $preferences') + ..write('key: $key, ') + ..write('value: $value') ..write(')')) .toString(); } @override - int get hashCode => Object.hash(userId, preferences); + int get hashCode => Object.hash(userId, key, value); @override bool operator ==(Object other) => identical(this, other) || (other is i1.UserMetadataEntityData && other.userId == this.userId && - other.preferences == this.preferences); + other.key == this.key && + other.value == this.value); } class UserMetadataEntityCompanion extends i0.UpdateCompanion { final i0.Value userId; - final i0.Value preferences; + final i0.Value key; + final i0.Value> value; const UserMetadataEntityCompanion({ this.userId = const i0.Value.absent(), - this.preferences = const i0.Value.absent(), + this.key = const i0.Value.absent(), + this.value = const i0.Value.absent(), }); UserMetadataEntityCompanion.insert({ required String userId, - required i2.UserPreferences preferences, + required i2.UserMetadataKey key, + required Map value, }) : userId = i0.Value(userId), - preferences = i0.Value(preferences); + key = i0.Value(key), + value = i0.Value(value); static i0.Insertable custom({ i0.Expression? userId, - i0.Expression? preferences, + i0.Expression? key, + i0.Expression? value, }) { return i0.RawValuesInsertable({ if (userId != null) 'user_id': userId, - if (preferences != null) 'preferences': preferences, + if (key != null) 'key': key, + if (value != null) 'value': value, }); } i1.UserMetadataEntityCompanion copyWith( - {i0.Value? userId, i0.Value? preferences}) { + {i0.Value? userId, + i0.Value? key, + i0.Value>? value}) { return i1.UserMetadataEntityCompanion( userId: userId ?? this.userId, - preferences: preferences ?? this.preferences, + key: key ?? this.key, + value: value ?? this.value, ); } @@ -446,10 +497,13 @@ class UserMetadataEntityCompanion if (userId.present) { map['user_id'] = i0.Variable(userId.value); } - if (preferences.present) { - map['preferences'] = i0.Variable(i1 - .$UserMetadataEntityTable.$converterpreferences - .toSql(preferences.value)); + if (key.present) { + map['key'] = i0.Variable( + i1.$UserMetadataEntityTable.$converterkey.toSql(key.value)); + } + if (value.present) { + map['value'] = i0.Variable( + i1.$UserMetadataEntityTable.$convertervalue.toSql(value.value)); } return map; } @@ -458,7 +512,8 @@ class UserMetadataEntityCompanion String toString() { return (StringBuffer('UserMetadataEntityCompanion(') ..write('userId: $userId, ') - ..write('preferences: $preferences') + ..write('key: $key, ') + ..write('value: $value') ..write(')')) .toString(); } diff --git a/mobile/lib/infrastructure/repositories/sync_api.repository.dart b/mobile/lib/infrastructure/repositories/sync_api.repository.dart index d43f786a29..d1ecbd580c 100644 --- a/mobile/lib/infrastructure/repositories/sync_api.repository.dart +++ b/mobile/lib/infrastructure/repositories/sync_api.repository.dart @@ -56,6 +56,7 @@ class SyncApiRepository { SyncRequestType.memoryToAssetsV1, SyncRequestType.stacksV1, SyncRequestType.partnerStacksV1, + SyncRequestType.userMetadataV1, ], ).toJson(), ); @@ -170,6 +171,8 @@ const _kResponseMap = { SyncEntityType.partnerStackV1: SyncStackV1.fromJson, SyncEntityType.partnerStackBackfillV1: SyncStackV1.fromJson, SyncEntityType.partnerStackDeleteV1: SyncStackDeleteV1.fromJson, + SyncEntityType.userMetadataV1: SyncUserMetadataV1.fromJson, + SyncEntityType.userMetadataDeleteV1: SyncUserMetadataDeleteV1.fromJson, }; class _SyncAckV1 { diff --git a/mobile/lib/infrastructure/repositories/sync_stream.repository.dart b/mobile/lib/infrastructure/repositories/sync_stream.repository.dart index dc3b466f01..f3f26bb01f 100644 --- a/mobile/lib/infrastructure/repositories/sync_stream.repository.dart +++ b/mobile/lib/infrastructure/repositories/sync_stream.repository.dart @@ -4,6 +4,7 @@ import 'package:drift/drift.dart'; import 'package:immich_mobile/domain/models/album/album.model.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; import 'package:immich_mobile/domain/models/memory.model.dart'; +import 'package:immich_mobile/domain/models/user_metadata.model.dart'; import 'package:immich_mobile/infrastructure/entities/exif.entity.drift.dart'; import 'package:immich_mobile/infrastructure/entities/memory.entity.drift.dart'; import 'package:immich_mobile/infrastructure/entities/memory_asset.entity.drift.dart'; @@ -14,6 +15,7 @@ import 'package:immich_mobile/infrastructure/entities/remote_album_user.entity.d import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.drift.dart'; import 'package:immich_mobile/infrastructure/entities/stack.entity.drift.dart'; import 'package:immich_mobile/infrastructure/entities/user.entity.drift.dart'; +import 'package:immich_mobile/infrastructure/entities/user_metadata.entity.drift.dart'; import 'package:immich_mobile/infrastructure/repositories/db.repository.dart'; import 'package:logging/logging.dart'; import 'package:openapi/api.dart' as api show AssetVisibility, AlbumUserRole; @@ -461,6 +463,53 @@ class SyncStreamRepository extends DriftDatabaseRepository { rethrow; } } + + Future updateUserMetadatasV1( + Iterable data, + ) async { + try { + await _db.batch((batch) { + for (final userMetadata in data) { + final companion = UserMetadataEntityCompanion( + value: Value(userMetadata.value as Map), + ); + + batch.insert( + _db.userMetadataEntity, + companion.copyWith( + userId: Value(userMetadata.userId), + key: Value(userMetadata.key.toUserMetadataKey()), + ), + onConflict: DoUpdate((_) => companion), + ); + } + }); + } catch (error, stack) { + _logger.severe('Error: deleteUserMetadatasV1', error, stack); + rethrow; + } + } + + Future deleteUserMetadatasV1( + Iterable data, + ) async { + try { + await _db.batch((batch) { + for (final userMetadata in data) { + batch.delete( + _db.userMetadataEntity, + UserMetadataEntityCompanion( + userId: Value(userMetadata.userId), + key: Value(userMetadata.key.toUserMetadataKey()), + ), + ); + } + }); + } catch (error, stack) { + _logger.severe('Error: deleteUserMetadatasV1', error, stack); + rethrow; + } + } } extension on AssetTypeEnum { @@ -506,6 +555,15 @@ extension on api.AssetVisibility { }; } +extension on String { + UserMetadataKey toUserMetadataKey() => switch (this) { + "onboarding" => UserMetadataKey.onboarding, + "preferences" => UserMetadataKey.preferences, + "license" => UserMetadataKey.license, + _ => throw Exception('Unknown UserMetadataKey value: $this'), + }; +} + extension on String { Duration? toDuration() { try { diff --git a/mobile/lib/infrastructure/repositories/user_metadata.repository.dart b/mobile/lib/infrastructure/repositories/user_metadata.repository.dart new file mode 100644 index 0000000000..19364afb43 --- /dev/null +++ b/mobile/lib/infrastructure/repositories/user_metadata.repository.dart @@ -0,0 +1,38 @@ +import 'package:drift/drift.dart'; +import 'package:immich_mobile/domain/models/user_metadata.model.dart'; +import 'package:immich_mobile/infrastructure/entities/user_metadata.entity.drift.dart'; +import 'package:immich_mobile/infrastructure/repositories/db.repository.dart'; + +class DriftUserMetadataRepository extends DriftDatabaseRepository { + final Drift _db; + const DriftUserMetadataRepository(this._db) : super(_db); + + Future> getUserMetadata(String userId) { + final query = _db.userMetadataEntity.select() + ..where((e) => e.userId.equals(userId)); + + return query.map((userMetadata) { + return userMetadata.toDto(); + }).get(); + } +} + +extension on UserMetadataEntityData { + UserMetadata toDto() => switch (key) { + UserMetadataKey.onboarding => UserMetadata( + userId: userId, + key: key, + onboarding: Onboarding.fromMap(value), + ), + UserMetadataKey.preferences => UserMetadata( + userId: userId, + key: key, + preferences: Preferences.fromMap(value), + ), + UserMetadataKey.license => UserMetadata( + userId: userId, + key: key, + license: License.fromMap(value), + ), + }; +} diff --git a/mobile/lib/providers/infrastructure/user_metadata.provider.dart b/mobile/lib/providers/infrastructure/user_metadata.provider.dart new file mode 100644 index 0000000000..2e2ae7555b --- /dev/null +++ b/mobile/lib/providers/infrastructure/user_metadata.provider.dart @@ -0,0 +1,7 @@ +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:immich_mobile/infrastructure/repositories/user_metadata.repository.dart'; +import 'package:immich_mobile/providers/infrastructure/db.provider.dart'; + +final userMetadataRepository = Provider( + (ref) => DriftUserMetadataRepository(ref.watch(driftProvider)), +); diff --git a/mobile/test/domain/services/sync_stream_service_test.dart b/mobile/test/domain/services/sync_stream_service_test.dart index 27cd8c5b21..c9fd8104e4 100644 --- a/mobile/test/domain/services/sync_stream_service_test.dart +++ b/mobile/test/domain/services/sync_stream_service_test.dart @@ -101,6 +101,10 @@ void main() { debugLabel: any(named: 'debugLabel'), ), ).thenAnswer(successHandler); + when(() => mockSyncStreamRepo.updateUserMetadatasV1(any())) + .thenAnswer(successHandler); + when(() => mockSyncStreamRepo.deleteUserMetadatasV1(any())) + .thenAnswer(successHandler); sut = SyncStreamService( syncApiRepository: mockSyncApiRepo,