Search in sources :

Example 31 with SQLiteCursor

use of org.telegram.SQLite.SQLiteCursor in project Telegram-FOSS by Telegram-FOSS-Team.

the class MessagesStorage method loadDialogsByIds.

private TLRPC.messages_Dialogs loadDialogsByIds(String ids, ArrayList<Long> usersToLoad, ArrayList<Long> chatsToLoad, ArrayList<Integer> encryptedToLoad) throws Exception {
    TLRPC.messages_Dialogs dialogs = new TLRPC.TL_messages_dialogs();
    LongSparseArray<TLRPC.Message> replyMessageOwners = new LongSparseArray<>();
    SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT d.did, d.last_mid, d.unread_count, d.date, m.data, m.read_state, m.mid, m.send_state, s.flags, m.date, d.pts, d.inbox_max, d.outbox_max, m.replydata, d.pinned, d.unread_count_i, d.flags, d.folder_id, d.data, d.unread_reactions FROM dialogs as d LEFT JOIN messages_v2 as m ON d.last_mid = m.mid AND d.did = m.uid LEFT JOIN dialog_settings as s ON d.did = s.did WHERE d.did IN (%s) ORDER BY d.pinned DESC, d.date DESC", ids));
    while (cursor.next()) {
        long dialogId = cursor.longValue(0);
        TLRPC.Dialog dialog = new TLRPC.TL_dialog();
        dialog.id = dialogId;
        dialog.top_message = cursor.intValue(1);
        dialog.unread_count = cursor.intValue(2);
        dialog.last_message_date = cursor.intValue(3);
        dialog.pts = cursor.intValue(10);
        dialog.flags = dialog.pts == 0 || DialogObject.isUserDialog(dialog.id) ? 0 : 1;
        dialog.read_inbox_max_id = cursor.intValue(11);
        dialog.read_outbox_max_id = cursor.intValue(12);
        dialog.pinnedNum = cursor.intValue(14);
        dialog.pinned = dialog.pinnedNum != 0;
        dialog.unread_mentions_count = cursor.intValue(15);
        int dialog_flags = cursor.intValue(16);
        dialog.unread_mark = (dialog_flags & 1) != 0;
        long flags = cursor.longValue(8);
        int low_flags = (int) flags;
        dialog.notify_settings = new TLRPC.TL_peerNotifySettings();
        if ((low_flags & 1) != 0) {
            dialog.notify_settings.mute_until = (int) (flags >> 32);
            if (dialog.notify_settings.mute_until == 0) {
                dialog.notify_settings.mute_until = Integer.MAX_VALUE;
            }
        }
        dialog.folder_id = cursor.intValue(17);
        dialog.unread_reactions_count = cursor.intValue(19);
        dialogs.dialogs.add(dialog);
        NativeByteBuffer data = cursor.byteBufferValue(4);
        if (data != null) {
            TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
            if (message != null) {
                message.readAttachPath(data, getUserConfig().clientUserId);
                data.reuse();
                MessageObject.setUnreadFlags(message, cursor.intValue(5));
                message.id = cursor.intValue(6);
                int date = cursor.intValue(9);
                if (date != 0) {
                    dialog.last_message_date = date;
                }
                message.send_state = cursor.intValue(7);
                message.dialog_id = dialog.id;
                dialogs.messages.add(message);
                addUsersAndChatsFromMessage(message, usersToLoad, chatsToLoad);
                try {
                    if (message.reply_to != null && message.reply_to.reply_to_msg_id != 0 && (message.action instanceof TLRPC.TL_messageActionPinMessage || message.action instanceof TLRPC.TL_messageActionPaymentSent || message.action instanceof TLRPC.TL_messageActionGameScore)) {
                        if (!cursor.isNull(13)) {
                            NativeByteBuffer data2 = cursor.byteBufferValue(13);
                            if (data2 != null) {
                                message.replyMessage = TLRPC.Message.TLdeserialize(data2, data2.readInt32(false), false);
                                message.replyMessage.readAttachPath(data2, getUserConfig().clientUserId);
                                data2.reuse();
                                if (message.replyMessage != null) {
                                    addUsersAndChatsFromMessage(message.replyMessage, usersToLoad, chatsToLoad);
                                }
                            }
                        }
                        if (message.replyMessage == null) {
                            replyMessageOwners.put(dialog.id, message);
                        }
                    }
                } catch (Exception e) {
                    FileLog.e(e);
                }
            } else {
                data.reuse();
            }
        }
        if (DialogObject.isEncryptedDialog(dialogId)) {
            int encryptedChatId = DialogObject.getEncryptedChatId(dialogId);
            if (!encryptedToLoad.contains(encryptedChatId)) {
                encryptedToLoad.add(encryptedChatId);
            }
        } else if (DialogObject.isUserDialog(dialogId)) {
            if (!usersToLoad.contains(dialogId)) {
                usersToLoad.add(dialogId);
            }
        } else {
            if (!chatsToLoad.contains(-dialogId)) {
                chatsToLoad.add(-dialogId);
            }
        }
    }
    cursor.dispose();
    if (!replyMessageOwners.isEmpty()) {
        for (int a = 0, N = replyMessageOwners.size(); a < N; a++) {
            long dialogId = replyMessageOwners.keyAt(a);
            TLRPC.Message ownerMessage = replyMessageOwners.valueAt(a);
            SQLiteCursor replyCursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid, date, uid FROM messages_v2 WHERE mid = %d and uid = %d", ownerMessage.id, dialogId));
            while (replyCursor.next()) {
                NativeByteBuffer data = replyCursor.byteBufferValue(0);
                if (data != null) {
                    TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
                    message.readAttachPath(data, getUserConfig().clientUserId);
                    data.reuse();
                    message.id = replyCursor.intValue(1);
                    message.date = replyCursor.intValue(2);
                    message.dialog_id = replyCursor.longValue(3);
                    addUsersAndChatsFromMessage(message, usersToLoad, chatsToLoad);
                    ownerMessage.replyMessage = message;
                    message.dialog_id = ownerMessage.dialog_id;
                }
            }
            replyCursor.dispose();
        }
    }
    return dialogs;
}
Also used : LongSparseArray(androidx.collection.LongSparseArray) NativeByteBuffer(org.telegram.tgnet.NativeByteBuffer) TLRPC(org.telegram.tgnet.TLRPC) SQLiteCursor(org.telegram.SQLite.SQLiteCursor) SQLiteException(org.telegram.SQLite.SQLiteException)

Example 32 with SQLiteCursor

use of org.telegram.SQLite.SQLiteCursor in project Telegram-FOSS by Telegram-FOSS-Team.

the class MessagesStorage method updateChatDefaultBannedRights.

public void updateChatDefaultBannedRights(long chatId, TLRPC.TL_chatBannedRights rights, int version) {
    if (rights == null || chatId == 0) {
        return;
    }
    storageQueue.postRunnable(() -> {
        try {
            TLRPC.Chat chat = null;
            SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT data FROM chats WHERE uid = %d", chatId));
            if (cursor.next()) {
                NativeByteBuffer data = cursor.byteBufferValue(0);
                if (data != null) {
                    chat = TLRPC.Chat.TLdeserialize(data, data.readInt32(false), false);
                    data.reuse();
                }
            }
            cursor.dispose();
            if (chat == null || chat.default_banned_rights != null && version < chat.version) {
                return;
            }
            chat.default_banned_rights = rights;
            chat.flags |= 262144;
            chat.version = version;
            SQLitePreparedStatement state = database.executeFast("UPDATE chats SET data = ? WHERE uid = ?");
            NativeByteBuffer data = new NativeByteBuffer(chat.getObjectSize());
            chat.serializeToStream(data);
            state.bindByteBuffer(1, data);
            state.bindLong(2, chat.id);
            state.step();
            data.reuse();
            state.dispose();
        } catch (Exception e) {
            FileLog.e(e);
        }
    });
}
Also used : NativeByteBuffer(org.telegram.tgnet.NativeByteBuffer) TLRPC(org.telegram.tgnet.TLRPC) SQLiteCursor(org.telegram.SQLite.SQLiteCursor) SQLiteException(org.telegram.SQLite.SQLiteException) SQLitePreparedStatement(org.telegram.SQLite.SQLitePreparedStatement)

