From 4b9180c3c78a88f9ac8095f95c83749bc65834f7 Mon Sep 17 00:00:00 2001 From: otsmr Date: Thu, 14 May 2026 14:38:00 +0200 Subject: [PATCH] move signal pre key store into the database --- lib/globals.dart | 2 +- lib/main.dart | 29 +- .../schemas/twonly_db/drift_schema_v15.json | 2995 +++++++++++++++++ .../signal/signal_signed_pre_key_store.dart | 58 +- .../signal_signed_pre_key_store.table.dart | 11 + lib/src/database/twonly.db.dart | 7 +- lib/src/database/twonly.db.g.dart | 466 +++ lib/src/database/twonly.db.steps.dart | 479 +++ lib/src/services/signal/identity.signal.dart | 28 +- .../main_camera_controller.dart | 67 +- .../components/flashback_banner.comp.dart | 12 +- .../visual/views/memories/memories.view.dart | 58 +- test/drift/twonly_db/generated/schema.dart | 21 +- .../drift/twonly_db/generated/schema_v15.dart | 925 ++++- 14 files changed, 5050 insertions(+), 108 deletions(-) create mode 100644 lib/src/database/schemas/twonly_db/drift_schema_v15.json create mode 100644 lib/src/database/tables/signal_signed_pre_key_store.table.dart diff --git a/lib/globals.dart b/lib/globals.dart index 41de888a..f3bd47b7 100644 --- a/lib/globals.dart +++ b/lib/globals.dart @@ -32,6 +32,6 @@ class AppState { static bool isInBackgroundTask = false; static bool allowErrorTrackingViaSentry = false; static bool gotMessageFromServer = false; - static int latestAppVersionId = 114; + static int latestAppVersionId = 115; } diff --git a/lib/main.dart b/lib/main.dart index e2e94029..ed54402e 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -267,9 +267,36 @@ Future runMigrations() async { } await UserService.update((u) => u.appVersion = 114); } + + if (userService.currentUser.appVersion < 115) { + var migrationSuccess = true; + try { + final rustStore = await RustKeyManager.loadSignedPrekeys(); + for (final entry in rustStore.entries) { + final companion = SignalSignedPreKeyStoresCompanion( + signedPreKeyId: Value(entry.key), + signedPreKey: Value(entry.value), + ); + await twonlyDB + .into(twonlyDB.signalSignedPreKeyStores) + .insert( + companion, + mode: InsertMode.insertOrReplace, + ); + await RustKeyManager.removeSignedPrekey(signedPreKeyId: entry.key); + } + } catch (e) { + Log.error('Failed to migrate signed prekeys to Drift: $e'); + migrationSuccess = false; + } + if (migrationSuccess) { + await UserService.update((u) => u.appVersion = 115); + } + } + if (kDebugMode) { assert( - AppState.latestAppVersionId == 114, + AppState.latestAppVersionId == 115, 'Forgot to update the target version in runMigrations() after incrementing AppState.latestAppVersionId.', ); assert( diff --git a/lib/src/database/schemas/twonly_db/drift_schema_v15.json b/lib/src/database/schemas/twonly_db/drift_schema_v15.json new file mode 100644 index 00000000..39d3aab8 --- /dev/null +++ b/lib/src/database/schemas/twonly_db/drift_schema_v15.json @@ -0,0 +1,2995 @@ +{ + "_meta": { + "description": "This file contains a serialized version of schema entities for drift.", + "version": "1.3.0" + }, + "options": { + "store_date_time_values_as_text": false + }, + "entities": [ + { + "id": 0, + "references": [], + "type": "table", + "data": { + "name": "contacts", + "was_declared_in_moor": false, + "columns": [ + { + "name": "user_id", + "getter_name": "userId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "username", + "getter_name": "username", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "display_name", + "getter_name": "displayName", + "moor_type": "string", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "nick_name", + "getter_name": "nickName", + "moor_type": "string", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "avatar_svg_compressed", + "getter_name": "avatarSvgCompressed", + "moor_type": "blob", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "sender_profile_counter", + "getter_name": "senderProfileCounter", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "accepted", + "getter_name": "accepted", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"accepted\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"accepted\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "deleted_by_user", + "getter_name": "deletedByUser", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"deleted_by_user\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"deleted_by_user\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "requested", + "getter_name": "requested", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"requested\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"requested\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "blocked", + "getter_name": "blocked", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"blocked\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"blocked\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "verified", + "getter_name": "verified", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"verified\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"verified\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "account_deleted", + "getter_name": "accountDeleted", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"account_deleted\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"account_deleted\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "created_at", + "getter_name": "createdAt", + "moor_type": "dateTime", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "user_discovery_version", + "getter_name": "userDiscoveryVersion", + "moor_type": "blob", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "user_discovery_excluded", + "getter_name": "userDiscoveryExcluded", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"user_discovery_excluded\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"user_discovery_excluded\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "user_discovery_manual_approved", + "getter_name": "userDiscoveryManualApproved", + "moor_type": "bool", + "nullable": true, + "customConstraints": null, + "defaultConstraints": "CHECK (\"user_discovery_manual_approved\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"user_discovery_manual_approved\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "media_send_counter", + "getter_name": "mediaSendCounter", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "media_received_counter", + "getter_name": "mediaReceivedCounter", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "user_id" + ] + } + }, + { + "id": 1, + "references": [], + "type": "table", + "data": { + "name": "groups", + "was_declared_in_moor": false, + "columns": [ + { + "name": "group_id", + "getter_name": "groupId", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "is_group_admin", + "getter_name": "isGroupAdmin", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"is_group_admin\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"is_group_admin\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "is_direct_chat", + "getter_name": "isDirectChat", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"is_direct_chat\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"is_direct_chat\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "pinned", + "getter_name": "pinned", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"pinned\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"pinned\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "archived", + "getter_name": "archived", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"archived\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"archived\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "joined_group", + "getter_name": "joinedGroup", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"joined_group\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"joined_group\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "left_group", + "getter_name": "leftGroup", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"left_group\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"left_group\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "deleted_content", + "getter_name": "deletedContent", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"deleted_content\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"deleted_content\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "state_version_id", + "getter_name": "stateVersionId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "state_encryption_key", + "getter_name": "stateEncryptionKey", + "moor_type": "blob", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "my_group_private_key", + "getter_name": "myGroupPrivateKey", + "moor_type": "blob", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "group_name", + "getter_name": "groupName", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "draft_message", + "getter_name": "draftMessage", + "moor_type": "string", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "total_media_counter", + "getter_name": "totalMediaCounter", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "also_best_friend", + "getter_name": "alsoBestFriend", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"also_best_friend\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"also_best_friend\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "delete_messages_after_milliseconds", + "getter_name": "deleteMessagesAfterMilliseconds", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('86400000')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "created_at", + "getter_name": "createdAt", + "moor_type": "dateTime", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "last_message_send", + "getter_name": "lastMessageSend", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "last_message_received", + "getter_name": "lastMessageReceived", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "last_flame_counter_change", + "getter_name": "lastFlameCounterChange", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "last_flame_sync", + "getter_name": "lastFlameSync", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "flame_counter", + "getter_name": "flameCounter", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "max_flame_counter", + "getter_name": "maxFlameCounter", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "max_flame_counter_from", + "getter_name": "maxFlameCounterFrom", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "last_message_exchange", + "getter_name": "lastMessageExchange", + "moor_type": "dateTime", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "group_id" + ] + } + }, + { + "id": 2, + "references": [], + "type": "table", + "data": { + "name": "media_files", + "was_declared_in_moor": false, + "columns": [ + { + "name": "media_id", + "getter_name": "mediaId", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "type", + "getter_name": "type", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [], + "type_converter": { + "dart_expr": "const EnumNameConverter(MediaType.values)", + "dart_type_name": "MediaType" + } + }, + { + "name": "upload_state", + "getter_name": "uploadState", + "moor_type": "string", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [], + "type_converter": { + "dart_expr": "const EnumNameConverter(UploadState.values)", + "dart_type_name": "UploadState" + } + }, + { + "name": "download_state", + "getter_name": "downloadState", + "moor_type": "string", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [], + "type_converter": { + "dart_expr": "const EnumNameConverter(DownloadState.values)", + "dart_type_name": "DownloadState" + } + }, + { + "name": "requires_authentication", + "getter_name": "requiresAuthentication", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"requires_authentication\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"requires_authentication\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "stored", + "getter_name": "stored", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"stored\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"stored\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "is_draft_media", + "getter_name": "isDraftMedia", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"is_draft_media\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"is_draft_media\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "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": "has_crop_analyzed", + "getter_name": "hasCropAnalyzed", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"has_crop_analyzed\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"has_crop_analyzed\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "pre_progressing_process", + "getter_name": "preProgressingProcess", + "moor_type": "int", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "reupload_requested_by", + "getter_name": "reuploadRequestedBy", + "moor_type": "string", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [], + "type_converter": { + "dart_expr": "IntListTypeConverter()", + "dart_type_name": "List" + } + }, + { + "name": "display_limit_in_milliseconds", + "getter_name": "displayLimitInMilliseconds", + "moor_type": "int", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "remove_audio", + "getter_name": "removeAudio", + "moor_type": "bool", + "nullable": true, + "customConstraints": null, + "defaultConstraints": "CHECK (\"remove_audio\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"remove_audio\" IN (0, 1))" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "download_token", + "getter_name": "downloadToken", + "moor_type": "blob", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "encryption_key", + "getter_name": "encryptionKey", + "moor_type": "blob", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "encryption_mac", + "getter_name": "encryptionMac", + "moor_type": "blob", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "encryption_nonce", + "getter_name": "encryptionNonce", + "moor_type": "blob", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "stored_file_hash", + "getter_name": "storedFileHash", + "moor_type": "blob", + "nullable": true, + "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('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "created_at_month", + "getter_name": "createdAtMonth", + "moor_type": "string", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "media_id" + ] + } + }, + { + "id": 3, + "references": [ + 1, + 0, + 2 + ], + "type": "table", + "data": { + "name": "messages", + "was_declared_in_moor": false, + "columns": [ + { + "name": "group_id", + "getter_name": "groupId", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "REFERENCES \"groups\" (group_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES \"groups\" (group_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "groups", + "column": "group_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "message_id", + "getter_name": "messageId", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "sender_id", + "getter_name": "senderId", + "moor_type": "int", + "nullable": true, + "customConstraints": null, + "defaultConstraints": "REFERENCES contacts (user_id)", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES contacts (user_id)" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "contacts", + "column": "user_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": null + } + } + ] + }, + { + "name": "type", + "getter_name": "type", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "content", + "getter_name": "content", + "moor_type": "string", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "media_id", + "getter_name": "mediaId", + "moor_type": "string", + "nullable": true, + "customConstraints": null, + "defaultConstraints": "REFERENCES media_files (media_id) ON DELETE SET NULL", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES media_files (media_id) ON DELETE SET NULL" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "media_files", + "column": "media_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "setNull" + } + } + ] + }, + { + "name": "additional_message_data", + "getter_name": "additionalMessageData", + "moor_type": "blob", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "media_stored", + "getter_name": "mediaStored", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"media_stored\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"media_stored\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "media_reopened", + "getter_name": "mediaReopened", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"media_reopened\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"media_reopened\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "download_token", + "getter_name": "downloadToken", + "moor_type": "blob", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "quotes_message_id", + "getter_name": "quotesMessageId", + "moor_type": "string", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "is_deleted_from_sender", + "getter_name": "isDeletedFromSender", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"is_deleted_from_sender\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"is_deleted_from_sender\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "opened_at", + "getter_name": "openedAt", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "opened_by_all", + "getter_name": "openedByAll", + "moor_type": "dateTime", + "nullable": true, + "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('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "modified_at", + "getter_name": "modifiedAt", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "ack_by_user", + "getter_name": "ackByUser", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "ack_by_server", + "getter_name": "ackByServer", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "message_id" + ] + } + }, + { + "id": 4, + "references": [ + 3, + 0 + ], + "type": "table", + "data": { + "name": "message_histories", + "was_declared_in_moor": false, + "columns": [ + { + "name": "id", + "getter_name": "id", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "PRIMARY KEY AUTOINCREMENT", + "dialectAwareDefaultConstraints": { + "sqlite": "PRIMARY KEY AUTOINCREMENT" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + "auto-increment" + ] + }, + { + "name": "message_id", + "getter_name": "messageId", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "REFERENCES messages (message_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES messages (message_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "messages", + "column": "message_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "contact_id", + "getter_name": "contactId", + "moor_type": "int", + "nullable": true, + "customConstraints": null, + "defaultConstraints": "REFERENCES contacts (user_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES contacts (user_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "contacts", + "column": "user_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "content", + "getter_name": "content", + "moor_type": "string", + "nullable": true, + "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('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [] + } + }, + { + "id": 5, + "references": [ + 3, + 0 + ], + "type": "table", + "data": { + "name": "reactions", + "was_declared_in_moor": false, + "columns": [ + { + "name": "message_id", + "getter_name": "messageId", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "REFERENCES messages (message_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES messages (message_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "messages", + "column": "message_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "emoji", + "getter_name": "emoji", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "sender_id", + "getter_name": "senderId", + "moor_type": "int", + "nullable": true, + "customConstraints": null, + "defaultConstraints": "REFERENCES contacts (user_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES contacts (user_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "contacts", + "column": "user_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "created_at", + "getter_name": "createdAt", + "moor_type": "dateTime", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "message_id", + "sender_id", + "emoji" + ] + } + }, + { + "id": 6, + "references": [ + 1, + 0 + ], + "type": "table", + "data": { + "name": "group_members", + "was_declared_in_moor": false, + "columns": [ + { + "name": "group_id", + "getter_name": "groupId", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "REFERENCES \"groups\" (group_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES \"groups\" (group_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "groups", + "column": "group_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "contact_id", + "getter_name": "contactId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "REFERENCES contacts (user_id)", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES contacts (user_id)" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "contacts", + "column": "user_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": null + } + } + ] + }, + { + "name": "member_state", + "getter_name": "memberState", + "moor_type": "string", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [], + "type_converter": { + "dart_expr": "const EnumNameConverter(MemberState.values)", + "dart_type_name": "MemberState" + } + }, + { + "name": "group_public_key", + "getter_name": "groupPublicKey", + "moor_type": "blob", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "last_chat_opened", + "getter_name": "lastChatOpened", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "last_type_indicator", + "getter_name": "lastTypeIndicator", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "last_message", + "getter_name": "lastMessage", + "moor_type": "dateTime", + "nullable": true, + "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('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "group_id", + "contact_id" + ] + } + }, + { + "id": 7, + "references": [ + 0, + 3 + ], + "type": "table", + "data": { + "name": "receipts", + "was_declared_in_moor": false, + "columns": [ + { + "name": "receipt_id", + "getter_name": "receiptId", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "contact_id", + "getter_name": "contactId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "REFERENCES contacts (user_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES contacts (user_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "contacts", + "column": "user_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "message_id", + "getter_name": "messageId", + "moor_type": "string", + "nullable": true, + "customConstraints": null, + "defaultConstraints": "REFERENCES messages (message_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES messages (message_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "messages", + "column": "message_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "message", + "getter_name": "message", + "moor_type": "blob", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "contact_will_sends_receipt", + "getter_name": "contactWillSendsReceipt", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"contact_will_sends_receipt\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"contact_will_sends_receipt\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('1')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "will_be_retried_by_media_upload", + "getter_name": "willBeRetriedByMediaUpload", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"will_be_retried_by_media_upload\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"will_be_retried_by_media_upload\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "mark_for_retry", + "getter_name": "markForRetry", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "mark_for_retry_after_accepted", + "getter_name": "markForRetryAfterAccepted", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "ack_by_server_at", + "getter_name": "ackByServerAt", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "retry_count", + "getter_name": "retryCount", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "last_retry", + "getter_name": "lastRetry", + "moor_type": "dateTime", + "nullable": true, + "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('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "receipt_id" + ] + } + }, + { + "id": 8, + "references": [], + "type": "table", + "data": { + "name": "received_receipts", + "was_declared_in_moor": false, + "columns": [ + { + "name": "receipt_id", + "getter_name": "receiptId", + "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('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "receipt_id" + ] + } + }, + { + "id": 9, + "references": [], + "type": "table", + "data": { + "name": "signal_identity_key_stores", + "was_declared_in_moor": false, + "columns": [ + { + "name": "device_id", + "getter_name": "deviceId", + "moor_type": "int", + "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": "identity_key", + "getter_name": "identityKey", + "moor_type": "blob", + "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('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "device_id", + "name" + ] + } + }, + { + "id": 10, + "references": [], + "type": "table", + "data": { + "name": "signal_pre_key_stores", + "was_declared_in_moor": false, + "columns": [ + { + "name": "pre_key_id", + "getter_name": "preKeyId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "pre_key", + "getter_name": "preKey", + "moor_type": "blob", + "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('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "pre_key_id" + ] + } + }, + { + "id": 11, + "references": [], + "type": "table", + "data": { + "name": "signal_sender_key_stores", + "was_declared_in_moor": false, + "columns": [ + { + "name": "sender_key_name", + "getter_name": "senderKeyName", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "sender_key", + "getter_name": "senderKey", + "moor_type": "blob", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "sender_key_name" + ] + } + }, + { + "id": 12, + "references": [], + "type": "table", + "data": { + "name": "signal_session_stores", + "was_declared_in_moor": false, + "columns": [ + { + "name": "device_id", + "getter_name": "deviceId", + "moor_type": "int", + "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": "session_record", + "getter_name": "sessionRecord", + "moor_type": "blob", + "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('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "device_id", + "name" + ] + } + }, + { + "id": 13, + "references": [], + "type": "table", + "data": { + "name": "signal_signed_pre_key_stores", + "was_declared_in_moor": false, + "columns": [ + { + "name": "signed_pre_key_id", + "getter_name": "signedPreKeyId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "signed_pre_key", + "getter_name": "signedPreKey", + "moor_type": "blob", + "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('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "signed_pre_key_id" + ] + } + }, + { + "id": 14, + "references": [ + 3, + 0 + ], + "type": "table", + "data": { + "name": "message_actions", + "was_declared_in_moor": false, + "columns": [ + { + "name": "message_id", + "getter_name": "messageId", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "REFERENCES messages (message_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES messages (message_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "messages", + "column": "message_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "contact_id", + "getter_name": "contactId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "REFERENCES contacts (user_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES contacts (user_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "contacts", + "column": "user_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "type", + "getter_name": "type", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [], + "type_converter": { + "dart_expr": "const EnumNameConverter(MessageActionType.values)", + "dart_type_name": "MessageActionType" + } + }, + { + "name": "action_at", + "getter_name": "actionAt", + "moor_type": "dateTime", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "message_id", + "contact_id", + "type" + ] + } + }, + { + "id": 15, + "references": [ + 1, + 0 + ], + "type": "table", + "data": { + "name": "group_histories", + "was_declared_in_moor": false, + "columns": [ + { + "name": "group_history_id", + "getter_name": "groupHistoryId", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "group_id", + "getter_name": "groupId", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "REFERENCES \"groups\" (group_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES \"groups\" (group_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "groups", + "column": "group_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "contact_id", + "getter_name": "contactId", + "moor_type": "int", + "nullable": true, + "customConstraints": null, + "defaultConstraints": "REFERENCES contacts (user_id)", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES contacts (user_id)" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "contacts", + "column": "user_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": null + } + } + ] + }, + { + "name": "affected_contact_id", + "getter_name": "affectedContactId", + "moor_type": "int", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "old_group_name", + "getter_name": "oldGroupName", + "moor_type": "string", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "new_group_name", + "getter_name": "newGroupName", + "moor_type": "string", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "new_delete_messages_after_milliseconds", + "getter_name": "newDeleteMessagesAfterMilliseconds", + "moor_type": "int", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "type", + "getter_name": "type", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [], + "type_converter": { + "dart_expr": "const EnumNameConverter(GroupActionType.values)", + "dart_type_name": "GroupActionType" + } + }, + { + "name": "action_at", + "getter_name": "actionAt", + "moor_type": "dateTime", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "group_history_id" + ] + } + }, + { + "id": 16, + "references": [ + 0 + ], + "type": "table", + "data": { + "name": "key_verifications", + "was_declared_in_moor": false, + "columns": [ + { + "name": "verification_id", + "getter_name": "verificationId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "PRIMARY KEY AUTOINCREMENT", + "dialectAwareDefaultConstraints": { + "sqlite": "PRIMARY KEY AUTOINCREMENT" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + "auto-increment" + ] + }, + { + "name": "contact_id", + "getter_name": "contactId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "REFERENCES contacts (user_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES contacts (user_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "contacts", + "column": "user_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "type", + "getter_name": "type", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [], + "type_converter": { + "dart_expr": "const EnumNameConverter(VerificationType.values)", + "dart_type_name": "VerificationType" + } + }, + { + "name": "created_at", + "getter_name": "createdAt", + "moor_type": "dateTime", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [] + } + }, + { + "id": 17, + "references": [], + "type": "table", + "data": { + "name": "verification_tokens", + "was_declared_in_moor": false, + "columns": [ + { + "name": "token_id", + "getter_name": "tokenId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "PRIMARY KEY AUTOINCREMENT", + "dialectAwareDefaultConstraints": { + "sqlite": "PRIMARY KEY AUTOINCREMENT" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + "auto-increment" + ] + }, + { + "name": "token", + "getter_name": "token", + "moor_type": "blob", + "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('CAST(strftime(\\'%s\\', CURRENT_TIMESTAMP) AS INTEGER)')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [] + } + }, + { + "id": 18, + "references": [], + "type": "table", + "data": { + "name": "user_discovery_announced_users", + "was_declared_in_moor": false, + "columns": [ + { + "name": "announced_user_id", + "getter_name": "announcedUserId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "announced_public_key", + "getter_name": "announcedPublicKey", + "moor_type": "blob", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "public_id", + "getter_name": "publicId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "UNIQUE", + "dialectAwareDefaultConstraints": { + "sqlite": "UNIQUE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + "unique" + ] + }, + { + "name": "username", + "getter_name": "username", + "moor_type": "string", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "was_shown_to_the_user", + "getter_name": "wasShownToTheUser", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"was_shown_to_the_user\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"was_shown_to_the_user\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "is_hidden", + "getter_name": "isHidden", + "moor_type": "bool", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "CHECK (\"is_hidden\" IN (0, 1))", + "dialectAwareDefaultConstraints": { + "sqlite": "CHECK (\"is_hidden\" IN (0, 1))" + }, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "announced_user_id" + ] + } + }, + { + "id": 19, + "references": [ + 18, + 0 + ], + "type": "table", + "data": { + "name": "user_discovery_user_relations", + "was_declared_in_moor": false, + "columns": [ + { + "name": "announced_user_id", + "getter_name": "announcedUserId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "REFERENCES user_discovery_announced_users (announced_user_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES user_discovery_announced_users (announced_user_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "user_discovery_announced_users", + "column": "announced_user_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "from_contact_id", + "getter_name": "fromContactId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "REFERENCES contacts (user_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES contacts (user_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "contacts", + "column": "user_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "public_key_verified_timestamp", + "getter_name": "publicKeyVerifiedTimestamp", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "announced_user_id", + "from_contact_id" + ] + } + }, + { + "id": 20, + "references": [ + 0 + ], + "type": "table", + "data": { + "name": "user_discovery_other_promotions", + "was_declared_in_moor": false, + "columns": [ + { + "name": "from_contact_id", + "getter_name": "fromContactId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "REFERENCES contacts (user_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES contacts (user_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "contacts", + "column": "user_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "promotion_id", + "getter_name": "promotionId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "public_id", + "getter_name": "publicId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "threshold", + "getter_name": "threshold", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "announcement_share", + "getter_name": "announcementShare", + "moor_type": "blob", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "public_key_verified_timestamp", + "getter_name": "publicKeyVerifiedTimestamp", + "moor_type": "dateTime", + "nullable": true, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "from_contact_id", + "public_id" + ] + } + }, + { + "id": 21, + "references": [ + 0 + ], + "type": "table", + "data": { + "name": "user_discovery_own_promotions", + "was_declared_in_moor": false, + "columns": [ + { + "name": "version_id", + "getter_name": "versionId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "PRIMARY KEY AUTOINCREMENT", + "dialectAwareDefaultConstraints": { + "sqlite": "PRIMARY KEY AUTOINCREMENT" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + "auto-increment" + ] + }, + { + "name": "contact_id", + "getter_name": "contactId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "REFERENCES contacts (user_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES contacts (user_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "contacts", + "column": "user_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "promotion", + "getter_name": "promotion", + "moor_type": "blob", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [] + } + }, + { + "id": 22, + "references": [ + 0 + ], + "type": "table", + "data": { + "name": "user_discovery_shares", + "was_declared_in_moor": false, + "columns": [ + { + "name": "share_id", + "getter_name": "shareId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "PRIMARY KEY AUTOINCREMENT", + "dialectAwareDefaultConstraints": { + "sqlite": "PRIMARY KEY AUTOINCREMENT" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + "auto-increment" + ] + }, + { + "name": "share", + "getter_name": "share", + "moor_type": "blob", + "nullable": false, + "customConstraints": null, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [] + }, + { + "name": "contact_id", + "getter_name": "contactId", + "moor_type": "int", + "nullable": true, + "customConstraints": null, + "defaultConstraints": "REFERENCES contacts (user_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES contacts (user_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "contacts", + "column": "user_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [] + } + }, + { + "id": 23, + "references": [], + "type": "table", + "data": { + "name": "shortcuts", + "was_declared_in_moor": false, + "columns": [ + { + "name": "id", + "getter_name": "id", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "PRIMARY KEY AUTOINCREMENT", + "dialectAwareDefaultConstraints": { + "sqlite": "PRIMARY KEY AUTOINCREMENT" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + "auto-increment" + ] + }, + { + "name": "emoji", + "getter_name": "emoji", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "UNIQUE", + "dialectAwareDefaultConstraints": { + "sqlite": "UNIQUE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + "unique" + ] + }, + { + "name": "usage_counter", + "getter_name": "usageCounter", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "default_dart": "const CustomExpression('0')", + "default_client_dart": null, + "dsl_features": [] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [] + } + }, + { + "id": 24, + "references": [ + 23, + 1 + ], + "type": "table", + "data": { + "name": "shortcut_members", + "was_declared_in_moor": false, + "columns": [ + { + "name": "shortcut_id", + "getter_name": "shortcutId", + "moor_type": "int", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "REFERENCES shortcuts (id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES shortcuts (id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "shortcuts", + "column": "id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + }, + { + "name": "group_id", + "getter_name": "groupId", + "moor_type": "string", + "nullable": false, + "customConstraints": null, + "defaultConstraints": "REFERENCES \"groups\" (group_id) ON DELETE CASCADE", + "dialectAwareDefaultConstraints": { + "sqlite": "REFERENCES \"groups\" (group_id) ON DELETE CASCADE" + }, + "default_dart": null, + "default_client_dart": null, + "dsl_features": [ + { + "foreign_key": { + "to": { + "table": "groups", + "column": "group_id" + }, + "initially_deferred": false, + "on_update": null, + "on_delete": "cascade" + } + } + ] + } + ], + "is_virtual": false, + "without_rowid": false, + "constraints": [], + "explicit_pk": [ + "shortcut_id", + "group_id" + ] + } + } + ], + "fixed_sql": [ + { + "name": "contacts", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"contacts\" (\"user_id\" INTEGER NOT NULL, \"username\" TEXT NOT NULL, \"display_name\" TEXT NULL, \"nick_name\" TEXT NULL, \"avatar_svg_compressed\" BLOB NULL, \"sender_profile_counter\" INTEGER NOT NULL DEFAULT 0, \"accepted\" INTEGER NOT NULL DEFAULT 0 CHECK (\"accepted\" IN (0, 1)), \"deleted_by_user\" INTEGER NOT NULL DEFAULT 0 CHECK (\"deleted_by_user\" IN (0, 1)), \"requested\" INTEGER NOT NULL DEFAULT 0 CHECK (\"requested\" IN (0, 1)), \"blocked\" INTEGER NOT NULL DEFAULT 0 CHECK (\"blocked\" IN (0, 1)), \"verified\" INTEGER NOT NULL DEFAULT 0 CHECK (\"verified\" IN (0, 1)), \"account_deleted\" INTEGER NOT NULL DEFAULT 0 CHECK (\"account_deleted\" IN (0, 1)), \"created_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)), \"user_discovery_version\" BLOB NULL, \"user_discovery_excluded\" INTEGER NOT NULL DEFAULT 0 CHECK (\"user_discovery_excluded\" IN (0, 1)), \"user_discovery_manual_approved\" INTEGER NULL DEFAULT 0 CHECK (\"user_discovery_manual_approved\" IN (0, 1)), \"media_send_counter\" INTEGER NOT NULL DEFAULT 0, \"media_received_counter\" INTEGER NOT NULL DEFAULT 0, PRIMARY KEY (\"user_id\"));" + } + ] + }, + { + "name": "groups", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"groups\" (\"group_id\" TEXT NOT NULL, \"is_group_admin\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_group_admin\" IN (0, 1)), \"is_direct_chat\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_direct_chat\" IN (0, 1)), \"pinned\" INTEGER NOT NULL DEFAULT 0 CHECK (\"pinned\" IN (0, 1)), \"archived\" INTEGER NOT NULL DEFAULT 0 CHECK (\"archived\" IN (0, 1)), \"joined_group\" INTEGER NOT NULL DEFAULT 0 CHECK (\"joined_group\" IN (0, 1)), \"left_group\" INTEGER NOT NULL DEFAULT 0 CHECK (\"left_group\" IN (0, 1)), \"deleted_content\" INTEGER NOT NULL DEFAULT 0 CHECK (\"deleted_content\" IN (0, 1)), \"state_version_id\" INTEGER NOT NULL DEFAULT 0, \"state_encryption_key\" BLOB NULL, \"my_group_private_key\" BLOB NULL, \"group_name\" TEXT NOT NULL, \"draft_message\" TEXT NULL, \"total_media_counter\" INTEGER NOT NULL DEFAULT 0, \"also_best_friend\" INTEGER NOT NULL DEFAULT 0 CHECK (\"also_best_friend\" IN (0, 1)), \"delete_messages_after_milliseconds\" INTEGER NOT NULL DEFAULT 86400000, \"created_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)), \"last_message_send\" INTEGER NULL, \"last_message_received\" INTEGER NULL, \"last_flame_counter_change\" INTEGER NULL, \"last_flame_sync\" INTEGER NULL, \"flame_counter\" INTEGER NOT NULL DEFAULT 0, \"max_flame_counter\" INTEGER NOT NULL DEFAULT 0, \"max_flame_counter_from\" INTEGER NULL, \"last_message_exchange\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)), PRIMARY KEY (\"group_id\"));" + } + ] + }, + { + "name": "media_files", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"media_files\" (\"media_id\" TEXT NOT NULL, \"type\" TEXT NOT NULL, \"upload_state\" TEXT NULL, \"download_state\" TEXT NULL, \"requires_authentication\" INTEGER NOT NULL DEFAULT 0 CHECK (\"requires_authentication\" IN (0, 1)), \"stored\" INTEGER NOT NULL DEFAULT 0 CHECK (\"stored\" IN (0, 1)), \"is_draft_media\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_draft_media\" IN (0, 1)), \"is_favorite\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_favorite\" IN (0, 1)), \"has_crop_analyzed\" INTEGER NOT NULL DEFAULT 0 CHECK (\"has_crop_analyzed\" IN (0, 1)), \"pre_progressing_process\" INTEGER NULL, \"reupload_requested_by\" TEXT NULL, \"display_limit_in_milliseconds\" INTEGER NULL, \"remove_audio\" INTEGER NULL CHECK (\"remove_audio\" IN (0, 1)), \"download_token\" BLOB NULL, \"encryption_key\" BLOB NULL, \"encryption_mac\" BLOB NULL, \"encryption_nonce\" BLOB NULL, \"stored_file_hash\" BLOB NULL, \"created_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)), \"created_at_month\" TEXT NULL, PRIMARY KEY (\"media_id\"));" + } + ] + }, + { + "name": "messages", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"messages\" (\"group_id\" TEXT NOT NULL REFERENCES \"groups\" (group_id) ON DELETE CASCADE, \"message_id\" TEXT NOT NULL, \"sender_id\" INTEGER NULL REFERENCES contacts (user_id), \"type\" TEXT NOT NULL, \"content\" TEXT NULL, \"media_id\" TEXT NULL REFERENCES media_files (media_id) ON DELETE SET NULL, \"additional_message_data\" BLOB NULL, \"media_stored\" INTEGER NOT NULL DEFAULT 0 CHECK (\"media_stored\" IN (0, 1)), \"media_reopened\" INTEGER NOT NULL DEFAULT 0 CHECK (\"media_reopened\" IN (0, 1)), \"download_token\" BLOB NULL, \"quotes_message_id\" TEXT NULL, \"is_deleted_from_sender\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_deleted_from_sender\" IN (0, 1)), \"opened_at\" INTEGER NULL, \"opened_by_all\" INTEGER NULL, \"created_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)), \"modified_at\" INTEGER NULL, \"ack_by_user\" INTEGER NULL, \"ack_by_server\" INTEGER NULL, PRIMARY KEY (\"message_id\"));" + } + ] + }, + { + "name": "message_histories", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"message_histories\" (\"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, \"message_id\" TEXT NOT NULL REFERENCES messages (message_id) ON DELETE CASCADE, \"contact_id\" INTEGER NULL REFERENCES contacts (user_id) ON DELETE CASCADE, \"content\" TEXT NULL, \"created_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)));" + } + ] + }, + { + "name": "reactions", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"reactions\" (\"message_id\" TEXT NOT NULL REFERENCES messages (message_id) ON DELETE CASCADE, \"emoji\" TEXT NOT NULL, \"sender_id\" INTEGER NULL REFERENCES contacts (user_id) ON DELETE CASCADE, \"created_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)), PRIMARY KEY (\"message_id\", \"sender_id\", \"emoji\"));" + } + ] + }, + { + "name": "group_members", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"group_members\" (\"group_id\" TEXT NOT NULL REFERENCES \"groups\" (group_id) ON DELETE CASCADE, \"contact_id\" INTEGER NOT NULL REFERENCES contacts (user_id), \"member_state\" TEXT NULL, \"group_public_key\" BLOB NULL, \"last_chat_opened\" INTEGER NULL, \"last_type_indicator\" INTEGER NULL, \"last_message\" INTEGER NULL, \"created_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)), PRIMARY KEY (\"group_id\", \"contact_id\"));" + } + ] + }, + { + "name": "receipts", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"receipts\" (\"receipt_id\" TEXT NOT NULL, \"contact_id\" INTEGER NOT NULL REFERENCES contacts (user_id) ON DELETE CASCADE, \"message_id\" TEXT NULL REFERENCES messages (message_id) ON DELETE CASCADE, \"message\" BLOB NOT NULL, \"contact_will_sends_receipt\" INTEGER NOT NULL DEFAULT 1 CHECK (\"contact_will_sends_receipt\" IN (0, 1)), \"will_be_retried_by_media_upload\" INTEGER NOT NULL DEFAULT 0 CHECK (\"will_be_retried_by_media_upload\" IN (0, 1)), \"mark_for_retry\" INTEGER NULL, \"mark_for_retry_after_accepted\" INTEGER NULL, \"ack_by_server_at\" INTEGER NULL, \"retry_count\" INTEGER NOT NULL DEFAULT 0, \"last_retry\" INTEGER NULL, \"created_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)), PRIMARY KEY (\"receipt_id\"));" + } + ] + }, + { + "name": "received_receipts", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"received_receipts\" (\"receipt_id\" TEXT NOT NULL, \"created_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)), PRIMARY KEY (\"receipt_id\"));" + } + ] + }, + { + "name": "signal_identity_key_stores", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"signal_identity_key_stores\" (\"device_id\" INTEGER NOT NULL, \"name\" TEXT NOT NULL, \"identity_key\" BLOB NOT NULL, \"created_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)), PRIMARY KEY (\"device_id\", \"name\"));" + } + ] + }, + { + "name": "signal_pre_key_stores", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"signal_pre_key_stores\" (\"pre_key_id\" INTEGER NOT NULL, \"pre_key\" BLOB NOT NULL, \"created_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)), PRIMARY KEY (\"pre_key_id\"));" + } + ] + }, + { + "name": "signal_sender_key_stores", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"signal_sender_key_stores\" (\"sender_key_name\" TEXT NOT NULL, \"sender_key\" BLOB NOT NULL, PRIMARY KEY (\"sender_key_name\"));" + } + ] + }, + { + "name": "signal_session_stores", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"signal_session_stores\" (\"device_id\" INTEGER NOT NULL, \"name\" TEXT NOT NULL, \"session_record\" BLOB NOT NULL, \"created_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)), PRIMARY KEY (\"device_id\", \"name\"));" + } + ] + }, + { + "name": "signal_signed_pre_key_stores", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"signal_signed_pre_key_stores\" (\"signed_pre_key_id\" INTEGER NOT NULL, \"signed_pre_key\" BLOB NOT NULL, \"created_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)), PRIMARY KEY (\"signed_pre_key_id\"));" + } + ] + }, + { + "name": "message_actions", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"message_actions\" (\"message_id\" TEXT NOT NULL REFERENCES messages (message_id) ON DELETE CASCADE, \"contact_id\" INTEGER NOT NULL REFERENCES contacts (user_id) ON DELETE CASCADE, \"type\" TEXT NOT NULL, \"action_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)), PRIMARY KEY (\"message_id\", \"contact_id\", \"type\"));" + } + ] + }, + { + "name": "group_histories", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"group_histories\" (\"group_history_id\" TEXT NOT NULL, \"group_id\" TEXT NOT NULL REFERENCES \"groups\" (group_id) ON DELETE CASCADE, \"contact_id\" INTEGER NULL REFERENCES contacts (user_id), \"affected_contact_id\" INTEGER NULL, \"old_group_name\" TEXT NULL, \"new_group_name\" TEXT NULL, \"new_delete_messages_after_milliseconds\" INTEGER NULL, \"type\" TEXT NOT NULL, \"action_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)), PRIMARY KEY (\"group_history_id\"));" + } + ] + }, + { + "name": "key_verifications", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"key_verifications\" (\"verification_id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, \"contact_id\" INTEGER NOT NULL REFERENCES contacts (user_id) ON DELETE CASCADE, \"type\" TEXT NOT NULL, \"created_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)));" + } + ] + }, + { + "name": "verification_tokens", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"verification_tokens\" (\"token_id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, \"token\" BLOB NOT NULL, \"created_at\" INTEGER NOT NULL DEFAULT (CAST(strftime('%s', CURRENT_TIMESTAMP) AS INTEGER)));" + } + ] + }, + { + "name": "user_discovery_announced_users", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"user_discovery_announced_users\" (\"announced_user_id\" INTEGER NOT NULL, \"announced_public_key\" BLOB NOT NULL, \"public_id\" INTEGER NOT NULL UNIQUE, \"username\" TEXT NULL, \"was_shown_to_the_user\" INTEGER NOT NULL DEFAULT 0 CHECK (\"was_shown_to_the_user\" IN (0, 1)), \"is_hidden\" INTEGER NOT NULL DEFAULT 0 CHECK (\"is_hidden\" IN (0, 1)), PRIMARY KEY (\"announced_user_id\"));" + } + ] + }, + { + "name": "user_discovery_user_relations", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"user_discovery_user_relations\" (\"announced_user_id\" INTEGER NOT NULL REFERENCES user_discovery_announced_users (announced_user_id) ON DELETE CASCADE, \"from_contact_id\" INTEGER NOT NULL REFERENCES contacts (user_id) ON DELETE CASCADE, \"public_key_verified_timestamp\" INTEGER NULL, PRIMARY KEY (\"announced_user_id\", \"from_contact_id\"));" + } + ] + }, + { + "name": "user_discovery_other_promotions", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"user_discovery_other_promotions\" (\"from_contact_id\" INTEGER NOT NULL REFERENCES contacts (user_id) ON DELETE CASCADE, \"promotion_id\" INTEGER NOT NULL, \"public_id\" INTEGER NOT NULL, \"threshold\" INTEGER NOT NULL, \"announcement_share\" BLOB NOT NULL, \"public_key_verified_timestamp\" INTEGER NULL, PRIMARY KEY (\"from_contact_id\", \"public_id\"));" + } + ] + }, + { + "name": "user_discovery_own_promotions", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"user_discovery_own_promotions\" (\"version_id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, \"contact_id\" INTEGER NOT NULL REFERENCES contacts (user_id) ON DELETE CASCADE, \"promotion\" BLOB NOT NULL);" + } + ] + }, + { + "name": "user_discovery_shares", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"user_discovery_shares\" (\"share_id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, \"share\" BLOB NOT NULL, \"contact_id\" INTEGER NULL REFERENCES contacts (user_id) ON DELETE CASCADE);" + } + ] + }, + { + "name": "shortcuts", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"shortcuts\" (\"id\" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, \"emoji\" TEXT NOT NULL UNIQUE, \"usage_counter\" INTEGER NOT NULL DEFAULT 0);" + } + ] + }, + { + "name": "shortcut_members", + "sql": [ + { + "dialect": "sqlite", + "sql": "CREATE TABLE IF NOT EXISTS \"shortcut_members\" (\"shortcut_id\" INTEGER NOT NULL REFERENCES shortcuts (id) ON DELETE CASCADE, \"group_id\" TEXT NOT NULL REFERENCES \"groups\" (group_id) ON DELETE CASCADE, PRIMARY KEY (\"shortcut_id\", \"group_id\"));" + } + ] + } + ] +} \ No newline at end of file diff --git a/lib/src/database/signal/signal_signed_pre_key_store.dart b/lib/src/database/signal/signal_signed_pre_key_store.dart index dbdcf970..adf927c7 100644 --- a/lib/src/database/signal/signal_signed_pre_key_store.dart +++ b/lib/src/database/signal/signal_signed_pre_key_store.dart @@ -1,10 +1,11 @@ import 'dart:collection'; import 'dart:convert'; -import 'dart:typed_data'; - +import 'package:drift/drift.dart'; import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart'; -import 'package:twonly/core/bridge/wrapper/key_manager.dart'; +import 'package:twonly/locator.dart'; import 'package:twonly/src/constants/secure_storage.keys.dart'; +import 'package:twonly/src/database/twonly.db.dart'; +import 'package:twonly/src/utils/log.dart'; import 'package:twonly/src/utils/secure_storage.dart'; Future> getSignalSignedPreKeyStoreOld() async { @@ -26,25 +27,25 @@ Future> getSignalSignedPreKeyStoreOld() async { class SignalSignedPreKeyStore extends SignedPreKeyStore { @override Future loadSignedPreKey(int signedPreKeyId) async { - final store = await RustKeyManager.loadSignedPrekey( - signedPreKeyId: signedPreKeyId, - ); - if (store == null) { + final record = await (twonlyDB.select( + twonlyDB.signalSignedPreKeyStores, + )..where((tbl) => tbl.signedPreKeyId.equals(signedPreKeyId))).get(); + if (record.isEmpty) { throw InvalidKeyIdException( 'No such signed prekey record! $signedPreKeyId', ); } - return SignedPreKeyRecord.fromSerialized(store); + return SignedPreKeyRecord.fromSerialized(record.first.signedPreKey); } @override Future> loadSignedPreKeys() async { - final store = await RustKeyManager.loadSignedPrekeys(); - final results = []; - for (final serialized in store.values) { - results.add(SignedPreKeyRecord.fromSerialized(serialized)); - } - return results; + final records = await twonlyDB + .select(twonlyDB.signalSignedPreKeyStores) + .get(); + return records + .map((r) => SignedPreKeyRecord.fromSerialized(r.signedPreKey)) + .toList(); } @override @@ -52,21 +53,32 @@ class SignalSignedPreKeyStore extends SignedPreKeyStore { int signedPreKeyId, SignedPreKeyRecord record, ) async { - await RustKeyManager.storeSignedPrekey( - signedPreKeyId: signedPreKeyId, - record: record.serialize(), + final companion = SignalSignedPreKeyStoresCompanion( + signedPreKeyId: Value(signedPreKeyId), + signedPreKey: Value(record.serialize()), ); + + try { + await twonlyDB + .into(twonlyDB.signalSignedPreKeyStores) + .insert(companion, mode: InsertMode.insertOrReplace); + } catch (e) { + Log.error('$e'); + } } @override - Future containsSignedPreKey(int signedPreKeyId) async => - await RustKeyManager.loadSignedPrekey( - signedPreKeyId: signedPreKeyId, - ) != - null; + Future containsSignedPreKey(int signedPreKeyId) async { + final record = await (twonlyDB.select( + twonlyDB.signalSignedPreKeyStores, + )..where((tbl) => tbl.signedPreKeyId.equals(signedPreKeyId))).get(); + return record.isNotEmpty; + } @override Future removeSignedPreKey(int signedPreKeyId) async { - await RustKeyManager.removeSignedPrekey(signedPreKeyId: signedPreKeyId); + await (twonlyDB.delete( + twonlyDB.signalSignedPreKeyStores, + )..where((tbl) => tbl.signedPreKeyId.equals(signedPreKeyId))).go(); } } diff --git a/lib/src/database/tables/signal_signed_pre_key_store.table.dart b/lib/src/database/tables/signal_signed_pre_key_store.table.dart new file mode 100644 index 00000000..82991717 --- /dev/null +++ b/lib/src/database/tables/signal_signed_pre_key_store.table.dart @@ -0,0 +1,11 @@ +import 'package:drift/drift.dart'; + +@DataClassName('SignalSignedPreKeyStore') +class SignalSignedPreKeyStores extends Table { + IntColumn get signedPreKeyId => integer()(); + BlobColumn get signedPreKey => blob()(); + DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)(); + + @override + Set get primaryKey => {signedPreKeyId}; +} diff --git a/lib/src/database/twonly.db.dart b/lib/src/database/twonly.db.dart index c39ef370..1579f2cf 100644 --- a/lib/src/database/twonly.db.dart +++ b/lib/src/database/twonly.db.dart @@ -23,6 +23,7 @@ import 'package:twonly/src/database/tables/signal_identity_key_store.table.dart' import 'package:twonly/src/database/tables/signal_pre_key_store.table.dart'; import 'package:twonly/src/database/tables/signal_sender_key_store.table.dart'; import 'package:twonly/src/database/tables/signal_session_store.table.dart'; +import 'package:twonly/src/database/tables/signal_signed_pre_key_store.table.dart'; import 'package:twonly/src/database/tables/user_discovery.table.dart'; import 'package:twonly/src/database/twonly.db.steps.dart'; import 'package:twonly/src/utils/log.dart'; @@ -45,6 +46,7 @@ part 'twonly.db.g.dart'; SignalPreKeyStores, SignalSenderKeyStores, SignalSessionStores, + SignalSignedPreKeyStores, MessageActions, GroupHistories, KeyVerifications, @@ -79,7 +81,7 @@ class TwonlyDB extends _$TwonlyDB { TwonlyDB.forTesting(DatabaseConnection super.connection); @override - int get schemaVersion => 14; + int get schemaVersion => 15; static QueryExecutor _openConnection() { return driftDatabase( @@ -206,6 +208,9 @@ class TwonlyDB extends _$TwonlyDB { schema.mediaFiles.hasCropAnalyzed, ); }, + from14To15: (m, schema) async { + await m.createTable(schema.signalSignedPreKeyStores); + }, )(m, from, to); }, ); diff --git a/lib/src/database/twonly.db.g.dart b/lib/src/database/twonly.db.g.dart index 4ef1df3b..e53efebe 100644 --- a/lib/src/database/twonly.db.g.dart +++ b/lib/src/database/twonly.db.g.dart @@ -8316,6 +8316,285 @@ class SignalSessionStoresCompanion extends UpdateCompanion { } } +class $SignalSignedPreKeyStoresTable extends SignalSignedPreKeyStores + with TableInfo<$SignalSignedPreKeyStoresTable, SignalSignedPreKeyStore> { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + $SignalSignedPreKeyStoresTable(this.attachedDatabase, [this._alias]); + static const VerificationMeta _signedPreKeyIdMeta = const VerificationMeta( + 'signedPreKeyId', + ); + @override + late final GeneratedColumn signedPreKeyId = GeneratedColumn( + 'signed_pre_key_id', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + ); + static const VerificationMeta _signedPreKeyMeta = const VerificationMeta( + 'signedPreKey', + ); + @override + late final GeneratedColumn signedPreKey = + GeneratedColumn( + 'signed_pre_key', + aliasedName, + false, + type: DriftSqlType.blob, + requiredDuringInsert: true, + ); + static const VerificationMeta _createdAtMeta = const VerificationMeta( + 'createdAt', + ); + @override + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: currentDateAndTime, + ); + @override + List get $columns => [ + signedPreKeyId, + signedPreKey, + createdAt, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'signal_signed_pre_key_stores'; + @override + VerificationContext validateIntegrity( + Insertable instance, { + bool isInserting = false, + }) { + final context = VerificationContext(); + final data = instance.toColumns(true); + if (data.containsKey('signed_pre_key_id')) { + context.handle( + _signedPreKeyIdMeta, + signedPreKeyId.isAcceptableOrUnknown( + data['signed_pre_key_id']!, + _signedPreKeyIdMeta, + ), + ); + } + if (data.containsKey('signed_pre_key')) { + context.handle( + _signedPreKeyMeta, + signedPreKey.isAcceptableOrUnknown( + data['signed_pre_key']!, + _signedPreKeyMeta, + ), + ); + } else if (isInserting) { + context.missing(_signedPreKeyMeta); + } + if (data.containsKey('created_at')) { + context.handle( + _createdAtMeta, + createdAt.isAcceptableOrUnknown(data['created_at']!, _createdAtMeta), + ); + } + return context; + } + + @override + Set get $primaryKey => {signedPreKeyId}; + @override + SignalSignedPreKeyStore map( + Map data, { + String? tablePrefix, + }) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return SignalSignedPreKeyStore( + signedPreKeyId: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}signed_pre_key_id'], + )!, + signedPreKey: attachedDatabase.typeMapping.read( + DriftSqlType.blob, + data['${effectivePrefix}signed_pre_key'], + )!, + createdAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}created_at'], + )!, + ); + } + + @override + $SignalSignedPreKeyStoresTable createAlias(String alias) { + return $SignalSignedPreKeyStoresTable(attachedDatabase, alias); + } +} + +class SignalSignedPreKeyStore extends DataClass + implements Insertable { + final int signedPreKeyId; + final Uint8List signedPreKey; + final DateTime createdAt; + const SignalSignedPreKeyStore({ + required this.signedPreKeyId, + required this.signedPreKey, + required this.createdAt, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['signed_pre_key_id'] = Variable(signedPreKeyId); + map['signed_pre_key'] = Variable(signedPreKey); + map['created_at'] = Variable(createdAt); + return map; + } + + SignalSignedPreKeyStoresCompanion toCompanion(bool nullToAbsent) { + return SignalSignedPreKeyStoresCompanion( + signedPreKeyId: Value(signedPreKeyId), + signedPreKey: Value(signedPreKey), + createdAt: Value(createdAt), + ); + } + + factory SignalSignedPreKeyStore.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return SignalSignedPreKeyStore( + signedPreKeyId: serializer.fromJson(json['signedPreKeyId']), + signedPreKey: serializer.fromJson(json['signedPreKey']), + createdAt: serializer.fromJson(json['createdAt']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'signedPreKeyId': serializer.toJson(signedPreKeyId), + 'signedPreKey': serializer.toJson(signedPreKey), + 'createdAt': serializer.toJson(createdAt), + }; + } + + SignalSignedPreKeyStore copyWith({ + int? signedPreKeyId, + Uint8List? signedPreKey, + DateTime? createdAt, + }) => SignalSignedPreKeyStore( + signedPreKeyId: signedPreKeyId ?? this.signedPreKeyId, + signedPreKey: signedPreKey ?? this.signedPreKey, + createdAt: createdAt ?? this.createdAt, + ); + SignalSignedPreKeyStore copyWithCompanion( + SignalSignedPreKeyStoresCompanion data, + ) { + return SignalSignedPreKeyStore( + signedPreKeyId: data.signedPreKeyId.present + ? data.signedPreKeyId.value + : this.signedPreKeyId, + signedPreKey: data.signedPreKey.present + ? data.signedPreKey.value + : this.signedPreKey, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + ); + } + + @override + String toString() { + return (StringBuffer('SignalSignedPreKeyStore(') + ..write('signedPreKeyId: $signedPreKeyId, ') + ..write('signedPreKey: $signedPreKey, ') + ..write('createdAt: $createdAt') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + signedPreKeyId, + $driftBlobEquality.hash(signedPreKey), + createdAt, + ); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is SignalSignedPreKeyStore && + other.signedPreKeyId == this.signedPreKeyId && + $driftBlobEquality.equals(other.signedPreKey, this.signedPreKey) && + other.createdAt == this.createdAt); +} + +class SignalSignedPreKeyStoresCompanion + extends UpdateCompanion { + final Value signedPreKeyId; + final Value signedPreKey; + final Value createdAt; + const SignalSignedPreKeyStoresCompanion({ + this.signedPreKeyId = const Value.absent(), + this.signedPreKey = const Value.absent(), + this.createdAt = const Value.absent(), + }); + SignalSignedPreKeyStoresCompanion.insert({ + this.signedPreKeyId = const Value.absent(), + required Uint8List signedPreKey, + this.createdAt = const Value.absent(), + }) : signedPreKey = Value(signedPreKey); + static Insertable custom({ + Expression? signedPreKeyId, + Expression? signedPreKey, + Expression? createdAt, + }) { + return RawValuesInsertable({ + if (signedPreKeyId != null) 'signed_pre_key_id': signedPreKeyId, + if (signedPreKey != null) 'signed_pre_key': signedPreKey, + if (createdAt != null) 'created_at': createdAt, + }); + } + + SignalSignedPreKeyStoresCompanion copyWith({ + Value? signedPreKeyId, + Value? signedPreKey, + Value? createdAt, + }) { + return SignalSignedPreKeyStoresCompanion( + signedPreKeyId: signedPreKeyId ?? this.signedPreKeyId, + signedPreKey: signedPreKey ?? this.signedPreKey, + createdAt: createdAt ?? this.createdAt, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (signedPreKeyId.present) { + map['signed_pre_key_id'] = Variable(signedPreKeyId.value); + } + if (signedPreKey.present) { + map['signed_pre_key'] = Variable(signedPreKey.value); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('SignalSignedPreKeyStoresCompanion(') + ..write('signedPreKeyId: $signedPreKeyId, ') + ..write('signedPreKey: $signedPreKey, ') + ..write('createdAt: $createdAt') + ..write(')')) + .toString(); + } +} + class $MessageActionsTable extends MessageActions with TableInfo<$MessageActionsTable, MessageAction> { @override @@ -12118,6 +12397,8 @@ abstract class _$TwonlyDB extends GeneratedDatabase { $SignalSenderKeyStoresTable(this); late final $SignalSessionStoresTable signalSessionStores = $SignalSessionStoresTable(this); + late final $SignalSignedPreKeyStoresTable signalSignedPreKeyStores = + $SignalSignedPreKeyStoresTable(this); late final $MessageActionsTable messageActions = $MessageActionsTable(this); late final $GroupHistoriesTable groupHistories = $GroupHistoriesTable(this); late final $KeyVerificationsTable keyVerifications = $KeyVerificationsTable( @@ -12170,6 +12451,7 @@ abstract class _$TwonlyDB extends GeneratedDatabase { signalPreKeyStores, signalSenderKeyStores, signalSessionStores, + signalSignedPreKeyStores, messageActions, groupHistories, keyVerifications, @@ -19540,6 +19822,185 @@ typedef $$SignalSessionStoresTableProcessedTableManager = SignalSessionStore, PrefetchHooks Function() >; +typedef $$SignalSignedPreKeyStoresTableCreateCompanionBuilder = + SignalSignedPreKeyStoresCompanion Function({ + Value signedPreKeyId, + required Uint8List signedPreKey, + Value createdAt, + }); +typedef $$SignalSignedPreKeyStoresTableUpdateCompanionBuilder = + SignalSignedPreKeyStoresCompanion Function({ + Value signedPreKeyId, + Value signedPreKey, + Value createdAt, + }); + +class $$SignalSignedPreKeyStoresTableFilterComposer + extends Composer<_$TwonlyDB, $SignalSignedPreKeyStoresTable> { + $$SignalSignedPreKeyStoresTableFilterComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + ColumnFilters get signedPreKeyId => $composableBuilder( + column: $table.signedPreKeyId, + builder: (column) => ColumnFilters(column), + ); + + ColumnFilters get signedPreKey => $composableBuilder( + column: $table.signedPreKey, + builder: (column) => ColumnFilters(column), + ); + + ColumnFilters get createdAt => $composableBuilder( + column: $table.createdAt, + builder: (column) => ColumnFilters(column), + ); +} + +class $$SignalSignedPreKeyStoresTableOrderingComposer + extends Composer<_$TwonlyDB, $SignalSignedPreKeyStoresTable> { + $$SignalSignedPreKeyStoresTableOrderingComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + ColumnOrderings get signedPreKeyId => $composableBuilder( + column: $table.signedPreKeyId, + builder: (column) => ColumnOrderings(column), + ); + + ColumnOrderings get signedPreKey => $composableBuilder( + column: $table.signedPreKey, + builder: (column) => ColumnOrderings(column), + ); + + ColumnOrderings get createdAt => $composableBuilder( + column: $table.createdAt, + builder: (column) => ColumnOrderings(column), + ); +} + +class $$SignalSignedPreKeyStoresTableAnnotationComposer + extends Composer<_$TwonlyDB, $SignalSignedPreKeyStoresTable> { + $$SignalSignedPreKeyStoresTableAnnotationComposer({ + required super.$db, + required super.$table, + super.joinBuilder, + super.$addJoinBuilderToRootComposer, + super.$removeJoinBuilderFromRootComposer, + }); + GeneratedColumn get signedPreKeyId => $composableBuilder( + column: $table.signedPreKeyId, + builder: (column) => column, + ); + + GeneratedColumn get signedPreKey => $composableBuilder( + column: $table.signedPreKey, + builder: (column) => column, + ); + + GeneratedColumn get createdAt => + $composableBuilder(column: $table.createdAt, builder: (column) => column); +} + +class $$SignalSignedPreKeyStoresTableTableManager + extends + RootTableManager< + _$TwonlyDB, + $SignalSignedPreKeyStoresTable, + SignalSignedPreKeyStore, + $$SignalSignedPreKeyStoresTableFilterComposer, + $$SignalSignedPreKeyStoresTableOrderingComposer, + $$SignalSignedPreKeyStoresTableAnnotationComposer, + $$SignalSignedPreKeyStoresTableCreateCompanionBuilder, + $$SignalSignedPreKeyStoresTableUpdateCompanionBuilder, + ( + SignalSignedPreKeyStore, + BaseReferences< + _$TwonlyDB, + $SignalSignedPreKeyStoresTable, + SignalSignedPreKeyStore + >, + ), + SignalSignedPreKeyStore, + PrefetchHooks Function() + > { + $$SignalSignedPreKeyStoresTableTableManager( + _$TwonlyDB db, + $SignalSignedPreKeyStoresTable table, + ) : super( + TableManagerState( + db: db, + table: table, + createFilteringComposer: () => + $$SignalSignedPreKeyStoresTableFilterComposer( + $db: db, + $table: table, + ), + createOrderingComposer: () => + $$SignalSignedPreKeyStoresTableOrderingComposer( + $db: db, + $table: table, + ), + createComputedFieldComposer: () => + $$SignalSignedPreKeyStoresTableAnnotationComposer( + $db: db, + $table: table, + ), + updateCompanionCallback: + ({ + Value signedPreKeyId = const Value.absent(), + Value signedPreKey = const Value.absent(), + Value createdAt = const Value.absent(), + }) => SignalSignedPreKeyStoresCompanion( + signedPreKeyId: signedPreKeyId, + signedPreKey: signedPreKey, + createdAt: createdAt, + ), + createCompanionCallback: + ({ + Value signedPreKeyId = const Value.absent(), + required Uint8List signedPreKey, + Value createdAt = const Value.absent(), + }) => SignalSignedPreKeyStoresCompanion.insert( + signedPreKeyId: signedPreKeyId, + signedPreKey: signedPreKey, + createdAt: createdAt, + ), + withReferenceMapper: (p0) => p0 + .map((e) => (e.readTable(table), BaseReferences(db, table, e))) + .toList(), + prefetchHooksCallback: null, + ), + ); +} + +typedef $$SignalSignedPreKeyStoresTableProcessedTableManager = + ProcessedTableManager< + _$TwonlyDB, + $SignalSignedPreKeyStoresTable, + SignalSignedPreKeyStore, + $$SignalSignedPreKeyStoresTableFilterComposer, + $$SignalSignedPreKeyStoresTableOrderingComposer, + $$SignalSignedPreKeyStoresTableAnnotationComposer, + $$SignalSignedPreKeyStoresTableCreateCompanionBuilder, + $$SignalSignedPreKeyStoresTableUpdateCompanionBuilder, + ( + SignalSignedPreKeyStore, + BaseReferences< + _$TwonlyDB, + $SignalSignedPreKeyStoresTable, + SignalSignedPreKeyStore + >, + ), + SignalSignedPreKeyStore, + PrefetchHooks Function() + >; typedef $$MessageActionsTableCreateCompanionBuilder = MessageActionsCompanion Function({ required String messageId, @@ -23335,6 +23796,11 @@ class $TwonlyDBManager { $$SignalSenderKeyStoresTableTableManager(_db, _db.signalSenderKeyStores); $$SignalSessionStoresTableTableManager get signalSessionStores => $$SignalSessionStoresTableTableManager(_db, _db.signalSessionStores); + $$SignalSignedPreKeyStoresTableTableManager get signalSignedPreKeyStores => + $$SignalSignedPreKeyStoresTableTableManager( + _db, + _db.signalSignedPreKeyStores, + ); $$MessageActionsTableTableManager get messageActions => $$MessageActionsTableTableManager(_db, _db.messageActions); $$GroupHistoriesTableTableManager get groupHistories => diff --git a/lib/src/database/twonly.db.steps.dart b/lib/src/database/twonly.db.steps.dart index 4c8cd6d5..c7b8c83b 100644 --- a/lib/src/database/twonly.db.steps.dart +++ b/lib/src/database/twonly.db.steps.dart @@ -7561,6 +7561,477 @@ i1.GeneratedColumn _column_241(String aliasedName) => type: i1.DriftSqlType.string, $customConstraints: 'NULL', ); + +final class Schema15 extends i0.VersionedSchema { + Schema15({required super.database}) : super(version: 15); + @override + late final List entities = [ + contacts, + groups, + mediaFiles, + messages, + messageHistories, + reactions, + groupMembers, + receipts, + receivedReceipts, + signalIdentityKeyStores, + signalPreKeyStores, + signalSenderKeyStores, + signalSessionStores, + signalSignedPreKeyStores, + messageActions, + groupHistories, + keyVerifications, + verificationTokens, + userDiscoveryAnnouncedUsers, + userDiscoveryUserRelations, + userDiscoveryOtherPromotions, + userDiscoveryOwnPromotions, + userDiscoveryShares, + shortcuts, + shortcutMembers, + ]; + late final Shape39 contacts = Shape39( + source: i0.VersionedTable( + entityName: 'contacts', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(user_id)'], + columns: [ + _column_106, + _column_107, + _column_108, + _column_109, + _column_110, + _column_111, + _column_112, + _column_113, + _column_114, + _column_115, + _column_116, + _column_117, + _column_118, + _column_211, + _column_212, + _column_213, + _column_214, + _column_215, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape23 groups = Shape23( + source: i0.VersionedTable( + entityName: 'groups', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(group_id)'], + columns: [ + _column_119, + _column_120, + _column_121, + _column_122, + _column_123, + _column_124, + _column_125, + _column_126, + _column_127, + _column_128, + _column_129, + _column_130, + _column_131, + _column_132, + _column_133, + _column_134, + _column_118, + _column_135, + _column_136, + _column_137, + _column_138, + _column_139, + _column_140, + _column_141, + _column_142, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape49 mediaFiles = Shape49( + source: i0.VersionedTable( + entityName: 'media_files', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(media_id)'], + columns: [ + _column_143, + _column_144, + _column_145, + _column_146, + _column_147, + _column_148, + _column_149, + _column_239, + _column_240, + _column_207, + _column_150, + _column_151, + _column_152, + _column_153, + _column_154, + _column_155, + _column_156, + _column_157, + _column_118, + _column_241, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape25 messages = Shape25( + source: i0.VersionedTable( + entityName: 'messages', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(message_id)'], + columns: [ + _column_158, + _column_159, + _column_160, + _column_144, + _column_161, + _column_162, + _column_163, + _column_164, + _column_165, + _column_153, + _column_166, + _column_167, + _column_168, + _column_169, + _column_118, + _column_170, + _column_171, + _column_172, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape26 messageHistories = Shape26( + source: i0.VersionedTable( + entityName: 'message_histories', + withoutRowId: false, + isStrict: false, + tableConstraints: [], + columns: [ + _column_173, + _column_174, + _column_175, + _column_161, + _column_118, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape27 reactions = Shape27( + source: i0.VersionedTable( + entityName: 'reactions', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(message_id, sender_id, emoji)'], + columns: [_column_174, _column_176, _column_177, _column_118], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape38 groupMembers = Shape38( + source: i0.VersionedTable( + entityName: 'group_members', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(group_id, contact_id)'], + columns: [ + _column_158, + _column_178, + _column_179, + _column_180, + _column_209, + _column_210, + _column_181, + _column_118, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape37 receipts = Shape37( + source: i0.VersionedTable( + entityName: 'receipts', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(receipt_id)'], + columns: [ + _column_182, + _column_183, + _column_184, + _column_185, + _column_186, + _column_208, + _column_187, + _column_188, + _column_189, + _column_190, + _column_191, + _column_118, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape30 receivedReceipts = Shape30( + source: i0.VersionedTable( + entityName: 'received_receipts', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(receipt_id)'], + columns: [_column_182, _column_118], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape31 signalIdentityKeyStores = Shape31( + source: i0.VersionedTable( + entityName: 'signal_identity_key_stores', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(device_id, name)'], + columns: [_column_192, _column_193, _column_194, _column_118], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape32 signalPreKeyStores = Shape32( + source: i0.VersionedTable( + entityName: 'signal_pre_key_stores', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(pre_key_id)'], + columns: [_column_195, _column_196, _column_118], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape11 signalSenderKeyStores = Shape11( + source: i0.VersionedTable( + entityName: 'signal_sender_key_stores', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(sender_key_name)'], + columns: [_column_197, _column_198], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape33 signalSessionStores = Shape33( + source: i0.VersionedTable( + entityName: 'signal_session_stores', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(device_id, name)'], + columns: [_column_192, _column_193, _column_199, _column_118], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape50 signalSignedPreKeyStores = Shape50( + source: i0.VersionedTable( + entityName: 'signal_signed_pre_key_stores', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(signed_pre_key_id)'], + columns: [_column_242, _column_243, _column_118], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape34 messageActions = Shape34( + source: i0.VersionedTable( + entityName: 'message_actions', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(message_id, contact_id, type)'], + columns: [_column_174, _column_183, _column_144, _column_200], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape35 groupHistories = Shape35( + source: i0.VersionedTable( + entityName: 'group_histories', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(group_history_id)'], + columns: [ + _column_201, + _column_158, + _column_202, + _column_203, + _column_204, + _column_205, + _column_206, + _column_144, + _column_200, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape40 keyVerifications = Shape40( + source: i0.VersionedTable( + entityName: 'key_verifications', + withoutRowId: false, + isStrict: false, + tableConstraints: [], + columns: [_column_216, _column_183, _column_144, _column_118], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape41 verificationTokens = Shape41( + source: i0.VersionedTable( + entityName: 'verification_tokens', + withoutRowId: false, + isStrict: false, + tableConstraints: [], + columns: [_column_217, _column_218, _column_118], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape42 userDiscoveryAnnouncedUsers = Shape42( + source: i0.VersionedTable( + entityName: 'user_discovery_announced_users', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(announced_user_id)'], + columns: [ + _column_219, + _column_220, + _column_221, + _column_222, + _column_223, + _column_224, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape43 userDiscoveryUserRelations = Shape43( + source: i0.VersionedTable( + entityName: 'user_discovery_user_relations', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(announced_user_id, from_contact_id)'], + columns: [_column_225, _column_226, _column_227], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape44 userDiscoveryOtherPromotions = Shape44( + source: i0.VersionedTable( + entityName: 'user_discovery_other_promotions', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(from_contact_id, public_id)'], + columns: [ + _column_226, + _column_228, + _column_229, + _column_230, + _column_231, + _column_227, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape45 userDiscoveryOwnPromotions = Shape45( + source: i0.VersionedTable( + entityName: 'user_discovery_own_promotions', + withoutRowId: false, + isStrict: false, + tableConstraints: [], + columns: [_column_232, _column_183, _column_233], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape46 userDiscoveryShares = Shape46( + source: i0.VersionedTable( + entityName: 'user_discovery_shares', + withoutRowId: false, + isStrict: false, + tableConstraints: [], + columns: [_column_234, _column_235, _column_175], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape47 shortcuts = Shape47( + source: i0.VersionedTable( + entityName: 'shortcuts', + withoutRowId: false, + isStrict: false, + tableConstraints: [], + columns: [_column_173, _column_236, _column_237], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape48 shortcutMembers = Shape48( + source: i0.VersionedTable( + entityName: 'shortcut_members', + withoutRowId: false, + isStrict: false, + tableConstraints: ['PRIMARY KEY(shortcut_id, group_id)'], + columns: [_column_238, _column_158], + attachedDatabase: database, + ), + alias: null, + ); +} + +class Shape50 extends i0.VersionedTable { + Shape50({required super.source, required super.alias}) : super.aliased(); + i1.GeneratedColumn get signedPreKeyId => + columnsByName['signed_pre_key_id']! as i1.GeneratedColumn; + i1.GeneratedColumn get signedPreKey => + columnsByName['signed_pre_key']! as i1.GeneratedColumn; + i1.GeneratedColumn get createdAt => + columnsByName['created_at']! as i1.GeneratedColumn; +} + +i1.GeneratedColumn _column_242(String aliasedName) => + i1.GeneratedColumn( + 'signed_pre_key_id', + aliasedName, + false, + type: i1.DriftSqlType.int, + $customConstraints: 'NOT NULL', + ); +i1.GeneratedColumn _column_243(String aliasedName) => + i1.GeneratedColumn( + 'signed_pre_key', + aliasedName, + false, + type: i1.DriftSqlType.blob, + $customConstraints: 'NOT NULL', + ); i0.MigrationStepWithVersion migrationSteps({ required Future Function(i1.Migrator m, Schema2 schema) from1To2, required Future Function(i1.Migrator m, Schema3 schema) from2To3, @@ -7575,6 +8046,7 @@ i0.MigrationStepWithVersion migrationSteps({ required Future Function(i1.Migrator m, Schema12 schema) from11To12, required Future Function(i1.Migrator m, Schema13 schema) from12To13, required Future Function(i1.Migrator m, Schema14 schema) from13To14, + required Future Function(i1.Migrator m, Schema15 schema) from14To15, }) { return (currentVersion, database) async { switch (currentVersion) { @@ -7643,6 +8115,11 @@ i0.MigrationStepWithVersion migrationSteps({ final migrator = i1.Migrator(database, schema); await from13To14(migrator, schema); return 14; + case 14: + final schema = Schema15(database: database); + final migrator = i1.Migrator(database, schema); + await from14To15(migrator, schema); + return 15; default: throw ArgumentError.value('Unknown migration from $currentVersion'); } @@ -7663,6 +8140,7 @@ i1.OnUpgrade stepByStep({ required Future Function(i1.Migrator m, Schema12 schema) from11To12, required Future Function(i1.Migrator m, Schema13 schema) from12To13, required Future Function(i1.Migrator m, Schema14 schema) from13To14, + required Future Function(i1.Migrator m, Schema15 schema) from14To15, }) => i0.VersionedSchema.stepByStepHelper( step: migrationSteps( from1To2: from1To2, @@ -7678,5 +8156,6 @@ i1.OnUpgrade stepByStep({ from11To12: from11To12, from12To13: from12To13, from13To14: from13To14, + from14To15: from14To15, ), ); diff --git a/lib/src/services/signal/identity.signal.dart b/lib/src/services/signal/identity.signal.dart index 8c7846db..4bc5feb1 100644 --- a/lib/src/services/signal/identity.signal.dart +++ b/lib/src/services/signal/identity.signal.dart @@ -3,6 +3,7 @@ import 'package:clock/clock.dart'; import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart'; import 'package:twonly/core/bridge/wrapper/key_manager.dart'; import 'package:twonly/locator.dart'; +import 'package:twonly/src/database/signal/signal_signed_pre_key_store.dart'; import 'package:twonly/src/model/json/signal_identity.model.dart'; import 'package:twonly/src/services/signal/consts.signal.dart'; import 'package:twonly/src/services/signal/protocol_state.signal.dart'; @@ -93,19 +94,38 @@ Future getUserPublicKey() async { Future createIfNotExistsSignalIdentity() async { // check if identity already exists - if (await getSignalIdentity() != null) return; + final existingIdentity = await getSignalIdentity(); + if (existingIdentity != null) { + final store = await getSignalStoreFromIdentity(existingIdentity); + final keys = await store.loadSignedPreKeys(); + if (keys.isEmpty) { + Log.warn( + 'Signal identity exists but signed prekeys are missing. Generating a new one.', + ); + final keyPair = await store.getIdentityKeyPair(); + final signedPreKey = generateSignedPreKey(keyPair, defaultDeviceId); + await SignalSignedPreKeyStore().storeSignedPreKey( + signedPreKey.id, + signedPreKey, + ); + } + return; + } final identityKeyPair = generateIdentityKeyPair(); final registrationId = generateRegistrationId(true); final signedPreKey = generateSignedPreKey(identityKeyPair, defaultDeviceId); - final signedPreKeyStore = {}; - signedPreKeyStore[signedPreKey.id] = signedPreKey.serialize(); + + await SignalSignedPreKeyStore().storeSignedPreKey( + signedPreKey.id, + signedPreKey, + ); await RustKeyManager.importSignalIdentity( identityKeyPairStructure: identityKeyPair.serialize(), registrationId: registrationId, - signedPreKeyStore: signedPreKeyStore, + signedPreKeyStore: const {}, ); } diff --git a/lib/src/visual/views/camera/camera_preview_components/main_camera_controller.dart b/lib/src/visual/views/camera/camera_preview_components/main_camera_controller.dart index ec5a8206..a1cf0e27 100644 --- a/lib/src/visual/views/camera/camera_preview_components/main_camera_controller.dart +++ b/lib/src/visual/views/camera/camera_preview_components/main_camera_controller.dart @@ -146,18 +146,17 @@ class MainCameraController { ); try { await cameraController?.initialize(); + await cameraController?.startImageStream(_processCameraImage); + await cameraController?.setZoomLevel(selectedCameraDetails.scaleFactor); + if (userService.currentUser.videoStabilizationEnabled && !kDebugMode) { + await cameraController?.setVideoStabilizationMode( + VideoStabilizationMode.level1, + ); + } } catch (e) { - Log.error(e); - cameraController = null; // ensure uninitialized controller is not reused + cameraController = null; return; } - await cameraController?.startImageStream(_processCameraImage); - await cameraController?.setZoomLevel(selectedCameraDetails.scaleFactor); - if (userService.currentUser.videoStabilizationEnabled && !kDebugMode) { - await cameraController?.setVideoStabilizationMode( - VideoStabilizationMode.level1, - ); - } } else { try { if (!isVideoRecording) { @@ -179,29 +178,35 @@ class MainCameraController { } } - await cameraController?.lockCaptureOrientation( - DeviceOrientation.portraitUp, - ); - await cameraController?.setFlashMode( - selectedCameraDetails.isFlashOn ? FlashMode.always : FlashMode.off, - ); - selectedCameraDetails.maxAvailableZoom = - await cameraController?.getMaxZoomLevel() ?? 1; - selectedCameraDetails.minAvailableZoom = - await cameraController?.getMinZoomLevel() ?? 1; - selectedCameraDetails - ..isZoomAble = - selectedCameraDetails.maxAvailableZoom != - selectedCameraDetails.minAvailableZoom - ..cameraLoaded = true - ..cameraId = cameraId; + try { + await cameraController?.lockCaptureOrientation( + DeviceOrientation.portraitUp, + ); + await cameraController?.setFlashMode( + selectedCameraDetails.isFlashOn ? FlashMode.always : FlashMode.off, + ); + selectedCameraDetails.maxAvailableZoom = + await cameraController?.getMaxZoomLevel() ?? 1; + selectedCameraDetails.minAvailableZoom = + await cameraController?.getMinZoomLevel() ?? 1; + selectedCameraDetails + ..isZoomAble = + selectedCameraDetails.maxAvailableZoom != + selectedCameraDetails.minAvailableZoom + ..cameraLoaded = true + ..cameraId = cameraId; - facePaint = null; - qrCodePain = null; - isSelectingFaceFilters = false; - setFilter(FaceFilterType.none); - zoomButtonKey = GlobalKey(); - setState(); + facePaint = null; + qrCodePain = null; + isSelectingFaceFilters = false; + setFilter(FaceFilterType.none); + zoomButtonKey = GlobalKey(); + setState(); + } catch (e) { + Log.error(e); + cameraController = null; + return; + } } Future onDoubleTap() async { diff --git a/lib/src/visual/views/memories/components/flashback_banner.comp.dart b/lib/src/visual/views/memories/components/flashback_banner.comp.dart index 01bbd48a..df3fb0c4 100644 --- a/lib/src/visual/views/memories/components/flashback_banner.comp.dart +++ b/lib/src/visual/views/memories/components/flashback_banner.comp.dart @@ -14,11 +14,13 @@ class MemoriesFlashbackBannerComp extends StatelessWidget { @override Widget build(BuildContext context) { - if (lastYears.isEmpty) return const SliverToBoxAdapter(child: SizedBox.shrink()); + if (lastYears.isEmpty) { + return const SliverToBoxAdapter(child: SizedBox.shrink()); + } return SliverToBoxAdapter( child: Padding( - padding: const EdgeInsets.fromLTRB(16, 8, 16, 16), + padding: const EdgeInsets.fromLTRB(0, 8, 0, 16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -27,9 +29,13 @@ class MemoriesFlashbackBannerComp extends StatelessWidget { child: ListView.separated( scrollDirection: Axis.horizontal, physics: const BouncingScrollPhysics(), - itemCount: lastYears.length, + itemCount: lastYears.length + 1, separatorBuilder: (context, _) => const SizedBox(width: 12), itemBuilder: (context, idx) { + if (idx == 0) { + return const SizedBox.shrink(); + } + idx -= 1; final entry = lastYears.entries.elementAt(idx); final years = entry.key; final items = entry.value; diff --git a/lib/src/visual/views/memories/memories.view.dart b/lib/src/visual/views/memories/memories.view.dart index 0a0655a8..dc81a51f 100644 --- a/lib/src/visual/views/memories/memories.view.dart +++ b/lib/src/visual/views/memories/memories.view.dart @@ -430,38 +430,34 @@ class MemoriesViewState extends State { ), ), ), - SliverPadding( - padding: const EdgeInsets.symmetric(horizontal: 4), - sliver: SliverGrid( - gridDelegate: - const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 4, - mainAxisSpacing: 2, - crossAxisSpacing: 2, - childAspectRatio: 9 / 16, - ), - delegate: SliverChildBuilderDelegate( - (context, idx) { - final globalIndex = orderedByMonth[month]![idx]; - final item = state.galleryItems[globalIndex]; - final mediaId = - item.mediaService.mediaFile.mediaId; - final isSelected = _selectedMediaIds.contains( - mediaId, - ); + SliverGrid( + gridDelegate: + const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 4, + mainAxisSpacing: 2, + crossAxisSpacing: 2, + childAspectRatio: 9 / 16, + ), + delegate: SliverChildBuilderDelegate( + (context, idx) { + final globalIndex = orderedByMonth[month]![idx]; + final item = state.galleryItems[globalIndex]; + final mediaId = item.mediaService.mediaFile.mediaId; + final isSelected = _selectedMediaIds.contains( + mediaId, + ); - return MemoriesThumbnailComp( - galleryItem: item, - index: globalIndex, - selectionMode: _selectionMode, - isSelected: isSelected, - activeMediaIdNotifier: _activeMediaIdNotifier, - onLongPress: () => _onLongPressItem(mediaId), - onTap: () => _onTapItem(mediaId, globalIndex), - ); - }, - childCount: orderedByMonth[month]!.length, - ), + return MemoriesThumbnailComp( + galleryItem: item, + index: globalIndex, + selectionMode: _selectionMode, + isSelected: isSelected, + activeMediaIdNotifier: _activeMediaIdNotifier, + onLongPress: () => _onLongPressItem(mediaId), + onTap: () => _onTapItem(mediaId, globalIndex), + ); + }, + childCount: orderedByMonth[month]!.length, ), ), ], diff --git a/test/drift/twonly_db/generated/schema.dart b/test/drift/twonly_db/generated/schema.dart index 938ab126..ad724535 100644 --- a/test/drift/twonly_db/generated/schema.dart +++ b/test/drift/twonly_db/generated/schema.dart @@ -18,6 +18,7 @@ import 'schema_v11.dart' as v11; import 'schema_v12.dart' as v12; import 'schema_v13.dart' as v13; import 'schema_v14.dart' as v14; +import 'schema_v15.dart' as v15; class GeneratedHelper implements SchemaInstantiationHelper { @override @@ -51,10 +52,28 @@ class GeneratedHelper implements SchemaInstantiationHelper { return v13.DatabaseAtV13(db); case 14: return v14.DatabaseAtV14(db); + case 15: + return v15.DatabaseAtV15(db); default: throw MissingSchemaException(version, versions); } } - static const versions = const [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]; + static const versions = const [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + ]; } diff --git a/test/drift/twonly_db/generated/schema_v15.dart b/test/drift/twonly_db/generated/schema_v15.dart index 8200e3b3..98003884 100644 --- a/test/drift/twonly_db/generated/schema_v15.dart +++ b/test/drift/twonly_db/generated/schema_v15.dart @@ -145,6 +145,17 @@ class Contacts extends Table with TableInfo { 'NOT NULL DEFAULT 0 CHECK (user_discovery_excluded IN (0, 1))', defaultValue: const CustomExpression('0'), ); + late final GeneratedColumn userDiscoveryManualApproved = + GeneratedColumn( + 'user_discovery_manual_approved', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NULL DEFAULT 0 CHECK (user_discovery_manual_approved IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); late final GeneratedColumn mediaSendCounter = GeneratedColumn( 'media_send_counter', aliasedName, @@ -180,6 +191,7 @@ class Contacts extends Table with TableInfo { createdAt, userDiscoveryVersion, userDiscoveryExcluded, + userDiscoveryManualApproved, mediaSendCounter, mediaReceivedCounter, ]; @@ -254,6 +266,10 @@ class Contacts extends Table with TableInfo { DriftSqlType.int, data['${effectivePrefix}user_discovery_excluded'], )!, + userDiscoveryManualApproved: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}user_discovery_manual_approved'], + ), mediaSendCounter: attachedDatabase.typeMapping.read( DriftSqlType.int, data['${effectivePrefix}media_send_counter'], @@ -292,6 +308,7 @@ class ContactsData extends DataClass implements Insertable { final int createdAt; final i2.Uint8List? userDiscoveryVersion; final int userDiscoveryExcluded; + final int? userDiscoveryManualApproved; final int mediaSendCounter; final int mediaReceivedCounter; const ContactsData({ @@ -310,6 +327,7 @@ class ContactsData extends DataClass implements Insertable { required this.createdAt, this.userDiscoveryVersion, required this.userDiscoveryExcluded, + this.userDiscoveryManualApproved, required this.mediaSendCounter, required this.mediaReceivedCounter, }); @@ -343,6 +361,11 @@ class ContactsData extends DataClass implements Insertable { ); } map['user_discovery_excluded'] = Variable(userDiscoveryExcluded); + if (!nullToAbsent || userDiscoveryManualApproved != null) { + map['user_discovery_manual_approved'] = Variable( + userDiscoveryManualApproved, + ); + } map['media_send_counter'] = Variable(mediaSendCounter); map['media_received_counter'] = Variable(mediaReceivedCounter); return map; @@ -373,6 +396,10 @@ class ContactsData extends DataClass implements Insertable { ? const Value.absent() : Value(userDiscoveryVersion), userDiscoveryExcluded: Value(userDiscoveryExcluded), + userDiscoveryManualApproved: + userDiscoveryManualApproved == null && nullToAbsent + ? const Value.absent() + : Value(userDiscoveryManualApproved), mediaSendCounter: Value(mediaSendCounter), mediaReceivedCounter: Value(mediaReceivedCounter), ); @@ -407,6 +434,9 @@ class ContactsData extends DataClass implements Insertable { userDiscoveryExcluded: serializer.fromJson( json['userDiscoveryExcluded'], ), + userDiscoveryManualApproved: serializer.fromJson( + json['userDiscoveryManualApproved'], + ), mediaSendCounter: serializer.fromJson(json['mediaSendCounter']), mediaReceivedCounter: serializer.fromJson( json['mediaReceivedCounter'], @@ -436,6 +466,9 @@ class ContactsData extends DataClass implements Insertable { userDiscoveryVersion, ), 'userDiscoveryExcluded': serializer.toJson(userDiscoveryExcluded), + 'userDiscoveryManualApproved': serializer.toJson( + userDiscoveryManualApproved, + ), 'mediaSendCounter': serializer.toJson(mediaSendCounter), 'mediaReceivedCounter': serializer.toJson(mediaReceivedCounter), }; @@ -457,6 +490,7 @@ class ContactsData extends DataClass implements Insertable { int? createdAt, Value userDiscoveryVersion = const Value.absent(), int? userDiscoveryExcluded, + Value userDiscoveryManualApproved = const Value.absent(), int? mediaSendCounter, int? mediaReceivedCounter, }) => ContactsData( @@ -479,6 +513,9 @@ class ContactsData extends DataClass implements Insertable { ? userDiscoveryVersion.value : this.userDiscoveryVersion, userDiscoveryExcluded: userDiscoveryExcluded ?? this.userDiscoveryExcluded, + userDiscoveryManualApproved: userDiscoveryManualApproved.present + ? userDiscoveryManualApproved.value + : this.userDiscoveryManualApproved, mediaSendCounter: mediaSendCounter ?? this.mediaSendCounter, mediaReceivedCounter: mediaReceivedCounter ?? this.mediaReceivedCounter, ); @@ -513,6 +550,9 @@ class ContactsData extends DataClass implements Insertable { userDiscoveryExcluded: data.userDiscoveryExcluded.present ? data.userDiscoveryExcluded.value : this.userDiscoveryExcluded, + userDiscoveryManualApproved: data.userDiscoveryManualApproved.present + ? data.userDiscoveryManualApproved.value + : this.userDiscoveryManualApproved, mediaSendCounter: data.mediaSendCounter.present ? data.mediaSendCounter.value : this.mediaSendCounter, @@ -540,6 +580,7 @@ class ContactsData extends DataClass implements Insertable { ..write('createdAt: $createdAt, ') ..write('userDiscoveryVersion: $userDiscoveryVersion, ') ..write('userDiscoveryExcluded: $userDiscoveryExcluded, ') + ..write('userDiscoveryManualApproved: $userDiscoveryManualApproved, ') ..write('mediaSendCounter: $mediaSendCounter, ') ..write('mediaReceivedCounter: $mediaReceivedCounter') ..write(')')) @@ -563,6 +604,7 @@ class ContactsData extends DataClass implements Insertable { createdAt, $driftBlobEquality.hash(userDiscoveryVersion), userDiscoveryExcluded, + userDiscoveryManualApproved, mediaSendCounter, mediaReceivedCounter, ); @@ -591,6 +633,8 @@ class ContactsData extends DataClass implements Insertable { this.userDiscoveryVersion, ) && other.userDiscoveryExcluded == this.userDiscoveryExcluded && + other.userDiscoveryManualApproved == + this.userDiscoveryManualApproved && other.mediaSendCounter == this.mediaSendCounter && other.mediaReceivedCounter == this.mediaReceivedCounter); } @@ -611,6 +655,7 @@ class ContactsCompanion extends UpdateCompanion { final Value createdAt; final Value userDiscoveryVersion; final Value userDiscoveryExcluded; + final Value userDiscoveryManualApproved; final Value mediaSendCounter; final Value mediaReceivedCounter; const ContactsCompanion({ @@ -629,6 +674,7 @@ class ContactsCompanion extends UpdateCompanion { this.createdAt = const Value.absent(), this.userDiscoveryVersion = const Value.absent(), this.userDiscoveryExcluded = const Value.absent(), + this.userDiscoveryManualApproved = const Value.absent(), this.mediaSendCounter = const Value.absent(), this.mediaReceivedCounter = const Value.absent(), }); @@ -648,6 +694,7 @@ class ContactsCompanion extends UpdateCompanion { this.createdAt = const Value.absent(), this.userDiscoveryVersion = const Value.absent(), this.userDiscoveryExcluded = const Value.absent(), + this.userDiscoveryManualApproved = const Value.absent(), this.mediaSendCounter = const Value.absent(), this.mediaReceivedCounter = const Value.absent(), }) : username = Value(username); @@ -667,6 +714,7 @@ class ContactsCompanion extends UpdateCompanion { Expression? createdAt, Expression? userDiscoveryVersion, Expression? userDiscoveryExcluded, + Expression? userDiscoveryManualApproved, Expression? mediaSendCounter, Expression? mediaReceivedCounter, }) { @@ -690,6 +738,8 @@ class ContactsCompanion extends UpdateCompanion { 'user_discovery_version': userDiscoveryVersion, if (userDiscoveryExcluded != null) 'user_discovery_excluded': userDiscoveryExcluded, + if (userDiscoveryManualApproved != null) + 'user_discovery_manual_approved': userDiscoveryManualApproved, if (mediaSendCounter != null) 'media_send_counter': mediaSendCounter, if (mediaReceivedCounter != null) 'media_received_counter': mediaReceivedCounter, @@ -712,6 +762,7 @@ class ContactsCompanion extends UpdateCompanion { Value? createdAt, Value? userDiscoveryVersion, Value? userDiscoveryExcluded, + Value? userDiscoveryManualApproved, Value? mediaSendCounter, Value? mediaReceivedCounter, }) { @@ -732,6 +783,8 @@ class ContactsCompanion extends UpdateCompanion { userDiscoveryVersion: userDiscoveryVersion ?? this.userDiscoveryVersion, userDiscoveryExcluded: userDiscoveryExcluded ?? this.userDiscoveryExcluded, + userDiscoveryManualApproved: + userDiscoveryManualApproved ?? this.userDiscoveryManualApproved, mediaSendCounter: mediaSendCounter ?? this.mediaSendCounter, mediaReceivedCounter: mediaReceivedCounter ?? this.mediaReceivedCounter, ); @@ -791,6 +844,11 @@ class ContactsCompanion extends UpdateCompanion { userDiscoveryExcluded.value, ); } + if (userDiscoveryManualApproved.present) { + map['user_discovery_manual_approved'] = Variable( + userDiscoveryManualApproved.value, + ); + } if (mediaSendCounter.present) { map['media_send_counter'] = Variable(mediaSendCounter.value); } @@ -818,6 +876,7 @@ class ContactsCompanion extends UpdateCompanion { ..write('createdAt: $createdAt, ') ..write('userDiscoveryVersion: $userDiscoveryVersion, ') ..write('userDiscoveryExcluded: $userDiscoveryExcluded, ') + ..write('userDiscoveryManualApproved: $userDiscoveryManualApproved, ') ..write('mediaSendCounter: $mediaSendCounter, ') ..write('mediaReceivedCounter: $mediaReceivedCounter') ..write(')')) @@ -2077,6 +2136,25 @@ class MediaFiles extends Table with TableInfo { $customConstraints: 'NOT NULL DEFAULT 0 CHECK (is_draft_media IN (0, 1))', defaultValue: const CustomExpression('0'), ); + late final GeneratedColumn isFavorite = GeneratedColumn( + 'is_favorite', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0 CHECK (is_favorite IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn hasCropAnalyzed = GeneratedColumn( + 'has_crop_analyzed', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NOT NULL DEFAULT 0 CHECK (has_crop_analyzed IN (0, 1))', + defaultValue: const CustomExpression('0'), + ); late final GeneratedColumn preProgressingProcess = GeneratedColumn( 'pre_progressing_process', aliasedName, @@ -2168,6 +2246,14 @@ class MediaFiles extends Table with TableInfo { 'CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER)', ), ); + late final GeneratedColumn createdAtMonth = GeneratedColumn( + 'created_at_month', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + $customConstraints: 'NULL', + ); @override List get $columns => [ mediaId, @@ -2177,6 +2263,8 @@ class MediaFiles extends Table with TableInfo { requiresAuthentication, stored, isDraftMedia, + isFavorite, + hasCropAnalyzed, preProgressingProcess, reuploadRequestedBy, displayLimitInMilliseconds, @@ -2187,6 +2275,7 @@ class MediaFiles extends Table with TableInfo { encryptionNonce, storedFileHash, createdAt, + createdAtMonth, ]; @override String get aliasedName => _alias ?? actualTableName; @@ -2227,6 +2316,14 @@ class MediaFiles extends Table with TableInfo { DriftSqlType.int, data['${effectivePrefix}is_draft_media'], )!, + isFavorite: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}is_favorite'], + )!, + hasCropAnalyzed: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}has_crop_analyzed'], + )!, preProgressingProcess: attachedDatabase.typeMapping.read( DriftSqlType.int, data['${effectivePrefix}pre_progressing_process'], @@ -2267,6 +2364,10 @@ class MediaFiles extends Table with TableInfo { DriftSqlType.int, data['${effectivePrefix}created_at'], )!, + createdAtMonth: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}created_at_month'], + ), ); } @@ -2289,6 +2390,8 @@ class MediaFilesData extends DataClass implements Insertable { final int requiresAuthentication; final int stored; final int isDraftMedia; + final int isFavorite; + final int hasCropAnalyzed; final int? preProgressingProcess; final String? reuploadRequestedBy; final int? displayLimitInMilliseconds; @@ -2299,6 +2402,7 @@ class MediaFilesData extends DataClass implements Insertable { final i2.Uint8List? encryptionNonce; final i2.Uint8List? storedFileHash; final int createdAt; + final String? createdAtMonth; const MediaFilesData({ required this.mediaId, required this.type, @@ -2307,6 +2411,8 @@ class MediaFilesData extends DataClass implements Insertable { required this.requiresAuthentication, required this.stored, required this.isDraftMedia, + required this.isFavorite, + required this.hasCropAnalyzed, this.preProgressingProcess, this.reuploadRequestedBy, this.displayLimitInMilliseconds, @@ -2317,6 +2423,7 @@ class MediaFilesData extends DataClass implements Insertable { this.encryptionNonce, this.storedFileHash, required this.createdAt, + this.createdAtMonth, }); @override Map toColumns(bool nullToAbsent) { @@ -2332,6 +2439,8 @@ class MediaFilesData extends DataClass implements Insertable { map['requires_authentication'] = Variable(requiresAuthentication); map['stored'] = Variable(stored); map['is_draft_media'] = Variable(isDraftMedia); + map['is_favorite'] = Variable(isFavorite); + map['has_crop_analyzed'] = Variable(hasCropAnalyzed); if (!nullToAbsent || preProgressingProcess != null) { map['pre_progressing_process'] = Variable(preProgressingProcess); } @@ -2362,6 +2471,9 @@ class MediaFilesData extends DataClass implements Insertable { map['stored_file_hash'] = Variable(storedFileHash); } map['created_at'] = Variable(createdAt); + if (!nullToAbsent || createdAtMonth != null) { + map['created_at_month'] = Variable(createdAtMonth); + } return map; } @@ -2378,6 +2490,8 @@ class MediaFilesData extends DataClass implements Insertable { requiresAuthentication: Value(requiresAuthentication), stored: Value(stored), isDraftMedia: Value(isDraftMedia), + isFavorite: Value(isFavorite), + hasCropAnalyzed: Value(hasCropAnalyzed), preProgressingProcess: preProgressingProcess == null && nullToAbsent ? const Value.absent() : Value(preProgressingProcess), @@ -2407,6 +2521,9 @@ class MediaFilesData extends DataClass implements Insertable { ? const Value.absent() : Value(storedFileHash), createdAt: Value(createdAt), + createdAtMonth: createdAtMonth == null && nullToAbsent + ? const Value.absent() + : Value(createdAtMonth), ); } @@ -2425,6 +2542,8 @@ class MediaFilesData extends DataClass implements Insertable { ), stored: serializer.fromJson(json['stored']), isDraftMedia: serializer.fromJson(json['isDraftMedia']), + isFavorite: serializer.fromJson(json['isFavorite']), + hasCropAnalyzed: serializer.fromJson(json['hasCropAnalyzed']), preProgressingProcess: serializer.fromJson( json['preProgressingProcess'], ), @@ -2445,6 +2564,7 @@ class MediaFilesData extends DataClass implements Insertable { json['storedFileHash'], ), createdAt: serializer.fromJson(json['createdAt']), + createdAtMonth: serializer.fromJson(json['createdAtMonth']), ); } @override @@ -2458,6 +2578,8 @@ class MediaFilesData extends DataClass implements Insertable { 'requiresAuthentication': serializer.toJson(requiresAuthentication), 'stored': serializer.toJson(stored), 'isDraftMedia': serializer.toJson(isDraftMedia), + 'isFavorite': serializer.toJson(isFavorite), + 'hasCropAnalyzed': serializer.toJson(hasCropAnalyzed), 'preProgressingProcess': serializer.toJson(preProgressingProcess), 'reuploadRequestedBy': serializer.toJson(reuploadRequestedBy), 'displayLimitInMilliseconds': serializer.toJson( @@ -2470,6 +2592,7 @@ class MediaFilesData extends DataClass implements Insertable { 'encryptionNonce': serializer.toJson(encryptionNonce), 'storedFileHash': serializer.toJson(storedFileHash), 'createdAt': serializer.toJson(createdAt), + 'createdAtMonth': serializer.toJson(createdAtMonth), }; } @@ -2481,6 +2604,8 @@ class MediaFilesData extends DataClass implements Insertable { int? requiresAuthentication, int? stored, int? isDraftMedia, + int? isFavorite, + int? hasCropAnalyzed, Value preProgressingProcess = const Value.absent(), Value reuploadRequestedBy = const Value.absent(), Value displayLimitInMilliseconds = const Value.absent(), @@ -2491,6 +2616,7 @@ class MediaFilesData extends DataClass implements Insertable { Value encryptionNonce = const Value.absent(), Value storedFileHash = const Value.absent(), int? createdAt, + Value createdAtMonth = const Value.absent(), }) => MediaFilesData( mediaId: mediaId ?? this.mediaId, type: type ?? this.type, @@ -2502,6 +2628,8 @@ class MediaFilesData extends DataClass implements Insertable { requiresAuthentication ?? this.requiresAuthentication, stored: stored ?? this.stored, isDraftMedia: isDraftMedia ?? this.isDraftMedia, + isFavorite: isFavorite ?? this.isFavorite, + hasCropAnalyzed: hasCropAnalyzed ?? this.hasCropAnalyzed, preProgressingProcess: preProgressingProcess.present ? preProgressingProcess.value : this.preProgressingProcess, @@ -2528,6 +2656,9 @@ class MediaFilesData extends DataClass implements Insertable { ? storedFileHash.value : this.storedFileHash, createdAt: createdAt ?? this.createdAt, + createdAtMonth: createdAtMonth.present + ? createdAtMonth.value + : this.createdAtMonth, ); MediaFilesData copyWithCompanion(MediaFilesCompanion data) { return MediaFilesData( @@ -2546,6 +2677,12 @@ class MediaFilesData extends DataClass implements Insertable { isDraftMedia: data.isDraftMedia.present ? data.isDraftMedia.value : this.isDraftMedia, + isFavorite: data.isFavorite.present + ? data.isFavorite.value + : this.isFavorite, + hasCropAnalyzed: data.hasCropAnalyzed.present + ? data.hasCropAnalyzed.value + : this.hasCropAnalyzed, preProgressingProcess: data.preProgressingProcess.present ? data.preProgressingProcess.value : this.preProgressingProcess, @@ -2574,6 +2711,9 @@ class MediaFilesData extends DataClass implements Insertable { ? data.storedFileHash.value : this.storedFileHash, createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + createdAtMonth: data.createdAtMonth.present + ? data.createdAtMonth.value + : this.createdAtMonth, ); } @@ -2587,6 +2727,8 @@ class MediaFilesData extends DataClass implements Insertable { ..write('requiresAuthentication: $requiresAuthentication, ') ..write('stored: $stored, ') ..write('isDraftMedia: $isDraftMedia, ') + ..write('isFavorite: $isFavorite, ') + ..write('hasCropAnalyzed: $hasCropAnalyzed, ') ..write('preProgressingProcess: $preProgressingProcess, ') ..write('reuploadRequestedBy: $reuploadRequestedBy, ') ..write('displayLimitInMilliseconds: $displayLimitInMilliseconds, ') @@ -2596,7 +2738,8 @@ class MediaFilesData extends DataClass implements Insertable { ..write('encryptionMac: $encryptionMac, ') ..write('encryptionNonce: $encryptionNonce, ') ..write('storedFileHash: $storedFileHash, ') - ..write('createdAt: $createdAt') + ..write('createdAt: $createdAt, ') + ..write('createdAtMonth: $createdAtMonth') ..write(')')) .toString(); } @@ -2610,6 +2753,8 @@ class MediaFilesData extends DataClass implements Insertable { requiresAuthentication, stored, isDraftMedia, + isFavorite, + hasCropAnalyzed, preProgressingProcess, reuploadRequestedBy, displayLimitInMilliseconds, @@ -2620,6 +2765,7 @@ class MediaFilesData extends DataClass implements Insertable { $driftBlobEquality.hash(encryptionNonce), $driftBlobEquality.hash(storedFileHash), createdAt, + createdAtMonth, ); @override bool operator ==(Object other) => @@ -2632,6 +2778,8 @@ class MediaFilesData extends DataClass implements Insertable { other.requiresAuthentication == this.requiresAuthentication && other.stored == this.stored && other.isDraftMedia == this.isDraftMedia && + other.isFavorite == this.isFavorite && + other.hasCropAnalyzed == this.hasCropAnalyzed && other.preProgressingProcess == this.preProgressingProcess && other.reuploadRequestedBy == this.reuploadRequestedBy && other.displayLimitInMilliseconds == this.displayLimitInMilliseconds && @@ -2647,7 +2795,8 @@ class MediaFilesData extends DataClass implements Insertable { other.storedFileHash, this.storedFileHash, ) && - other.createdAt == this.createdAt); + other.createdAt == this.createdAt && + other.createdAtMonth == this.createdAtMonth); } class MediaFilesCompanion extends UpdateCompanion { @@ -2658,6 +2807,8 @@ class MediaFilesCompanion extends UpdateCompanion { final Value requiresAuthentication; final Value stored; final Value isDraftMedia; + final Value isFavorite; + final Value hasCropAnalyzed; final Value preProgressingProcess; final Value reuploadRequestedBy; final Value displayLimitInMilliseconds; @@ -2668,6 +2819,7 @@ class MediaFilesCompanion extends UpdateCompanion { final Value encryptionNonce; final Value storedFileHash; final Value createdAt; + final Value createdAtMonth; final Value rowid; const MediaFilesCompanion({ this.mediaId = const Value.absent(), @@ -2677,6 +2829,8 @@ class MediaFilesCompanion extends UpdateCompanion { this.requiresAuthentication = const Value.absent(), this.stored = const Value.absent(), this.isDraftMedia = const Value.absent(), + this.isFavorite = const Value.absent(), + this.hasCropAnalyzed = const Value.absent(), this.preProgressingProcess = const Value.absent(), this.reuploadRequestedBy = const Value.absent(), this.displayLimitInMilliseconds = const Value.absent(), @@ -2687,6 +2841,7 @@ class MediaFilesCompanion extends UpdateCompanion { this.encryptionNonce = const Value.absent(), this.storedFileHash = const Value.absent(), this.createdAt = const Value.absent(), + this.createdAtMonth = const Value.absent(), this.rowid = const Value.absent(), }); MediaFilesCompanion.insert({ @@ -2697,6 +2852,8 @@ class MediaFilesCompanion extends UpdateCompanion { this.requiresAuthentication = const Value.absent(), this.stored = const Value.absent(), this.isDraftMedia = const Value.absent(), + this.isFavorite = const Value.absent(), + this.hasCropAnalyzed = const Value.absent(), this.preProgressingProcess = const Value.absent(), this.reuploadRequestedBy = const Value.absent(), this.displayLimitInMilliseconds = const Value.absent(), @@ -2707,6 +2864,7 @@ class MediaFilesCompanion extends UpdateCompanion { this.encryptionNonce = const Value.absent(), this.storedFileHash = const Value.absent(), this.createdAt = const Value.absent(), + this.createdAtMonth = const Value.absent(), this.rowid = const Value.absent(), }) : mediaId = Value(mediaId), type = Value(type); @@ -2718,6 +2876,8 @@ class MediaFilesCompanion extends UpdateCompanion { Expression? requiresAuthentication, Expression? stored, Expression? isDraftMedia, + Expression? isFavorite, + Expression? hasCropAnalyzed, Expression? preProgressingProcess, Expression? reuploadRequestedBy, Expression? displayLimitInMilliseconds, @@ -2728,6 +2888,7 @@ class MediaFilesCompanion extends UpdateCompanion { Expression? encryptionNonce, Expression? storedFileHash, Expression? createdAt, + Expression? createdAtMonth, Expression? rowid, }) { return RawValuesInsertable({ @@ -2739,6 +2900,8 @@ class MediaFilesCompanion extends UpdateCompanion { 'requires_authentication': requiresAuthentication, if (stored != null) 'stored': stored, if (isDraftMedia != null) 'is_draft_media': isDraftMedia, + if (isFavorite != null) 'is_favorite': isFavorite, + if (hasCropAnalyzed != null) 'has_crop_analyzed': hasCropAnalyzed, if (preProgressingProcess != null) 'pre_progressing_process': preProgressingProcess, if (reuploadRequestedBy != null) @@ -2752,6 +2915,7 @@ class MediaFilesCompanion extends UpdateCompanion { if (encryptionNonce != null) 'encryption_nonce': encryptionNonce, if (storedFileHash != null) 'stored_file_hash': storedFileHash, if (createdAt != null) 'created_at': createdAt, + if (createdAtMonth != null) 'created_at_month': createdAtMonth, if (rowid != null) 'rowid': rowid, }); } @@ -2764,6 +2928,8 @@ class MediaFilesCompanion extends UpdateCompanion { Value? requiresAuthentication, Value? stored, Value? isDraftMedia, + Value? isFavorite, + Value? hasCropAnalyzed, Value? preProgressingProcess, Value? reuploadRequestedBy, Value? displayLimitInMilliseconds, @@ -2774,6 +2940,7 @@ class MediaFilesCompanion extends UpdateCompanion { Value? encryptionNonce, Value? storedFileHash, Value? createdAt, + Value? createdAtMonth, Value? rowid, }) { return MediaFilesCompanion( @@ -2785,6 +2952,8 @@ class MediaFilesCompanion extends UpdateCompanion { requiresAuthentication ?? this.requiresAuthentication, stored: stored ?? this.stored, isDraftMedia: isDraftMedia ?? this.isDraftMedia, + isFavorite: isFavorite ?? this.isFavorite, + hasCropAnalyzed: hasCropAnalyzed ?? this.hasCropAnalyzed, preProgressingProcess: preProgressingProcess ?? this.preProgressingProcess, reuploadRequestedBy: reuploadRequestedBy ?? this.reuploadRequestedBy, @@ -2797,6 +2966,7 @@ class MediaFilesCompanion extends UpdateCompanion { encryptionNonce: encryptionNonce ?? this.encryptionNonce, storedFileHash: storedFileHash ?? this.storedFileHash, createdAt: createdAt ?? this.createdAt, + createdAtMonth: createdAtMonth ?? this.createdAtMonth, rowid: rowid ?? this.rowid, ); } @@ -2827,6 +2997,12 @@ class MediaFilesCompanion extends UpdateCompanion { if (isDraftMedia.present) { map['is_draft_media'] = Variable(isDraftMedia.value); } + if (isFavorite.present) { + map['is_favorite'] = Variable(isFavorite.value); + } + if (hasCropAnalyzed.present) { + map['has_crop_analyzed'] = Variable(hasCropAnalyzed.value); + } if (preProgressingProcess.present) { map['pre_progressing_process'] = Variable( preProgressingProcess.value, @@ -2863,6 +3039,9 @@ class MediaFilesCompanion extends UpdateCompanion { if (createdAt.present) { map['created_at'] = Variable(createdAt.value); } + if (createdAtMonth.present) { + map['created_at_month'] = Variable(createdAtMonth.value); + } if (rowid.present) { map['rowid'] = Variable(rowid.value); } @@ -2879,6 +3058,8 @@ class MediaFilesCompanion extends UpdateCompanion { ..write('requiresAuthentication: $requiresAuthentication, ') ..write('stored: $stored, ') ..write('isDraftMedia: $isDraftMedia, ') + ..write('isFavorite: $isFavorite, ') + ..write('hasCropAnalyzed: $hasCropAnalyzed, ') ..write('preProgressingProcess: $preProgressingProcess, ') ..write('reuploadRequestedBy: $reuploadRequestedBy, ') ..write('displayLimitInMilliseconds: $displayLimitInMilliseconds, ') @@ -2889,6 +3070,7 @@ class MediaFilesCompanion extends UpdateCompanion { ..write('encryptionNonce: $encryptionNonce, ') ..write('storedFileHash: $storedFileHash, ') ..write('createdAt: $createdAt, ') + ..write('createdAtMonth: $createdAtMonth, ') ..write('rowid: $rowid') ..write(')')) .toString(); @@ -6666,6 +6848,250 @@ class SignalSessionStoresCompanion } } +class SignalSignedPreKeyStores extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + SignalSignedPreKeyStores(this.attachedDatabase, [this._alias]); + late final GeneratedColumn signedPreKeyId = GeneratedColumn( + 'signed_pre_key_id', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn signedPreKey = + GeneratedColumn( + 'signed_pre_key', + aliasedName, + false, + type: DriftSqlType.blob, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL', + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: + 'NOT NULL DEFAULT (CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER))', + defaultValue: const CustomExpression( + 'CAST(strftime(\'%s\', CURRENT_TIMESTAMP) AS INTEGER)', + ), + ); + @override + List get $columns => [ + signedPreKeyId, + signedPreKey, + createdAt, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'signal_signed_pre_key_stores'; + @override + Set get $primaryKey => {signedPreKeyId}; + @override + SignalSignedPreKeyStoresData map( + Map data, { + String? tablePrefix, + }) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return SignalSignedPreKeyStoresData( + signedPreKeyId: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}signed_pre_key_id'], + )!, + signedPreKey: attachedDatabase.typeMapping.read( + DriftSqlType.blob, + data['${effectivePrefix}signed_pre_key'], + )!, + createdAt: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}created_at'], + )!, + ); + } + + @override + SignalSignedPreKeyStores createAlias(String alias) { + return SignalSignedPreKeyStores(attachedDatabase, alias); + } + + @override + List get customConstraints => const [ + 'PRIMARY KEY(signed_pre_key_id)', + ]; + @override + bool get dontWriteConstraints => true; +} + +class SignalSignedPreKeyStoresData extends DataClass + implements Insertable { + final int signedPreKeyId; + final i2.Uint8List signedPreKey; + final int createdAt; + const SignalSignedPreKeyStoresData({ + required this.signedPreKeyId, + required this.signedPreKey, + required this.createdAt, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['signed_pre_key_id'] = Variable(signedPreKeyId); + map['signed_pre_key'] = Variable(signedPreKey); + map['created_at'] = Variable(createdAt); + return map; + } + + SignalSignedPreKeyStoresCompanion toCompanion(bool nullToAbsent) { + return SignalSignedPreKeyStoresCompanion( + signedPreKeyId: Value(signedPreKeyId), + signedPreKey: Value(signedPreKey), + createdAt: Value(createdAt), + ); + } + + factory SignalSignedPreKeyStoresData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return SignalSignedPreKeyStoresData( + signedPreKeyId: serializer.fromJson(json['signedPreKeyId']), + signedPreKey: serializer.fromJson(json['signedPreKey']), + createdAt: serializer.fromJson(json['createdAt']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'signedPreKeyId': serializer.toJson(signedPreKeyId), + 'signedPreKey': serializer.toJson(signedPreKey), + 'createdAt': serializer.toJson(createdAt), + }; + } + + SignalSignedPreKeyStoresData copyWith({ + int? signedPreKeyId, + i2.Uint8List? signedPreKey, + int? createdAt, + }) => SignalSignedPreKeyStoresData( + signedPreKeyId: signedPreKeyId ?? this.signedPreKeyId, + signedPreKey: signedPreKey ?? this.signedPreKey, + createdAt: createdAt ?? this.createdAt, + ); + SignalSignedPreKeyStoresData copyWithCompanion( + SignalSignedPreKeyStoresCompanion data, + ) { + return SignalSignedPreKeyStoresData( + signedPreKeyId: data.signedPreKeyId.present + ? data.signedPreKeyId.value + : this.signedPreKeyId, + signedPreKey: data.signedPreKey.present + ? data.signedPreKey.value + : this.signedPreKey, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + ); + } + + @override + String toString() { + return (StringBuffer('SignalSignedPreKeyStoresData(') + ..write('signedPreKeyId: $signedPreKeyId, ') + ..write('signedPreKey: $signedPreKey, ') + ..write('createdAt: $createdAt') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + signedPreKeyId, + $driftBlobEquality.hash(signedPreKey), + createdAt, + ); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is SignalSignedPreKeyStoresData && + other.signedPreKeyId == this.signedPreKeyId && + $driftBlobEquality.equals(other.signedPreKey, this.signedPreKey) && + other.createdAt == this.createdAt); +} + +class SignalSignedPreKeyStoresCompanion + extends UpdateCompanion { + final Value signedPreKeyId; + final Value signedPreKey; + final Value createdAt; + const SignalSignedPreKeyStoresCompanion({ + this.signedPreKeyId = const Value.absent(), + this.signedPreKey = const Value.absent(), + this.createdAt = const Value.absent(), + }); + SignalSignedPreKeyStoresCompanion.insert({ + this.signedPreKeyId = const Value.absent(), + required i2.Uint8List signedPreKey, + this.createdAt = const Value.absent(), + }) : signedPreKey = Value(signedPreKey); + static Insertable custom({ + Expression? signedPreKeyId, + Expression? signedPreKey, + Expression? createdAt, + }) { + return RawValuesInsertable({ + if (signedPreKeyId != null) 'signed_pre_key_id': signedPreKeyId, + if (signedPreKey != null) 'signed_pre_key': signedPreKey, + if (createdAt != null) 'created_at': createdAt, + }); + } + + SignalSignedPreKeyStoresCompanion copyWith({ + Value? signedPreKeyId, + Value? signedPreKey, + Value? createdAt, + }) { + return SignalSignedPreKeyStoresCompanion( + signedPreKeyId: signedPreKeyId ?? this.signedPreKeyId, + signedPreKey: signedPreKey ?? this.signedPreKey, + createdAt: createdAt ?? this.createdAt, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (signedPreKeyId.present) { + map['signed_pre_key_id'] = Variable(signedPreKeyId.value); + } + if (signedPreKey.present) { + map['signed_pre_key'] = Variable(signedPreKey.value); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('SignalSignedPreKeyStoresCompanion(') + ..write('signedPreKeyId: $signedPreKeyId, ') + ..write('signedPreKey: $signedPreKey, ') + ..write('createdAt: $createdAt') + ..write(')')) + .toString(); + } +} + class MessageActions extends Table with TableInfo { @override @@ -7462,12 +7888,21 @@ class KeyVerifications extends Table final GeneratedDatabase attachedDatabase; final String? _alias; KeyVerifications(this.attachedDatabase, [this._alias]); + late final GeneratedColumn verificationId = GeneratedColumn( + 'verification_id', + aliasedName, + false, + hasAutoIncrement: true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL PRIMARY KEY AUTOINCREMENT', + ); late final GeneratedColumn contactId = GeneratedColumn( 'contact_id', aliasedName, false, type: DriftSqlType.int, - requiredDuringInsert: false, + requiredDuringInsert: true, $customConstraints: 'NOT NULL REFERENCES contacts(user_id)ON DELETE CASCADE', ); @@ -7492,18 +7927,27 @@ class KeyVerifications extends Table ), ); @override - List get $columns => [contactId, type, createdAt]; + List get $columns => [ + verificationId, + contactId, + type, + createdAt, + ]; @override String get aliasedName => _alias ?? actualTableName; @override String get actualTableName => $name; static const String $name = 'key_verifications'; @override - Set get $primaryKey => {contactId}; + Set get $primaryKey => {verificationId}; @override KeyVerificationsData map(Map data, {String? tablePrefix}) { final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; return KeyVerificationsData( + verificationId: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}verification_id'], + )!, contactId: attachedDatabase.typeMapping.read( DriftSqlType.int, data['${effectivePrefix}contact_id'], @@ -7524,18 +7968,18 @@ class KeyVerifications extends Table return KeyVerifications(attachedDatabase, alias); } - @override - List get customConstraints => const ['PRIMARY KEY(contact_id)']; @override bool get dontWriteConstraints => true; } class KeyVerificationsData extends DataClass implements Insertable { + final int verificationId; final int contactId; final String type; final int createdAt; const KeyVerificationsData({ + required this.verificationId, required this.contactId, required this.type, required this.createdAt, @@ -7543,6 +7987,7 @@ class KeyVerificationsData extends DataClass @override Map toColumns(bool nullToAbsent) { final map = {}; + map['verification_id'] = Variable(verificationId); map['contact_id'] = Variable(contactId); map['type'] = Variable(type); map['created_at'] = Variable(createdAt); @@ -7551,6 +7996,7 @@ class KeyVerificationsData extends DataClass KeyVerificationsCompanion toCompanion(bool nullToAbsent) { return KeyVerificationsCompanion( + verificationId: Value(verificationId), contactId: Value(contactId), type: Value(type), createdAt: Value(createdAt), @@ -7563,6 +8009,7 @@ class KeyVerificationsData extends DataClass }) { serializer ??= driftRuntimeOptions.defaultSerializer; return KeyVerificationsData( + verificationId: serializer.fromJson(json['verificationId']), contactId: serializer.fromJson(json['contactId']), type: serializer.fromJson(json['type']), createdAt: serializer.fromJson(json['createdAt']), @@ -7572,6 +8019,7 @@ class KeyVerificationsData extends DataClass Map toJson({ValueSerializer? serializer}) { serializer ??= driftRuntimeOptions.defaultSerializer; return { + 'verificationId': serializer.toJson(verificationId), 'contactId': serializer.toJson(contactId), 'type': serializer.toJson(type), 'createdAt': serializer.toJson(createdAt), @@ -7579,16 +8027,21 @@ class KeyVerificationsData extends DataClass } KeyVerificationsData copyWith({ + int? verificationId, int? contactId, String? type, int? createdAt, }) => KeyVerificationsData( + verificationId: verificationId ?? this.verificationId, contactId: contactId ?? this.contactId, type: type ?? this.type, createdAt: createdAt ?? this.createdAt, ); KeyVerificationsData copyWithCompanion(KeyVerificationsCompanion data) { return KeyVerificationsData( + verificationId: data.verificationId.present + ? data.verificationId.value + : this.verificationId, contactId: data.contactId.present ? data.contactId.value : this.contactId, type: data.type.present ? data.type.value : this.type, createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, @@ -7598,6 +8051,7 @@ class KeyVerificationsData extends DataClass @override String toString() { return (StringBuffer('KeyVerificationsData(') + ..write('verificationId: $verificationId, ') ..write('contactId: $contactId, ') ..write('type: $type, ') ..write('createdAt: $createdAt') @@ -7606,36 +8060,43 @@ class KeyVerificationsData extends DataClass } @override - int get hashCode => Object.hash(contactId, type, createdAt); + int get hashCode => Object.hash(verificationId, contactId, type, createdAt); @override bool operator ==(Object other) => identical(this, other) || (other is KeyVerificationsData && + other.verificationId == this.verificationId && other.contactId == this.contactId && other.type == this.type && other.createdAt == this.createdAt); } class KeyVerificationsCompanion extends UpdateCompanion { + final Value verificationId; final Value contactId; final Value type; final Value createdAt; const KeyVerificationsCompanion({ + this.verificationId = const Value.absent(), this.contactId = const Value.absent(), this.type = const Value.absent(), this.createdAt = const Value.absent(), }); KeyVerificationsCompanion.insert({ - this.contactId = const Value.absent(), + this.verificationId = const Value.absent(), + required int contactId, required String type, this.createdAt = const Value.absent(), - }) : type = Value(type); + }) : contactId = Value(contactId), + type = Value(type); static Insertable custom({ + Expression? verificationId, Expression? contactId, Expression? type, Expression? createdAt, }) { return RawValuesInsertable({ + if (verificationId != null) 'verification_id': verificationId, if (contactId != null) 'contact_id': contactId, if (type != null) 'type': type, if (createdAt != null) 'created_at': createdAt, @@ -7643,11 +8104,13 @@ class KeyVerificationsCompanion extends UpdateCompanion { } KeyVerificationsCompanion copyWith({ + Value? verificationId, Value? contactId, Value? type, Value? createdAt, }) { return KeyVerificationsCompanion( + verificationId: verificationId ?? this.verificationId, contactId: contactId ?? this.contactId, type: type ?? this.type, createdAt: createdAt ?? this.createdAt, @@ -7657,6 +8120,9 @@ class KeyVerificationsCompanion extends UpdateCompanion { @override Map toColumns(bool nullToAbsent) { final map = {}; + if (verificationId.present) { + map['verification_id'] = Variable(verificationId.value); + } if (contactId.present) { map['contact_id'] = Variable(contactId.value); } @@ -7672,6 +8138,7 @@ class KeyVerificationsCompanion extends UpdateCompanion { @override String toString() { return (StringBuffer('KeyVerificationsCompanion(') + ..write('verificationId: $verificationId, ') ..write('contactId: $contactId, ') ..write('type: $type, ') ..write('createdAt: $createdAt') @@ -8621,7 +9088,7 @@ class UserDiscoveryOtherPromotions extends Table String get actualTableName => $name; static const String $name = 'user_discovery_other_promotions'; @override - Set get $primaryKey => {fromContactId, promotionId}; + Set get $primaryKey => {fromContactId, publicId}; @override UserDiscoveryOtherPromotionsData map( Map data, { @@ -8663,7 +9130,7 @@ class UserDiscoveryOtherPromotions extends Table @override List get customConstraints => const [ - 'PRIMARY KEY(from_contact_id, promotion_id)', + 'PRIMARY KEY(from_contact_id, public_id)', ]; @override bool get dontWriteConstraints => true; @@ -9398,6 +9865,419 @@ class UserDiscoverySharesCompanion } } +class Shortcuts extends Table with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + Shortcuts(this.attachedDatabase, [this._alias]); + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + hasAutoIncrement: true, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL PRIMARY KEY AUTOINCREMENT', + ); + late final GeneratedColumn emoji = GeneratedColumn( + 'emoji', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL UNIQUE', + ); + late final GeneratedColumn usageCounter = GeneratedColumn( + 'usage_counter', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + $customConstraints: 'NOT NULL DEFAULT 0', + defaultValue: const CustomExpression('0'), + ); + @override + List get $columns => [id, emoji, usageCounter]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'shortcuts'; + @override + Set get $primaryKey => {id}; + @override + ShortcutsData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return ShortcutsData( + id: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}id'], + )!, + emoji: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}emoji'], + )!, + usageCounter: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}usage_counter'], + )!, + ); + } + + @override + Shortcuts createAlias(String alias) { + return Shortcuts(attachedDatabase, alias); + } + + @override + bool get dontWriteConstraints => true; +} + +class ShortcutsData extends DataClass implements Insertable { + final int id; + final String emoji; + final int usageCounter; + const ShortcutsData({ + required this.id, + required this.emoji, + required this.usageCounter, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + map['emoji'] = Variable(emoji); + map['usage_counter'] = Variable(usageCounter); + return map; + } + + ShortcutsCompanion toCompanion(bool nullToAbsent) { + return ShortcutsCompanion( + id: Value(id), + emoji: Value(emoji), + usageCounter: Value(usageCounter), + ); + } + + factory ShortcutsData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return ShortcutsData( + id: serializer.fromJson(json['id']), + emoji: serializer.fromJson(json['emoji']), + usageCounter: serializer.fromJson(json['usageCounter']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'emoji': serializer.toJson(emoji), + 'usageCounter': serializer.toJson(usageCounter), + }; + } + + ShortcutsData copyWith({int? id, String? emoji, int? usageCounter}) => + ShortcutsData( + id: id ?? this.id, + emoji: emoji ?? this.emoji, + usageCounter: usageCounter ?? this.usageCounter, + ); + ShortcutsData copyWithCompanion(ShortcutsCompanion data) { + return ShortcutsData( + id: data.id.present ? data.id.value : this.id, + emoji: data.emoji.present ? data.emoji.value : this.emoji, + usageCounter: data.usageCounter.present + ? data.usageCounter.value + : this.usageCounter, + ); + } + + @override + String toString() { + return (StringBuffer('ShortcutsData(') + ..write('id: $id, ') + ..write('emoji: $emoji, ') + ..write('usageCounter: $usageCounter') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(id, emoji, usageCounter); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is ShortcutsData && + other.id == this.id && + other.emoji == this.emoji && + other.usageCounter == this.usageCounter); +} + +class ShortcutsCompanion extends UpdateCompanion { + final Value id; + final Value emoji; + final Value usageCounter; + const ShortcutsCompanion({ + this.id = const Value.absent(), + this.emoji = const Value.absent(), + this.usageCounter = const Value.absent(), + }); + ShortcutsCompanion.insert({ + this.id = const Value.absent(), + required String emoji, + this.usageCounter = const Value.absent(), + }) : emoji = Value(emoji); + static Insertable custom({ + Expression? id, + Expression? emoji, + Expression? usageCounter, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (emoji != null) 'emoji': emoji, + if (usageCounter != null) 'usage_counter': usageCounter, + }); + } + + ShortcutsCompanion copyWith({ + Value? id, + Value? emoji, + Value? usageCounter, + }) { + return ShortcutsCompanion( + id: id ?? this.id, + emoji: emoji ?? this.emoji, + usageCounter: usageCounter ?? this.usageCounter, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (emoji.present) { + map['emoji'] = Variable(emoji.value); + } + if (usageCounter.present) { + map['usage_counter'] = Variable(usageCounter.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('ShortcutsCompanion(') + ..write('id: $id, ') + ..write('emoji: $emoji, ') + ..write('usageCounter: $usageCounter') + ..write(')')) + .toString(); + } +} + +class ShortcutMembers extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + ShortcutMembers(this.attachedDatabase, [this._alias]); + late final GeneratedColumn shortcutId = GeneratedColumn( + 'shortcut_id', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + $customConstraints: 'NOT NULL REFERENCES shortcuts(id)ON DELETE CASCADE', + ); + late final GeneratedColumn groupId = GeneratedColumn( + 'group_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + $customConstraints: + 'NOT NULL REFERENCES "groups"(group_id)ON DELETE CASCADE', + ); + @override + List get $columns => [shortcutId, groupId]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'shortcut_members'; + @override + Set get $primaryKey => {shortcutId, groupId}; + @override + ShortcutMembersData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return ShortcutMembersData( + shortcutId: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}shortcut_id'], + )!, + groupId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}group_id'], + )!, + ); + } + + @override + ShortcutMembers createAlias(String alias) { + return ShortcutMembers(attachedDatabase, alias); + } + + @override + List get customConstraints => const [ + 'PRIMARY KEY(shortcut_id, group_id)', + ]; + @override + bool get dontWriteConstraints => true; +} + +class ShortcutMembersData extends DataClass + implements Insertable { + final int shortcutId; + final String groupId; + const ShortcutMembersData({required this.shortcutId, required this.groupId}); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['shortcut_id'] = Variable(shortcutId); + map['group_id'] = Variable(groupId); + return map; + } + + ShortcutMembersCompanion toCompanion(bool nullToAbsent) { + return ShortcutMembersCompanion( + shortcutId: Value(shortcutId), + groupId: Value(groupId), + ); + } + + factory ShortcutMembersData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return ShortcutMembersData( + shortcutId: serializer.fromJson(json['shortcutId']), + groupId: serializer.fromJson(json['groupId']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'shortcutId': serializer.toJson(shortcutId), + 'groupId': serializer.toJson(groupId), + }; + } + + ShortcutMembersData copyWith({int? shortcutId, String? groupId}) => + ShortcutMembersData( + shortcutId: shortcutId ?? this.shortcutId, + groupId: groupId ?? this.groupId, + ); + ShortcutMembersData copyWithCompanion(ShortcutMembersCompanion data) { + return ShortcutMembersData( + shortcutId: data.shortcutId.present + ? data.shortcutId.value + : this.shortcutId, + groupId: data.groupId.present ? data.groupId.value : this.groupId, + ); + } + + @override + String toString() { + return (StringBuffer('ShortcutMembersData(') + ..write('shortcutId: $shortcutId, ') + ..write('groupId: $groupId') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(shortcutId, groupId); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is ShortcutMembersData && + other.shortcutId == this.shortcutId && + other.groupId == this.groupId); +} + +class ShortcutMembersCompanion extends UpdateCompanion { + final Value shortcutId; + final Value groupId; + final Value rowid; + const ShortcutMembersCompanion({ + this.shortcutId = const Value.absent(), + this.groupId = const Value.absent(), + this.rowid = const Value.absent(), + }); + ShortcutMembersCompanion.insert({ + required int shortcutId, + required String groupId, + this.rowid = const Value.absent(), + }) : shortcutId = Value(shortcutId), + groupId = Value(groupId); + static Insertable custom({ + Expression? shortcutId, + Expression? groupId, + Expression? rowid, + }) { + return RawValuesInsertable({ + if (shortcutId != null) 'shortcut_id': shortcutId, + if (groupId != null) 'group_id': groupId, + if (rowid != null) 'rowid': rowid, + }); + } + + ShortcutMembersCompanion copyWith({ + Value? shortcutId, + Value? groupId, + Value? rowid, + }) { + return ShortcutMembersCompanion( + shortcutId: shortcutId ?? this.shortcutId, + groupId: groupId ?? this.groupId, + rowid: rowid ?? this.rowid, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (shortcutId.present) { + map['shortcut_id'] = Variable(shortcutId.value); + } + if (groupId.present) { + map['group_id'] = Variable(groupId.value); + } + if (rowid.present) { + map['rowid'] = Variable(rowid.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('ShortcutMembersCompanion(') + ..write('shortcutId: $shortcutId, ') + ..write('groupId: $groupId, ') + ..write('rowid: $rowid') + ..write(')')) + .toString(); + } +} + class DatabaseAtV15 extends GeneratedDatabase { DatabaseAtV15(QueryExecutor e) : super(e); late final Contacts contacts = Contacts(this); @@ -9417,6 +10297,8 @@ class DatabaseAtV15 extends GeneratedDatabase { late final SignalSessionStores signalSessionStores = SignalSessionStores( this, ); + late final SignalSignedPreKeyStores signalSignedPreKeyStores = + SignalSignedPreKeyStores(this); late final MessageActions messageActions = MessageActions(this); late final GroupHistories groupHistories = GroupHistories(this); late final KeyVerifications keyVerifications = KeyVerifications(this); @@ -9432,6 +10314,8 @@ class DatabaseAtV15 extends GeneratedDatabase { late final UserDiscoveryShares userDiscoveryShares = UserDiscoveryShares( this, ); + late final Shortcuts shortcuts = Shortcuts(this); + late final ShortcutMembers shortcutMembers = ShortcutMembers(this); @override Iterable> get allTables => allSchemaEntities.whereType>(); @@ -9450,6 +10334,7 @@ class DatabaseAtV15 extends GeneratedDatabase { signalPreKeyStores, signalSenderKeyStores, signalSessionStores, + signalSignedPreKeyStores, messageActions, groupHistories, keyVerifications, @@ -9459,6 +10344,8 @@ class DatabaseAtV15 extends GeneratedDatabase { userDiscoveryOtherPromotions, userDiscoveryOwnPromotions, userDiscoveryShares, + shortcuts, + shortcutMembers, ]; @override StreamQueryUpdateRules get streamUpdateRules => const StreamQueryUpdateRules([ @@ -9596,6 +10483,20 @@ class DatabaseAtV15 extends GeneratedDatabase { ), result: [TableUpdate('user_discovery_shares', kind: UpdateKind.delete)], ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'shortcuts', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('shortcut_members', kind: UpdateKind.delete)], + ), + WritePropagation( + on: TableUpdateQuery.onTableName( + 'groups', + limitUpdateKind: UpdateKind.delete, + ), + result: [TableUpdate('shortcut_members', kind: UpdateKind.delete)], + ), ]); @override int get schemaVersion => 15;