Example 33 with SQLiteCursor

use of org.telegram.SQLite.SQLiteCursor in project Telegram-FOSS by Telegram-FOSS-Team.

the class MessagesStorage method updateDbToLastVersion.

private void updateDbToLastVersion(int currentVersion) throws Exception {
    AndroidUtilities.runOnUIThread(() -> {
        databaseMigrationInProgress = true;
        NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.onDatabaseMigration, true);
    });
    int version = currentVersion;
    FileLog.d("MessagesStorage start db migration from " + version + " to " + LAST_DB_VERSION);
    if (version < 4) {
        database.executeFast("CREATE TABLE IF NOT EXISTS user_photos(uid INTEGER, id INTEGER, data BLOB, PRIMARY KEY (uid, id))").stepThis().dispose();
        database.executeFast("DROP INDEX IF EXISTS read_state_out_idx_messages;").stepThis().dispose();
        database.executeFast("DROP INDEX IF EXISTS ttl_idx_messages;").stepThis().dispose();
        database.executeFast("DROP INDEX IF EXISTS date_idx_messages;").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS mid_out_idx_messages ON messages(mid, out);").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS task_idx_messages ON messages(uid, out, read_state, ttl, date, send_state);").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS uid_date_mid_idx_messages ON messages(uid, date, mid);").stepThis().dispose();
        database.executeFast("CREATE TABLE IF NOT EXISTS user_contacts_v6(uid INTEGER PRIMARY KEY, fname TEXT, sname TEXT)").stepThis().dispose();
        database.executeFast("CREATE TABLE IF NOT EXISTS user_phones_v6(uid INTEGER, phone TEXT, sphone TEXT, deleted INTEGER, PRIMARY KEY (uid, phone))").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS sphone_deleted_idx_user_phones ON user_phones_v6(sphone, deleted);").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS mid_idx_randoms ON randoms(mid);").stepThis().dispose();
        database.executeFast("CREATE TABLE IF NOT EXISTS sent_files_v2(uid TEXT, type INTEGER, data BLOB, PRIMARY KEY (uid, type))").stepThis().dispose();
        database.executeFast("CREATE TABLE IF NOT EXISTS download_queue(uid INTEGER, type INTEGER, date INTEGER, data BLOB, PRIMARY KEY (uid, type));").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS type_date_idx_download_queue ON download_queue(type, date);").stepThis().dispose();
        database.executeFast("CREATE TABLE IF NOT EXISTS dialog_settings(did INTEGER PRIMARY KEY, flags INTEGER);").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS unread_count_idx_dialogs ON dialogs(unread_count);").stepThis().dispose();
        database.executeFast("UPDATE messages SET send_state = 2 WHERE mid < 0 AND send_state = 1").stepThis().dispose();
        fixNotificationSettings();
        database.executeFast("PRAGMA user_version = 4").stepThis().dispose();
        version = 4;
    }
    if (version == 4) {
        database.executeFast("CREATE TABLE IF NOT EXISTS enc_tasks_v2(mid INTEGER PRIMARY KEY, date INTEGER)").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS date_idx_enc_tasks_v2 ON enc_tasks_v2(date);").stepThis().dispose();
        database.beginTransaction();
        SQLiteCursor cursor = database.queryFinalized("SELECT date, data FROM enc_tasks WHERE 1");
        SQLitePreparedStatement state = database.executeFast("REPLACE INTO enc_tasks_v2 VALUES(?, ?)");
        if (cursor.next()) {
            int date = cursor.intValue(0);
            NativeByteBuffer data = cursor.byteBufferValue(1);
            if (data != null) {
                int length = data.limit();
                for (int a = 0; a < length / 4; a++) {
                    state.requery();
                    state.bindInteger(1, data.readInt32(false));
                    state.bindInteger(2, date);
                    state.step();
                }
                data.reuse();
            }
        }
        state.dispose();
        cursor.dispose();
        database.commitTransaction();
        database.executeFast("DROP INDEX IF EXISTS date_idx_enc_tasks;").stepThis().dispose();
        database.executeFast("DROP TABLE IF EXISTS enc_tasks;").stepThis().dispose();
        database.executeFast("ALTER TABLE messages ADD COLUMN media INTEGER default 0").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 6").stepThis().dispose();
        version = 6;
    }
    if (version == 6) {
        database.executeFast("CREATE TABLE IF NOT EXISTS messages_seq(mid INTEGER PRIMARY KEY, seq_in INTEGER, seq_out INTEGER);").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS seq_idx_messages_seq ON messages_seq(seq_in, seq_out);").stepThis().dispose();
        database.executeFast("ALTER TABLE enc_chats ADD COLUMN layer INTEGER default 0").stepThis().dispose();
        database.executeFast("ALTER TABLE enc_chats ADD COLUMN seq_in INTEGER default 0").stepThis().dispose();
        database.executeFast("ALTER TABLE enc_chats ADD COLUMN seq_out INTEGER default 0").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 7").stepThis().dispose();
        version = 7;
    }
    if (version == 7 || version == 8 || version == 9) {
        database.executeFast("ALTER TABLE enc_chats ADD COLUMN use_count INTEGER default 0").stepThis().dispose();
        database.executeFast("ALTER TABLE enc_chats ADD COLUMN exchange_id INTEGER default 0").stepThis().dispose();
        database.executeFast("ALTER TABLE enc_chats ADD COLUMN key_date INTEGER default 0").stepThis().dispose();
        database.executeFast("ALTER TABLE enc_chats ADD COLUMN fprint INTEGER default 0").stepThis().dispose();
        database.executeFast("ALTER TABLE enc_chats ADD COLUMN fauthkey BLOB default NULL").stepThis().dispose();
        database.executeFast("ALTER TABLE enc_chats ADD COLUMN khash BLOB default NULL").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 10").stepThis().dispose();
        version = 10;
    }
    if (version == 10) {
        database.executeFast("CREATE TABLE IF NOT EXISTS web_recent_v3(id TEXT, type INTEGER, image_url TEXT, thumb_url TEXT, local_url TEXT, width INTEGER, height INTEGER, size INTEGER, date INTEGER, PRIMARY KEY (id, type));").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 11").stepThis().dispose();
        version = 11;
    }
    if (version == 11 || version == 12) {
        database.executeFast("DROP INDEX IF EXISTS uid_mid_idx_media;").stepThis().dispose();
        database.executeFast("DROP INDEX IF EXISTS mid_idx_media;").stepThis().dispose();
        database.executeFast("DROP INDEX IF EXISTS uid_date_mid_idx_media;").stepThis().dispose();
        database.executeFast("DROP TABLE IF EXISTS media;").stepThis().dispose();
        database.executeFast("DROP TABLE IF EXISTS media_counts;").stepThis().dispose();
        database.executeFast("CREATE TABLE IF NOT EXISTS media_v2(mid INTEGER PRIMARY KEY, uid INTEGER, date INTEGER, type INTEGER, data BLOB)").stepThis().dispose();
        database.executeFast("CREATE TABLE IF NOT EXISTS media_counts_v2(uid INTEGER, type INTEGER, count INTEGER, PRIMARY KEY(uid, type))").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS uid_mid_type_date_idx_media ON media_v2(uid, mid, type, date);").stepThis().dispose();
        database.executeFast("CREATE TABLE IF NOT EXISTS keyvalue(id TEXT PRIMARY KEY, value TEXT)").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 13").stepThis().dispose();
        version = 13;
    }
    if (version == 13) {
        database.executeFast("ALTER TABLE messages ADD COLUMN replydata BLOB default NULL").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 14").stepThis().dispose();
        version = 14;
    }
    if (version == 14) {
        database.executeFast("CREATE TABLE IF NOT EXISTS hashtag_recent_v2(id TEXT PRIMARY KEY, date INTEGER);").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 15").stepThis().dispose();
        version = 15;
    }
    if (version == 15) {
        database.executeFast("CREATE TABLE IF NOT EXISTS webpage_pending(id INTEGER, mid INTEGER, PRIMARY KEY (id, mid));").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 16").stepThis().dispose();
        version = 16;
    }
    if (version == 16) {
        database.executeFast("ALTER TABLE dialogs ADD COLUMN inbox_max INTEGER default 0").stepThis().dispose();
        database.executeFast("ALTER TABLE dialogs ADD COLUMN outbox_max INTEGER default 0").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 17").stepThis().dispose();
        version = 17;
    }
    if (version == 17) {
        database.executeFast("PRAGMA user_version = 18").stepThis().dispose();
        version = 18;
    }
    if (version == 18) {
        database.executeFast("DROP TABLE IF EXISTS stickers;").stepThis().dispose();
        database.executeFast("CREATE TABLE IF NOT EXISTS stickers_v2(id INTEGER PRIMARY KEY, data BLOB, date INTEGER, hash INTEGER);").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 19").stepThis().dispose();
        version = 19;
    }
    if (version == 19) {
        database.executeFast("CREATE TABLE IF NOT EXISTS bot_keyboard(uid INTEGER PRIMARY KEY, mid INTEGER, info BLOB)").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS bot_keyboard_idx_mid ON bot_keyboard(mid);").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 20").stepThis().dispose();
        version = 20;
    }
    if (version == 20) {
        database.executeFast("CREATE TABLE search_recent(did INTEGER PRIMARY KEY, date INTEGER);").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 21").stepThis().dispose();
        version = 21;
    }
    if (version == 21) {
        database.executeFast("CREATE TABLE IF NOT EXISTS chat_settings_v2(uid INTEGER PRIMARY KEY, info BLOB)").stepThis().dispose();
        SQLiteCursor cursor = database.queryFinalized("SELECT uid, participants FROM chat_settings WHERE uid < 0");
        SQLitePreparedStatement state = database.executeFast("REPLACE INTO chat_settings_v2 VALUES(?, ?)");
        while (cursor.next()) {
            long chatId = cursor.intValue(0);
            NativeByteBuffer data = cursor.byteBufferValue(1);
            if (data != null) {
                TLRPC.ChatParticipants participants = TLRPC.ChatParticipants.TLdeserialize(data, data.readInt32(false), false);
                data.reuse();
                if (participants != null) {
                    TLRPC.TL_chatFull chatFull = new TLRPC.TL_chatFull();
                    chatFull.id = chatId;
                    chatFull.chat_photo = new TLRPC.TL_photoEmpty();
                    chatFull.notify_settings = new TLRPC.TL_peerNotifySettingsEmpty_layer77();
                    chatFull.exported_invite = null;
                    chatFull.participants = participants;
                    NativeByteBuffer data2 = new NativeByteBuffer(chatFull.getObjectSize());
                    chatFull.serializeToStream(data2);
                    state.requery();
                    state.bindLong(1, chatId);
                    state.bindByteBuffer(2, data2);
                    state.step();
                    data2.reuse();
                }
            }
        }
        state.dispose();
        cursor.dispose();
        database.executeFast("DROP TABLE IF EXISTS chat_settings;").stepThis().dispose();
        database.executeFast("ALTER TABLE dialogs ADD COLUMN last_mid_i INTEGER default 0").stepThis().dispose();
        database.executeFast("ALTER TABLE dialogs ADD COLUMN unread_count_i INTEGER default 0").stepThis().dispose();
        database.executeFast("ALTER TABLE dialogs ADD COLUMN pts INTEGER default 0").stepThis().dispose();
        database.executeFast("ALTER TABLE dialogs ADD COLUMN date_i INTEGER default 0").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS last_mid_i_idx_dialogs ON dialogs(last_mid_i);").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS unread_count_i_idx_dialogs ON dialogs(unread_count_i);").stepThis().dispose();
        database.executeFast("ALTER TABLE messages ADD COLUMN imp INTEGER default 0").stepThis().dispose();
        database.executeFast("CREATE TABLE IF NOT EXISTS messages_holes(uid INTEGER, start INTEGER, end INTEGER, PRIMARY KEY(uid, start));").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS uid_end_messages_holes ON messages_holes(uid, end);").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 22").stepThis().dispose();
        version = 22;
    }
    if (version == 22) {
        database.executeFast("CREATE TABLE IF NOT EXISTS media_holes_v2(uid INTEGER, type INTEGER, start INTEGER, end INTEGER, PRIMARY KEY(uid, type, start));").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS uid_end_media_holes_v2 ON media_holes_v2(uid, type, end);").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 23").stepThis().dispose();
        version = 23;
    }
    if (version == 23 || version == 24) {
        database.executeFast("DELETE FROM media_holes_v2 WHERE uid != 0 AND type >= 0 AND start IN (0, 1)").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 25").stepThis().dispose();
        version = 25;
    }
    if (version == 25 || version == 26) {
        database.executeFast("CREATE TABLE IF NOT EXISTS channel_users_v2(did INTEGER, uid INTEGER, date INTEGER, data BLOB, PRIMARY KEY(did, uid))").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 27").stepThis().dispose();
        version = 27;
    }
    if (version == 27) {
        database.executeFast("ALTER TABLE web_recent_v3 ADD COLUMN document BLOB default NULL").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 28").stepThis().dispose();
        version = 28;
    }
    if (version == 28 || version == 29) {
        database.executeFast("DELETE FROM sent_files_v2 WHERE 1").stepThis().dispose();
        database.executeFast("DELETE FROM download_queue WHERE 1").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 30").stepThis().dispose();
        version = 30;
    }
    if (version == 30) {
        database.executeFast("ALTER TABLE chat_settings_v2 ADD COLUMN pinned INTEGER default 0").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS chat_settings_pinned_idx ON chat_settings_v2(uid, pinned) WHERE pinned != 0;").stepThis().dispose();
        database.executeFast("CREATE TABLE IF NOT EXISTS users_data(uid INTEGER PRIMARY KEY, about TEXT)").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 31").stepThis().dispose();
        version = 31;
    }
    if (version == 31) {
        database.executeFast("DROP TABLE IF EXISTS bot_recent;").stepThis().dispose();
        database.executeFast("CREATE TABLE IF NOT EXISTS chat_hints(did INTEGER, type INTEGER, rating REAL, date INTEGER, PRIMARY KEY(did, type))").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS chat_hints_rating_idx ON chat_hints(rating);").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 32").stepThis().dispose();
        version = 32;
    }
    if (version == 32) {
        database.executeFast("DROP INDEX IF EXISTS uid_mid_idx_imp_messages;").stepThis().dispose();
        database.executeFast("DROP INDEX IF EXISTS uid_date_mid_imp_idx_messages;").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 33").stepThis().dispose();
        version = 33;
    }
    if (version == 33) {
        database.executeFast("CREATE TABLE IF NOT EXISTS pending_tasks(id INTEGER PRIMARY KEY, data BLOB);").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 34").stepThis().dispose();
        version = 34;
    }
    if (version == 34) {
        database.executeFast("CREATE TABLE IF NOT EXISTS stickers_featured(id INTEGER PRIMARY KEY, data BLOB, unread BLOB, date INTEGER, hash INTEGER);").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 35").stepThis().dispose();
        version = 35;
    }
    if (version == 35) {
        database.executeFast("CREATE TABLE IF NOT EXISTS requested_holes(uid INTEGER, seq_out_start INTEGER, seq_out_end INTEGER, PRIMARY KEY (uid, seq_out_start, seq_out_end));").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 36").stepThis().dispose();
        version = 36;
    }
    if (version == 36) {
        database.executeFast("ALTER TABLE enc_chats ADD COLUMN in_seq_no INTEGER default 0").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 37").stepThis().dispose();
        version = 37;
    }
    if (version == 37) {
        database.executeFast("CREATE TABLE IF NOT EXISTS botcache(id TEXT PRIMARY KEY, date INTEGER, data BLOB)").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS botcache_date_idx ON botcache(date);").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 38").stepThis().dispose();
        version = 38;
    }
    if (version == 38) {
        database.executeFast("ALTER TABLE dialogs ADD COLUMN pinned INTEGER default 0").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 39").stepThis().dispose();
        version = 39;
    }
    if (version == 39) {
        database.executeFast("ALTER TABLE enc_chats ADD COLUMN admin_id INTEGER default 0").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 40").stepThis().dispose();
        version = 40;
    }
    if (version == 40) {
        fixNotificationSettings();
        database.executeFast("PRAGMA user_version = 41").stepThis().dispose();
        version = 41;
    }
    if (version == 41) {
        database.executeFast("ALTER TABLE messages ADD COLUMN mention INTEGER default 0").stepThis().dispose();
        database.executeFast("ALTER TABLE user_contacts_v6 ADD COLUMN imported INTEGER default 0").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS uid_mention_idx_messages ON messages(uid, mention, read_state);").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 42").stepThis().dispose();
        version = 42;
    }
    if (version == 42) {
        database.executeFast("CREATE TABLE IF NOT EXISTS sharing_locations(uid INTEGER PRIMARY KEY, mid INTEGER, date INTEGER, period INTEGER, message BLOB);").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 43").stepThis().dispose();
        version = 43;
    }
    if (version == 43) {
        database.executeFast("PRAGMA user_version = 44").stepThis().dispose();
        version = 44;
    }
    if (version == 44) {
        database.executeFast("CREATE TABLE IF NOT EXISTS user_contacts_v7(key TEXT PRIMARY KEY, uid INTEGER, fname TEXT, sname TEXT, imported INTEGER)").stepThis().dispose();
        database.executeFast("CREATE TABLE IF NOT EXISTS user_phones_v7(key TEXT, phone TEXT, sphone TEXT, deleted INTEGER, PRIMARY KEY (key, phone))").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS sphone_deleted_idx_user_phones ON user_phones_v7(sphone, deleted);").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 45").stepThis().dispose();
        version = 45;
    }
    if (version == 45) {
        database.executeFast("ALTER TABLE enc_chats ADD COLUMN mtproto_seq INTEGER default 0").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 46").stepThis().dispose();
        version = 46;
    }
    if (version == 46) {
        database.executeFast("DELETE FROM botcache WHERE 1").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 47").stepThis().dispose();
        version = 47;
    }
    if (version == 47) {
        database.executeFast("ALTER TABLE dialogs ADD COLUMN flags INTEGER default 0").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 48").stepThis().dispose();
        version = 48;
    }
    if (version == 48) {
        database.executeFast("CREATE TABLE IF NOT EXISTS unread_push_messages(uid INTEGER, mid INTEGER, random INTEGER, date INTEGER, data BLOB, fm TEXT, name TEXT, uname TEXT, flags INTEGER, PRIMARY KEY(uid, mid))").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS unread_push_messages_idx_date ON unread_push_messages(date);").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS unread_push_messages_idx_random ON unread_push_messages(random);").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 49").stepThis().dispose();
        version = 49;
    }
    if (version == 49) {
        database.executeFast("CREATE TABLE IF NOT EXISTS user_settings(uid INTEGER PRIMARY KEY, info BLOB, pinned INTEGER)").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS user_settings_pinned_idx ON user_settings(uid, pinned) WHERE pinned != 0;").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 50").stepThis().dispose();
        version = 50;
    }
    if (version == 50) {
        database.executeFast("DELETE FROM sent_files_v2 WHERE 1").stepThis().dispose();
        database.executeFast("ALTER TABLE sent_files_v2 ADD COLUMN parent TEXT").stepThis().dispose();
        database.executeFast("DELETE FROM download_queue WHERE 1").stepThis().dispose();
        database.executeFast("ALTER TABLE download_queue ADD COLUMN parent TEXT").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 51").stepThis().dispose();
        version = 51;
    }
    if (version == 51) {
        database.executeFast("ALTER TABLE media_counts_v2 ADD COLUMN old INTEGER").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 52").stepThis().dispose();
        version = 52;
    }
    if (version == 52) {
        database.executeFast("CREATE TABLE IF NOT EXISTS polls_v2(mid INTEGER, uid INTEGER, id INTEGER, PRIMARY KEY (mid, uid));").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS polls_id ON polls_v2(id);").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 53").stepThis().dispose();
        version = 53;
    }
    if (version == 53) {
        database.executeFast("ALTER TABLE chat_settings_v2 ADD COLUMN online INTEGER default 0").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 54").stepThis().dispose();
        version = 54;
    }
    if (version == 54) {
        database.executeFast("DROP TABLE IF EXISTS wallpapers;").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 55").stepThis().dispose();
        version = 55;
    }
    if (version == 55) {
        database.executeFast("CREATE TABLE IF NOT EXISTS wallpapers2(uid INTEGER PRIMARY KEY, data BLOB, num INTEGER)").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS wallpapers_num ON wallpapers2(num);").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 56").stepThis().dispose();
        version = 56;
    }
    if (version == 56 || version == 57) {
        database.executeFast("CREATE TABLE IF NOT EXISTS emoji_keywords_v2(lang TEXT, keyword TEXT, emoji TEXT, PRIMARY KEY(lang, keyword, emoji));").stepThis().dispose();
        database.executeFast("CREATE TABLE IF NOT EXISTS emoji_keywords_info_v2(lang TEXT PRIMARY KEY, alias TEXT, version INTEGER);").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 58").stepThis().dispose();
        version = 58;
    }
    if (version == 58) {
        database.executeFast("CREATE INDEX IF NOT EXISTS emoji_keywords_v2_keyword ON emoji_keywords_v2(keyword);").stepThis().dispose();
        database.executeFast("ALTER TABLE emoji_keywords_info_v2 ADD COLUMN date INTEGER default 0").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 59").stepThis().dispose();
        version = 59;
    }
    if (version == 59) {
        database.executeFast("ALTER TABLE dialogs ADD COLUMN folder_id INTEGER default 0").stepThis().dispose();
        database.executeFast("ALTER TABLE dialogs ADD COLUMN data BLOB default NULL").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS folder_id_idx_dialogs ON dialogs(folder_id);").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 60").stepThis().dispose();
        version = 60;
    }
    if (version == 60) {
        database.executeFast("DROP TABLE IF EXISTS channel_admins;").stepThis().dispose();
        database.executeFast("DROP TABLE IF EXISTS blocked_users;").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 61").stepThis().dispose();
        version = 61;
    }
    if (version == 61) {
        database.executeFast("DROP INDEX IF EXISTS send_state_idx_messages;").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS send_state_idx_messages2 ON messages(mid, send_state, date);").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 62").stepThis().dispose();
        version = 62;
    }
    if (version == 62) {
        database.executeFast("CREATE TABLE IF NOT EXISTS scheduled_messages(mid INTEGER PRIMARY KEY, uid INTEGER, send_state INTEGER, date INTEGER, data BLOB, ttl INTEGER, replydata BLOB)").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS send_state_idx_scheduled_messages ON scheduled_messages(mid, send_state, date);").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS uid_date_idx_scheduled_messages ON scheduled_messages(uid, date);").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 63").stepThis().dispose();
        version = 63;
    }
    if (version == 63) {
        database.executeFast("DELETE FROM download_queue WHERE 1").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 64").stepThis().dispose();
        version = 64;
    }
    if (version == 64) {
        database.executeFast("CREATE TABLE IF NOT EXISTS dialog_filter(id INTEGER PRIMARY KEY, ord INTEGER, unread_count INTEGER, flags INTEGER, title TEXT)").stepThis().dispose();
        database.executeFast("CREATE TABLE IF NOT EXISTS dialog_filter_ep(id INTEGER, peer INTEGER, PRIMARY KEY (id, peer))").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 65").stepThis().dispose();
        version = 65;
    }
    if (version == 65) {
        database.executeFast("CREATE INDEX IF NOT EXISTS flags_idx_dialogs ON dialogs(flags);").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 66").stepThis().dispose();
        version = 66;
    }
    if (version == 66) {
        database.executeFast("CREATE TABLE dialog_filter_pin_v2(id INTEGER, peer INTEGER, pin INTEGER, PRIMARY KEY (id, peer))").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 67").stepThis().dispose();
        version = 67;
    }
    if (version == 67) {
        database.executeFast("CREATE TABLE IF NOT EXISTS stickers_dice(emoji TEXT PRIMARY KEY, data BLOB, date INTEGER);").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 68").stepThis().dispose();
        version = 68;
    }
    if (version == 68) {
        executeNoException("ALTER TABLE messages ADD COLUMN forwards INTEGER default 0");
        database.executeFast("PRAGMA user_version = 69").stepThis().dispose();
        version = 69;
    }
    if (version == 69) {
        executeNoException("ALTER TABLE messages ADD COLUMN replies_data BLOB default NULL");
        executeNoException("ALTER TABLE messages ADD COLUMN thread_reply_id INTEGER default 0");
        database.executeFast("PRAGMA user_version = 70").stepThis().dispose();
        version = 70;
    }
    if (version == 70) {
        database.executeFast("CREATE TABLE IF NOT EXISTS chat_pinned_v2(uid INTEGER, mid INTEGER, data BLOB, PRIMARY KEY (uid, mid));").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 71").stepThis().dispose();
        version = 71;
    }
    if (version == 71) {
        executeNoException("ALTER TABLE sharing_locations ADD COLUMN proximity INTEGER default 0");
        database.executeFast("PRAGMA user_version = 72").stepThis().dispose();
        version = 72;
    }
    if (version == 72) {
        database.executeFast("CREATE TABLE IF NOT EXISTS chat_pinned_count(uid INTEGER PRIMARY KEY, count INTEGER, end INTEGER);").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 73").stepThis().dispose();
        version = 73;
    }
    if (version == 73) {
        executeNoException("ALTER TABLE chat_settings_v2 ADD COLUMN inviter INTEGER default 0");
        database.executeFast("PRAGMA user_version = 74").stepThis().dispose();
        version = 74;
    }
    if (version == 74) {
        database.executeFast("CREATE TABLE IF NOT EXISTS shortcut_widget(id INTEGER, did INTEGER, ord INTEGER, PRIMARY KEY (id, did));").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS shortcut_widget_did ON shortcut_widget(did);").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 75").stepThis().dispose();
        version = 75;
    }
    if (version == 75) {
        executeNoException("ALTER TABLE chat_settings_v2 ADD COLUMN links INTEGER default 0");
        database.executeFast("PRAGMA user_version = 76").stepThis().dispose();
        version = 76;
    }
    if (version == 76) {
        executeNoException("ALTER TABLE enc_tasks_v2 ADD COLUMN media INTEGER default -1");
        database.executeFast("PRAGMA user_version = 77").stepThis().dispose();
        version = 77;
    }
    if (version == 77) {
        database.executeFast("DROP TABLE IF EXISTS channel_admins_v2;").stepThis().dispose();
        database.executeFast("CREATE TABLE IF NOT EXISTS channel_admins_v3(did INTEGER, uid INTEGER, data BLOB, PRIMARY KEY(did, uid))").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 78").stepThis().dispose();
        version = 78;
    }
    if (version == 78) {
        database.executeFast("DROP TABLE IF EXISTS bot_info;").stepThis().dispose();
        database.executeFast("CREATE TABLE IF NOT EXISTS bot_info_v2(uid INTEGER, dialogId INTEGER, info BLOB, PRIMARY KEY(uid, dialogId))").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 79").stepThis().dispose();
        version = 79;
    }
    if (version == 79) {
        database.executeFast("CREATE TABLE IF NOT EXISTS enc_tasks_v3(mid INTEGER, date INTEGER, media INTEGER, PRIMARY KEY(mid, media))").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS date_idx_enc_tasks_v3 ON enc_tasks_v3(date);").stepThis().dispose();
        database.beginTransaction();
        SQLiteCursor cursor = database.queryFinalized("SELECT mid, date, media FROM enc_tasks_v2 WHERE 1");
        SQLitePreparedStatement state = database.executeFast("REPLACE INTO enc_tasks_v3 VALUES(?, ?, ?)");
        if (cursor.next()) {
            long mid = cursor.longValue(0);
            int date = cursor.intValue(1);
            int media = cursor.intValue(2);
            state.requery();
            state.bindLong(1, mid);
            state.bindInteger(2, date);
            state.bindInteger(3, media);
            state.step();
        }
        state.dispose();
        cursor.dispose();
        database.commitTransaction();
        database.executeFast("DROP INDEX IF EXISTS date_idx_enc_tasks_v2;").stepThis().dispose();
        database.executeFast("DROP TABLE IF EXISTS enc_tasks_v2;").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 80").stepThis().dispose();
        version = 80;
    }
    if (version == 80) {
        database.executeFast("CREATE TABLE IF NOT EXISTS scheduled_messages_v2(mid INTEGER, uid INTEGER, send_state INTEGER, date INTEGER, data BLOB, ttl INTEGER, replydata BLOB, PRIMARY KEY(mid, uid))").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS send_state_idx_scheduled_messages_v2 ON scheduled_messages_v2(mid, send_state, date);").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS uid_date_idx_scheduled_messages_v2 ON scheduled_messages_v2(uid, date);").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS bot_keyboard_idx_mid_v2 ON bot_keyboard(mid, uid);").stepThis().dispose();
        database.executeFast("DROP INDEX IF EXISTS bot_keyboard_idx_mid;").stepThis().dispose();
        database.beginTransaction();
        SQLiteCursor cursor;
        try {
            cursor = database.queryFinalized("SELECT mid, uid, send_state, date, data, ttl, replydata FROM scheduled_messages_v2 WHERE 1");
        } catch (Exception e) {
            cursor = null;
            FileLog.e(e);
        }
        if (cursor != null) {
            SQLitePreparedStatement statement = database.executeFast("REPLACE INTO scheduled_messages_v2 VALUES(?, ?, ?, ?, ?, ?, ?)");
            while (cursor.next()) {
                NativeByteBuffer data = cursor.byteBufferValue(4);
                if (data == null) {
                    continue;
                }
                int mid = cursor.intValue(0);
                long uid = cursor.longValue(1);
                int sendState = cursor.intValue(2);
                int date = cursor.intValue(3);
                int ttl = cursor.intValue(5);
                NativeByteBuffer replydata = cursor.byteBufferValue(6);
                statement.requery();
                statement.bindInteger(1, mid);
                statement.bindLong(2, uid);
                statement.bindInteger(3, sendState);
                statement.bindByteBuffer(4, data);
                statement.bindInteger(5, date);
                statement.bindInteger(6, ttl);
                if (replydata != null) {
                    statement.bindByteBuffer(7, replydata);
                } else {
                    statement.bindNull(7);
                }
                statement.step();
                if (replydata != null) {
                    replydata.reuse();
                }
                data.reuse();
            }
            cursor.dispose();
            statement.dispose();
        }
        database.executeFast("DROP INDEX IF EXISTS send_state_idx_scheduled_messages;").stepThis().dispose();
        database.executeFast("DROP INDEX IF EXISTS uid_date_idx_scheduled_messages;").stepThis().dispose();
        database.executeFast("DROP TABLE IF EXISTS scheduled_messages;").stepThis().dispose();
        database.commitTransaction();
        database.executeFast("PRAGMA user_version = 81").stepThis().dispose();
        version = 81;
    }
    if (version == 81) {
        database.executeFast("CREATE TABLE IF NOT EXISTS media_v3(mid INTEGER, uid INTEGER, date INTEGER, type INTEGER, data BLOB, PRIMARY KEY(mid, uid))").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS uid_mid_type_date_idx_media_v3 ON media_v3(uid, mid, type, date);").stepThis().dispose();
        database.beginTransaction();
        SQLiteCursor cursor;
        try {
            cursor = database.queryFinalized("SELECT mid, uid, date, type, data FROM media_v2 WHERE 1");
        } catch (Exception e) {
            cursor = null;
            FileLog.e(e);
        }
        if (cursor != null) {
            SQLitePreparedStatement statement = database.executeFast("REPLACE INTO media_v3 VALUES(?, ?, ?, ?, ?)");
            while (cursor.next()) {
                NativeByteBuffer data = cursor.byteBufferValue(4);
                if (data == null) {
                    continue;
                }
                int mid = cursor.intValue(0);
                long uid = cursor.longValue(1);
                int lowerId = (int) uid;
                if (lowerId == 0) {
                    int highId = (int) (uid >> 32);
                    uid = DialogObject.makeEncryptedDialogId(highId);
                }
                int date = cursor.intValue(2);
                int type = cursor.intValue(3);
                statement.requery();
                statement.bindInteger(1, mid);
                statement.bindLong(2, uid);
                statement.bindInteger(3, date);
                statement.bindInteger(4, type);
                statement.bindByteBuffer(5, data);
                statement.step();
                data.reuse();
            }
            cursor.dispose();
            statement.dispose();
        }
        database.executeFast("DROP INDEX IF EXISTS uid_mid_type_date_idx_media;").stepThis().dispose();
        database.executeFast("DROP TABLE IF EXISTS media_v2;").stepThis().dispose();
        database.commitTransaction();
        database.executeFast("PRAGMA user_version = 82").stepThis().dispose();
        version = 82;
    }
    if (version == 82) {
        database.executeFast("CREATE TABLE IF NOT EXISTS randoms_v2(random_id INTEGER, mid INTEGER, uid INTEGER, PRIMARY KEY (random_id, mid, uid))").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS mid_idx_randoms_v2 ON randoms_v2(mid, uid);").stepThis().dispose();
        database.executeFast("CREATE TABLE IF NOT EXISTS enc_tasks_v4(mid INTEGER, uid INTEGER, date INTEGER, media INTEGER, PRIMARY KEY(mid, uid, media))").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS date_idx_enc_tasks_v4 ON enc_tasks_v4(date);").stepThis().dispose();
        database.executeFast("CREATE TABLE IF NOT EXISTS polls_v2(mid INTEGER, uid INTEGER, id INTEGER, PRIMARY KEY (mid, uid));").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS polls_id_v2 ON polls_v2(id);").stepThis().dispose();
        database.executeFast("CREATE TABLE IF NOT EXISTS webpage_pending_v2(id INTEGER, mid INTEGER, uid INTEGER, PRIMARY KEY (id, mid, uid));").stepThis().dispose();
        database.beginTransaction();
        SQLiteCursor cursor;
        try {
            cursor = database.queryFinalized("SELECT r.random_id, r.mid, m.uid FROM randoms as r INNER JOIN messages as m ON r.mid = m.mid WHERE 1");
        } catch (Exception e) {
            cursor = null;
            FileLog.e(e);
        }
        if (cursor != null) {
            SQLitePreparedStatement statement = database.executeFast("REPLACE INTO randoms_v2 VALUES(?, ?, ?)");
            while (cursor.next()) {
                long randomId = cursor.longValue(0);
                int mid = cursor.intValue(1);
                long uid = cursor.longValue(2);
                int lowerId = (int) uid;
                if (lowerId == 0) {
                    int highId = (int) (uid >> 32);
                    uid = DialogObject.makeEncryptedDialogId(highId);
                }
                statement.requery();
                statement.bindLong(1, randomId);
                statement.bindInteger(2, mid);
                statement.bindLong(3, uid);
                statement.step();
            }
            cursor.dispose();
            statement.dispose();
        }
        try {
            cursor = database.queryFinalized("SELECT p.mid, m.uid, p.id FROM polls as p INNER JOIN messages as m ON p.mid = m.mid WHERE 1");
        } catch (Exception e) {
            cursor = null;
            FileLog.e(e);
        }
        if (cursor != null) {
            SQLitePreparedStatement statement = database.executeFast("REPLACE INTO polls_v2 VALUES(?, ?, ?)");
            while (cursor.next()) {
                int mid = cursor.intValue(0);
                long uid = cursor.longValue(1);
                long id = cursor.longValue(2);
                int lowerId = (int) uid;
                if (lowerId == 0) {
                    int highId = (int) (uid >> 32);
                    uid = DialogObject.makeEncryptedDialogId(highId);
                }
                statement.requery();
                statement.bindInteger(1, mid);
                statement.bindLong(2, uid);
                statement.bindLong(3, id);
                statement.step();
            }
            cursor.dispose();
            statement.dispose();
        }
        try {
            cursor = database.queryFinalized("SELECT wp.id, wp.mid, m.uid FROM webpage_pending as wp INNER JOIN messages as m ON wp.mid = m.mid WHERE 1");
        } catch (Exception e) {
            cursor = null;
            FileLog.e(e);
        }
        if (cursor != null) {
            SQLitePreparedStatement statement = database.executeFast("REPLACE INTO webpage_pending_v2 VALUES(?, ?, ?)");
            while (cursor.next()) {
                long id = cursor.longValue(0);
                int mid = cursor.intValue(1);
                long uid = cursor.longValue(2);
                int lowerId = (int) uid;
                if (lowerId == 0) {
                    int highId = (int) (uid >> 32);
                    uid = DialogObject.makeEncryptedDialogId(highId);
                }
                statement.requery();
                statement.bindLong(1, id);
                statement.bindInteger(2, mid);
                statement.bindLong(3, uid);
                statement.step();
            }
            cursor.dispose();
            statement.dispose();
        }
        try {
            cursor = database.queryFinalized("SELECT et.mid, m.uid, et.date, et.media FROM enc_tasks_v3 as et INNER JOIN messages as m ON et.mid = m.mid WHERE 1");
        } catch (Exception e) {
            cursor = null;
            FileLog.e(e);
        }
        if (cursor != null) {
            SQLitePreparedStatement statement = database.executeFast("REPLACE INTO enc_tasks_v4 VALUES(?, ?, ?, ?)");
            while (cursor.next()) {
                int mid = cursor.intValue(0);
                long uid = cursor.longValue(1);
                int date = cursor.intValue(2);
                int media = cursor.intValue(3);
                int lowerId = (int) uid;
                if (lowerId == 0) {
                    int highId = (int) (uid >> 32);
                    uid = DialogObject.makeEncryptedDialogId(highId);
                }
                statement.requery();
                statement.bindInteger(1, mid);
                statement.bindLong(2, uid);
                statement.bindInteger(3, date);
                statement.bindInteger(4, media);
                statement.step();
            }
            cursor.dispose();
            statement.dispose();
        }
        database.executeFast("DROP INDEX IF EXISTS mid_idx_randoms;").stepThis().dispose();
        database.executeFast("DROP TABLE IF EXISTS randoms;").stepThis().dispose();
        database.executeFast("DROP INDEX IF EXISTS date_idx_enc_tasks_v3;").stepThis().dispose();
        database.executeFast("DROP TABLE IF EXISTS enc_tasks_v3;").stepThis().dispose();
        database.executeFast("DROP INDEX IF EXISTS polls_id;").stepThis().dispose();
        database.executeFast("DROP TABLE IF EXISTS polls;").stepThis().dispose();
        database.executeFast("DROP TABLE IF EXISTS webpage_pending;").stepThis().dispose();
        database.commitTransaction();
        database.executeFast("PRAGMA user_version = 83").stepThis().dispose();
        version = 83;
    }
    if (version == 83) {
        database.executeFast("CREATE TABLE IF NOT EXISTS messages_v2(mid INTEGER, uid INTEGER, read_state INTEGER, send_state INTEGER, date INTEGER, data BLOB, out INTEGER, ttl INTEGER, media INTEGER, replydata BLOB, imp INTEGER, mention INTEGER, forwards INTEGER, replies_data BLOB, thread_reply_id INTEGER, is_channel INTEGER, PRIMARY KEY(mid, uid))").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS uid_mid_read_out_idx_messages_v2 ON messages_v2(uid, mid, read_state, out);").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS uid_date_mid_idx_messages_v2 ON messages_v2(uid, date, mid);").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS mid_out_idx_messages_v2 ON messages_v2(mid, out);").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS task_idx_messages_v2 ON messages_v2(uid, out, read_state, ttl, date, send_state);").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS send_state_idx_messages_v2 ON messages_v2(mid, send_state, date);").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS uid_mention_idx_messages_v2 ON messages_v2(uid, mention, read_state);").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS is_channel_idx_messages_v2 ON messages_v2(mid, is_channel);").stepThis().dispose();
        database.beginTransaction();
        SQLiteCursor cursor;
        try {
            cursor = database.queryFinalized("SELECT mid, uid, read_state, send_state, date, data, out, ttl, media, replydata, imp, mention, forwards, replies_data, thread_reply_id FROM messages WHERE 1");
        } catch (Exception e) {
            cursor = null;
            FileLog.e(e);
        }
        if (cursor != null) {
            SQLitePreparedStatement statement = database.executeFast("REPLACE INTO messages_v2 VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
            int num = 0;
            while (cursor.next()) {
                NativeByteBuffer data = cursor.byteBufferValue(5);
                if (data == null) {
                    continue;
                }
                num++;
                long mid = cursor.intValue(0);
                long uid = cursor.longValue(1);
                int lowerId = (int) uid;
                if (lowerId == 0) {
                    int highId = (int) (uid >> 32);
                    uid = DialogObject.makeEncryptedDialogId(highId);
                }
                int readState = cursor.intValue(2);
                int sendState = cursor.intValue(3);
                int date = cursor.intValue(4);
                int out = cursor.intValue(6);
                int ttl = cursor.intValue(7);
                int media = cursor.intValue(8);
                NativeByteBuffer replydata = cursor.byteBufferValue(9);
                int imp = cursor.intValue(10);
                int mention = cursor.intValue(11);
                int forwards = cursor.intValue(12);
                NativeByteBuffer repliesdata = cursor.byteBufferValue(13);
                int thread_reply_id = cursor.intValue(14);
                int channelId = (int) (uid >> 32);
                if (ttl < 0) {
                    TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
                    if (message != null) {
                        message.readAttachPath(data, getUserConfig().clientUserId);
                        if (message.params == null) {
                            message.params = new HashMap<>();
                            message.params.put("fwd_peer", "" + ttl);
                        }
                        data.reuse();
                        data = new NativeByteBuffer(message.getObjectSize());
                        message.serializeToStream(data);
                    }
                    ttl = 0;
                }
                statement.requery();
                statement.bindInteger(1, (int) mid);
                statement.bindLong(2, uid);
                statement.bindInteger(3, readState);
                statement.bindInteger(4, sendState);
                statement.bindInteger(5, date);
                statement.bindByteBuffer(6, data);
                statement.bindInteger(7, out);
                statement.bindInteger(8, ttl);
                statement.bindInteger(9, media);
                if (replydata != null) {
                    statement.bindByteBuffer(10, replydata);
                } else {
                    statement.bindNull(10);
                }
                statement.bindInteger(11, imp);
                statement.bindInteger(12, mention);
                statement.bindInteger(13, forwards);
                if (repliesdata != null) {
                    statement.bindByteBuffer(14, repliesdata);
                } else {
                    statement.bindNull(14);
                }
                statement.bindInteger(15, thread_reply_id);
                statement.bindInteger(16, channelId > 0 ? 1 : 0);
                statement.step();
                if (replydata != null) {
                    replydata.reuse();
                }
                if (repliesdata != null) {
                    repliesdata.reuse();
                }
                data.reuse();
            }
            cursor.dispose();
            statement.dispose();
        }
        ArrayList<Integer> secretChatsToUpdate = null;
        ArrayList<Integer> foldersToUpdate = null;
        cursor = database.queryFinalized("SELECT did, last_mid, last_mid_i FROM dialogs WHERE 1");
        SQLitePreparedStatement statement4 = database.executeFast("UPDATE dialogs SET last_mid = ?, last_mid_i = ? WHERE did = ?");
        while (cursor.next()) {
            long did = cursor.longValue(0);
            int lowerId = (int) did;
            int highId = (int) (did >> 32);
            if (lowerId == 0) {
                if (secretChatsToUpdate == null) {
                    secretChatsToUpdate = new ArrayList<>();
                }
                secretChatsToUpdate.add(highId);
            } else if (highId == 2) {
                if (foldersToUpdate == null) {
                    foldersToUpdate = new ArrayList<>();
                }
                foldersToUpdate.add(lowerId);
            }
            statement4.requery();
            statement4.bindInteger(1, cursor.intValue(1));
            statement4.bindInteger(2, cursor.intValue(2));
            statement4.bindLong(3, did);
            statement4.step();
        }
        statement4.dispose();
        cursor.dispose();
        cursor = database.queryFinalized("SELECT uid, mid FROM unread_push_messages WHERE 1");
        statement4 = database.executeFast("UPDATE unread_push_messages SET mid = ? WHERE uid = ? AND mid = ?");
        while (cursor.next()) {
            long did = cursor.longValue(0);
            int mid = cursor.intValue(1);
            statement4.requery();
            statement4.bindInteger(1, mid);
            statement4.bindLong(2, did);
            statement4.bindInteger(3, mid);
            statement4.step();
        }
        statement4.dispose();
        cursor.dispose();
        if (secretChatsToUpdate != null) {
            SQLitePreparedStatement statement = database.executeFast("UPDATE dialogs SET did = ? WHERE did = ?");
            SQLitePreparedStatement statement2 = database.executeFast("UPDATE dialog_filter_pin_v2 SET peer = ? WHERE peer = ?");
            SQLitePreparedStatement statement3 = database.executeFast("UPDATE dialog_filter_ep SET peer = ? WHERE peer = ?");
            for (int a = 0, N = secretChatsToUpdate.size(); a < N; a++) {
                int sid = secretChatsToUpdate.get(a);
                long newId = DialogObject.makeEncryptedDialogId(sid);
                long oldId = ((long) sid) << 32;
                statement.requery();
                statement.bindLong(1, newId);
                statement.bindLong(2, oldId);
                statement.step();
                statement2.requery();
                statement2.bindLong(1, newId);
                statement2.bindLong(2, oldId);
                statement2.step();
                statement3.requery();
                statement3.bindLong(1, newId);
                statement3.bindLong(2, oldId);
                statement3.step();
            }
            statement.dispose();
            statement2.dispose();
            statement3.dispose();
        }
        if (foldersToUpdate != null) {
            SQLitePreparedStatement statement = database.executeFast("UPDATE dialogs SET did = ? WHERE did = ?");
            for (int a = 0, N = foldersToUpdate.size(); a < N; a++) {
                int fid = foldersToUpdate.get(a);
                long newId = DialogObject.makeFolderDialogId(fid);
                long oldId = (((long) 2) << 32) | fid;
                statement.requery();
                statement.bindLong(1, newId);
                statement.bindLong(2, oldId);
                statement.step();
            }
            statement.dispose();
        }
        database.executeFast("DROP INDEX IF EXISTS uid_mid_read_out_idx_messages;").stepThis().dispose();
        database.executeFast("DROP INDEX IF EXISTS uid_date_mid_idx_messages;").stepThis().dispose();
        database.executeFast("DROP INDEX IF EXISTS mid_out_idx_messages;").stepThis().dispose();
        database.executeFast("DROP INDEX IF EXISTS task_idx_messages;").stepThis().dispose();
        database.executeFast("DROP INDEX IF EXISTS send_state_idx_messages2;").stepThis().dispose();
        database.executeFast("DROP INDEX IF EXISTS uid_mention_idx_messages;").stepThis().dispose();
        database.executeFast("DROP TABLE IF EXISTS messages;").stepThis().dispose();
        database.commitTransaction();
        database.executeFast("PRAGMA user_version = 84").stepThis().dispose();
        version = 84;
    }
    if (version == 84) {
        database.executeFast("CREATE TABLE IF NOT EXISTS media_v4(mid INTEGER, uid INTEGER, date INTEGER, type INTEGER, data BLOB, PRIMARY KEY(mid, uid, type))").stepThis().dispose();
        database.beginTransaction();
        SQLiteCursor cursor;
        try {
            cursor = database.queryFinalized("SELECT mid, uid, date, type, data FROM media_v3 WHERE 1");
        } catch (Exception e) {
            cursor = null;
            FileLog.e(e);
        }
        if (cursor != null) {
            SQLitePreparedStatement statement = database.executeFast("REPLACE INTO media_v4 VALUES(?, ?, ?, ?, ?)");
            while (cursor.next()) {
                NativeByteBuffer data = cursor.byteBufferValue(4);
                if (data == null) {
                    continue;
                }
                int mid = cursor.intValue(0);
                long uid = cursor.longValue(1);
                int lowerId = (int) uid;
                if (lowerId == 0) {
                    int highId = (int) (uid >> 32);
                    uid = DialogObject.makeEncryptedDialogId(highId);
                }
                int date = cursor.intValue(2);
                int type = cursor.intValue(3);
                statement.requery();
                statement.bindInteger(1, mid);
                statement.bindLong(2, uid);
                statement.bindInteger(3, date);
                statement.bindInteger(4, type);
                statement.bindByteBuffer(5, data);
                statement.step();
                data.reuse();
            }
            cursor.dispose();
            statement.dispose();
        }
        database.commitTransaction();
        database.executeFast("DROP TABLE IF EXISTS media_v3;").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 85").stepThis().dispose();
        version = 85;
    }
    if (version == 85) {
        executeNoException("ALTER TABLE messages_v2 ADD COLUMN reply_to_message_id INTEGER default 0");
        executeNoException("ALTER TABLE scheduled_messages_v2 ADD COLUMN reply_to_message_id INTEGER default 0");
        database.executeFast("CREATE INDEX IF NOT EXISTS reply_to_idx_messages_v2 ON messages_v2(mid, reply_to_message_id);").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS reply_to_idx_scheduled_messages_v2 ON scheduled_messages_v2(mid, reply_to_message_id);").stepThis().dispose();
        executeNoException("UPDATE messages_v2 SET replydata = NULL");
        executeNoException("UPDATE scheduled_messages_v2 SET replydata = NULL");
        database.executeFast("PRAGMA user_version = 86").stepThis().dispose();
        version = 86;
    }
    if (version == 86) {
        database.executeFast("CREATE TABLE IF NOT EXISTS reactions(data BLOB, hash INTEGER, date INTEGER);").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 87").stepThis().dispose();
        version = 87;
    }
    if (version == 87) {
        database.executeFast("ALTER TABLE dialogs ADD COLUMN unread_reactions INTEGER default 0").stepThis().dispose();
        database.executeFast("CREATE TABLE reaction_mentions(message_id INTEGER PRIMARY KEY, state INTEGER);").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 88").stepThis().dispose();
        version = 88;
    }
    if (version == 88 || version == 89) {
        long time = System.currentTimeMillis();
        database.executeFast("DROP TABLE IF EXISTS reaction_mentions;").stepThis().dispose();
        database.executeFast("CREATE TABLE IF NOT EXISTS reaction_mentions(message_id INTEGER, state INTEGER, dialog_id INTEGER, PRIMARY KEY(dialog_id, message_id));").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS reaction_mentions_did ON reaction_mentions(dialog_id);").stepThis().dispose();
        database.executeFast("DROP INDEX IF EXISTS uid_mid_type_date_idx_media_v3").stepThis().dispose();
        database.executeFast("CREATE INDEX IF NOT EXISTS uid_mid_type_date_idx_media_v4 ON media_v4(uid, mid, type, date);").stepThis().dispose();
        database.executeFast("PRAGMA user_version = 90").stepThis().dispose();
        version = 90;
    }
    FileLog.d("MessagesStorage db migration finished");
    AndroidUtilities.runOnUIThread(() -> {
        databaseMigrationInProgress = false;
        NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.onDatabaseMigration, false);
    });
}
Also used : ArrayList(java.util.ArrayList) NativeByteBuffer(org.telegram.tgnet.NativeByteBuffer) SQLiteCursor(org.telegram.SQLite.SQLiteCursor) TLRPC(org.telegram.tgnet.TLRPC) SQLiteException(org.telegram.SQLite.SQLiteException) SQLitePreparedStatement(org.telegram.SQLite.SQLitePreparedStatement)

Example 34 with SQLiteCursor

use of org.telegram.SQLite.SQLiteCursor in project Telegram-FOSS by Telegram-FOSS-Team.

the class MessagesStorage method updateUserInfo.

public void updateUserInfo(TLRPC.UserFull info, boolean ifExist) {
    storageQueue.postRunnable(() -> {
        try {
            if (ifExist) {
                SQLiteCursor cursor = database.queryFinalized("SELECT uid FROM user_settings WHERE uid = " + info.user.id);
                boolean exist = cursor.next();
                cursor.dispose();
                if (!exist) {
                    return;
                }
            }
            SQLitePreparedStatement state = database.executeFast("REPLACE INTO user_settings VALUES(?, ?, ?)");
            NativeByteBuffer data = new NativeByteBuffer(info.getObjectSize());
            info.serializeToStream(data);
            state.bindLong(1, info.user.id);
            state.bindByteBuffer(2, data);
            state.bindInteger(3, info.pinned_msg_id);
            state.step();
            state.dispose();
            data.reuse();
            if ((info.flags & 2048) != 0) {
                state = database.executeFast("UPDATE dialogs SET folder_id = ? WHERE did = ?");
                state.bindInteger(1, info.folder_id);
                state.bindLong(2, info.user.id);
                state.step();
                state.dispose();
                unknownDialogsIds.remove(info.user.id);
            }
        } catch (Exception e) {
            FileLog.e(e);
        }
    });
}
Also used : NativeByteBuffer(org.telegram.tgnet.NativeByteBuffer) SQLiteCursor(org.telegram.SQLite.SQLiteCursor) SQLiteException(org.telegram.SQLite.SQLiteException) SQLitePreparedStatement(org.telegram.SQLite.SQLitePreparedStatement)

Example 35 with SQLiteCursor

use of org.telegram.SQLite.SQLiteCursor in project Telegram-FOSS by Telegram-FOSS-Team.

the class MessagesStorage method getDialogMaxMessageId.

public void getDialogMaxMessageId(long dialog_id, IntCallback callback) {
    storageQueue.postRunnable(() -> {
        SQLiteCursor cursor = null;
        int[] max = new int[1];
        try {
            cursor = database.queryFinalized("SELECT MAX(mid) FROM messages_v2 WHERE uid = " + dialog_id);
            if (cursor.next()) {
                max[0] = cursor.intValue(0);
            }
        } catch (Exception e) {
            FileLog.e(e);
        } finally {
            if (cursor != null) {
                cursor.dispose();
            }
        }
        AndroidUtilities.runOnUIThread(() -> callback.run(max[0]));
    });
}
Also used : SQLiteCursor(org.telegram.SQLite.SQLiteCursor) SQLiteException(org.telegram.SQLite.SQLiteException)

Aggregations

SQLiteCursor (org.telegram.SQLite.SQLiteCursor)118 SQLiteException (org.telegram.SQLite.SQLiteException)105 TLRPC (org.telegram.tgnet.TLRPC)77 NativeByteBuffer (org.telegram.tgnet.NativeByteBuffer)66 ArrayList (java.util.ArrayList)58 SQLitePreparedStatement (org.telegram.SQLite.SQLitePreparedStatement)42 LongSparseArray (androidx.collection.LongSparseArray)25 AtomicLong (java.util.concurrent.atomic.AtomicLong)19 Paint (android.graphics.Paint)18 SparseArray (android.util.SparseArray)11 CountDownLatch (java.util.concurrent.CountDownLatch)11 SpannableStringBuilder (android.text.SpannableStringBuilder)10 LongSparseIntArray (org.telegram.messenger.support.LongSparseIntArray)10 File (java.io.File)8 HashMap (java.util.HashMap)7 Pair (android.util.Pair)6 TLObject (org.telegram.tgnet.TLObject)6 LinkedHashMap (java.util.LinkedHashMap)4 SharedPreferences (android.content.SharedPreferences)3 SpannedString (android.text.SpannedString)3