Search in sources :

Example 71 with SQLiteCursor

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

the class MessagesStorage method checkMessageId.

public boolean checkMessageId(long dialogId, int mid) {
    boolean[] result = new boolean[1];
    CountDownLatch countDownLatch = new CountDownLatch(1);
    storageQueue.postRunnable(() -> {
        SQLiteCursor cursor = null;
        try {
            cursor = database.queryFinalized(String.format(Locale.US, "SELECT mid FROM messages_v2 WHERE uid = %d AND mid = %d", dialogId, mid));
            if (cursor.next()) {
                result[0] = true;
            }
        } catch (Exception e) {
            FileLog.e(e);
        } finally {
            if (cursor != null) {
                cursor.dispose();
            }
        }
        countDownLatch.countDown();
    });
    try {
        countDownLatch.await();
    } catch (Exception e) {
        FileLog.e(e);
    }
    return result[0];
}
Also used : CountDownLatch(java.util.concurrent.CountDownLatch) SQLiteCursor(org.telegram.SQLite.SQLiteCursor) SQLiteException(org.telegram.SQLite.SQLiteException)

Example 72 with SQLiteCursor

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

the class MessagesStorage method checkIfFolderEmptyInternal.

private void checkIfFolderEmptyInternal(int folderId) {
    try {
        SQLiteCursor cursor = database.queryFinalized("SELECT did FROM dialogs WHERE folder_id = ?", folderId);
        boolean isEmpty = true;
        while (cursor.next()) {
            long did = cursor.longValue(0);
            if (DialogObject.isUserDialog(did) || DialogObject.isEncryptedDialog(did)) {
                isEmpty = false;
                break;
            } else {
                TLRPC.Chat chat = getChat(-did);
                if (!ChatObject.isNotInChat(chat) && chat.migrated_to == null) {
                    isEmpty = false;
                    break;
                }
            }
        }
        cursor.dispose();
        if (isEmpty) {
            AndroidUtilities.runOnUIThread(() -> getMessagesController().onFolderEmpty(folderId));
            database.executeFast("DELETE FROM dialogs WHERE did = " + DialogObject.makeFolderDialogId(folderId)).stepThis().dispose();
        }
    } catch (Exception e) {
        FileLog.e(e);
    }
}
Also used : SQLiteCursor(org.telegram.SQLite.SQLiteCursor) TLRPC(org.telegram.tgnet.TLRPC) SQLiteException(org.telegram.SQLite.SQLiteException)

Example 73 with SQLiteCursor

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

the class MessagesStorage method markMessagesAsDeletedInternal.

private ArrayList<Long> markMessagesAsDeletedInternal(long dialogId, ArrayList<Integer> messages, boolean deleteFiles, boolean scheduled) {
    try {
        ArrayList<Long> dialogsIds = new ArrayList<>();
        if (scheduled) {
            String ids = TextUtils.join(",", messages);
            ArrayList<Long> dialogsToUpdate = new ArrayList<>();
            SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT uid FROM scheduled_messages_v2 WHERE mid IN(%s) AND uid = %d", ids, dialogId));
            try {
                while (cursor.next()) {
                    long did = cursor.longValue(0);
                    if (!dialogsToUpdate.contains(did)) {
                        dialogsToUpdate.add(did);
                    }
                }
            } catch (Exception e) {
                FileLog.e(e);
            }
            cursor.dispose();
            database.executeFast(String.format(Locale.US, "DELETE FROM scheduled_messages_v2 WHERE mid IN(%s) AND uid = %d", ids, dialogId)).stepThis().dispose();
            for (int a = 0, N = dialogsToUpdate.size(); a < N; a++) {
                broadcastScheduledMessagesChange(dialogsToUpdate.get(a));
            }
        } else {
            ArrayList<Integer> temp = new ArrayList<>(messages);
            LongSparseArray<Integer[]> dialogsToUpdate = new LongSparseArray<>();
            LongSparseArray<ArrayList<Integer>> messagesByDialogs = new LongSparseArray<>();
            String ids = TextUtils.join(",", messages);
            ArrayList<File> filesToDelete = new ArrayList<>();
            ArrayList<String> namesToDelete = new ArrayList<>();
            ArrayList<Pair<Long, Integer>> idsToDelete = new ArrayList<>();
            long currentUser = getUserConfig().getClientUserId();
            SQLiteCursor cursor;
            if (dialogId != 0) {
                cursor = database.queryFinalized(String.format(Locale.US, "SELECT uid, data, read_state, out, mention, mid FROM messages_v2 WHERE mid IN(%s) AND uid = %d", ids, dialogId));
            } else {
                cursor = database.queryFinalized(String.format(Locale.US, "SELECT uid, data, read_state, out, mention, mid FROM messages_v2 WHERE mid IN(%s) AND is_channel = 0", ids));
            }
            try {
                while (cursor.next()) {
                    long did = cursor.longValue(0);
                    int mid = cursor.intValue(5);
                    temp.remove((Integer) mid);
                    ArrayList<Integer> mids = messagesByDialogs.get(did);
                    if (mids == null) {
                        mids = new ArrayList<>();
                        messagesByDialogs.put(did, mids);
                    }
                    mids.add(mid);
                    if (did != currentUser) {
                        int read_state = cursor.intValue(2);
                        if (cursor.intValue(3) == 0) {
                            Integer[] unread_count = dialogsToUpdate.get(did);
                            if (unread_count == null) {
                                unread_count = new Integer[] { 0, 0 };
                                dialogsToUpdate.put(did, unread_count);
                            }
                            if (read_state < 2) {
                                unread_count[1]++;
                            }
                            if (read_state == 0 || read_state == 2) {
                                unread_count[0]++;
                            }
                        }
                    }
                    if (!DialogObject.isEncryptedDialog(did) && !deleteFiles) {
                        continue;
                    }
                    NativeByteBuffer data = cursor.byteBufferValue(1);
                    if (data != null) {
                        TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
                        message.readAttachPath(data, getUserConfig().clientUserId);
                        data.reuse();
                        addFilesToDelete(message, filesToDelete, idsToDelete, namesToDelete, false);
                    }
                }
            } catch (Exception e) {
                FileLog.e(e);
            }
            cursor.dispose();
            getMessagesStorage().getDatabase().beginTransaction();
            SQLitePreparedStatement state;
            for (int i = 0; i < 2; i++) {
                if (i == 0) {
                    if (dialogId != 0) {
                        state = getMessagesStorage().getDatabase().executeFast("UPDATE messages_v2 SET replydata = ? WHERE reply_to_message_id IN(?) AND uid = ?");
                    } else {
                        state = getMessagesStorage().getDatabase().executeFast("UPDATE messages_v2 SET replydata = ? WHERE reply_to_message_id IN(?) AND is_channel = 0");
                    }
                } else {
                    if (dialogId != 0) {
                        state = getMessagesStorage().getDatabase().executeFast("UPDATE scheduled_messages_v2 SET replydata = ? WHERE reply_to_message_id IN(?) AND uid = ?");
                    } else {
                        state = getMessagesStorage().getDatabase().executeFast("UPDATE scheduled_messages_v2 SET replydata = ? WHERE reply_to_message_id IN(?)");
                    }
                }
                TLRPC.TL_messageEmpty emptyMessage = new TLRPC.TL_messageEmpty();
                NativeByteBuffer data = new NativeByteBuffer(emptyMessage.getObjectSize());
                emptyMessage.serializeToStream(data);
                state.requery();
                state.bindByteBuffer(1, data);
                state.bindString(2, ids);
                if (dialogId != 0) {
                    state.bindLong(3, dialogId);
                }
                state.step();
                state.dispose();
                getMessagesStorage().getDatabase().commitTransaction();
            }
            deleteFromDownloadQueue(idsToDelete, true);
            AndroidUtilities.runOnUIThread(() -> getFileLoader().cancelLoadFiles(namesToDelete));
            getFileLoader().deleteFiles(filesToDelete, 0);
            for (int a = 0; a < dialogsToUpdate.size(); a++) {
                long did = dialogsToUpdate.keyAt(a);
                Integer[] counts = dialogsToUpdate.valueAt(a);
                cursor = database.queryFinalized("SELECT unread_count, unread_count_i FROM dialogs WHERE did = " + did);
                int old_unread_count = 0;
                int old_mentions_count = 0;
                if (cursor.next()) {
                    old_unread_count = cursor.intValue(0);
                    old_mentions_count = cursor.intValue(1);
                }
                cursor.dispose();
                dialogsIds.add(did);
                state = database.executeFast("UPDATE dialogs SET unread_count = ?, unread_count_i = ? WHERE did = ?");
                state.requery();
                state.bindInteger(1, Math.max(0, old_unread_count - counts[0]));
                state.bindInteger(2, Math.max(0, old_mentions_count - counts[1]));
                state.bindLong(3, did);
                state.step();
                state.dispose();
            }
            for (int a = 0, N = messagesByDialogs.size(); a < N; a++) {
                long did = messagesByDialogs.keyAt(a);
                ArrayList<Integer> mids = messagesByDialogs.valueAt(a);
                String idsStr = TextUtils.join(",", mids);
                if (!DialogObject.isEncryptedDialog(did)) {
                    if (DialogObject.isChatDialog(did)) {
                        database.executeFast(String.format(Locale.US, "UPDATE chat_settings_v2 SET pinned = 0 WHERE uid = %d AND pinned IN (%s)", -did, idsStr)).stepThis().dispose();
                    } else {
                        database.executeFast(String.format(Locale.US, "UPDATE user_settings SET pinned = 0 WHERE uid = %d AND pinned IN (%s)", did, idsStr)).stepThis().dispose();
                    }
                }
                database.executeFast(String.format(Locale.US, "DELETE FROM chat_pinned_v2 WHERE uid = %d AND mid IN(%s)", did, idsStr)).stepThis().dispose();
                int updatedCount = 0;
                cursor = database.queryFinalized("SELECT changes()");
                if (cursor.next()) {
                    updatedCount = cursor.intValue(0);
                }
                cursor.dispose();
                if (updatedCount > 0) {
                    cursor = database.queryFinalized(String.format(Locale.US, "SELECT count FROM chat_pinned_count WHERE uid = %d", did));
                    if (cursor.next()) {
                        int count = cursor.intValue(0);
                        state = database.executeFast("UPDATE chat_pinned_count SET count = ? WHERE uid = ?");
                        state.requery();
                        state.bindInteger(1, Math.max(0, count - updatedCount));
                        state.bindLong(2, did);
                        state.step();
                        state.dispose();
                    }
                    cursor.dispose();
                }
                database.executeFast(String.format(Locale.US, "DELETE FROM messages_v2 WHERE mid IN(%s) AND uid = %d", ids, did)).stepThis().dispose();
                database.executeFast(String.format(Locale.US, "DELETE FROM polls_v2 WHERE mid IN(%s) AND uid = %d", ids, did)).stepThis().dispose();
                database.executeFast(String.format(Locale.US, "DELETE FROM bot_keyboard WHERE mid IN(%s) AND uid = %d", ids, did)).stepThis().dispose();
                if (temp.isEmpty()) {
                    cursor = database.queryFinalized(String.format(Locale.US, "SELECT uid, type FROM media_v4 WHERE mid IN(%s) AND uid = %d", ids, did));
                    SparseArray<LongSparseArray<Integer>> mediaCounts = null;
                    while (cursor.next()) {
                        long uid = cursor.longValue(0);
                        int type = cursor.intValue(1);
                        if (mediaCounts == null) {
                            mediaCounts = new SparseArray<>();
                        }
                        LongSparseArray<Integer> counts = mediaCounts.get(type);
                        Integer count;
                        if (counts == null) {
                            counts = new LongSparseArray<>();
                            count = 0;
                            mediaCounts.put(type, counts);
                        } else {
                            count = counts.get(uid);
                        }
                        if (count == null) {
                            count = 0;
                        }
                        count++;
                        counts.put(uid, count);
                    }
                    cursor.dispose();
                    if (mediaCounts != null) {
                        state = database.executeFast("REPLACE INTO media_counts_v2 VALUES(?, ?, ?, ?)");
                        for (int c = 0, N3 = mediaCounts.size(); c < N3; c++) {
                            int type = mediaCounts.keyAt(c);
                            LongSparseArray<Integer> value = mediaCounts.valueAt(c);
                            for (int b = 0, N2 = value.size(); b < N2; b++) {
                                long uid = value.keyAt(b);
                                int count = -1;
                                int old = 0;
                                cursor = database.queryFinalized(String.format(Locale.US, "SELECT count, old FROM media_counts_v2 WHERE uid = %d AND type = %d LIMIT 1", uid, type));
                                if (cursor.next()) {
                                    count = cursor.intValue(0);
                                    old = cursor.intValue(1);
                                }
                                cursor.dispose();
                                if (count != -1) {
                                    state.requery();
                                    count = Math.max(0, count - value.valueAt(b));
                                    state.bindLong(1, uid);
                                    state.bindInteger(2, type);
                                    state.bindInteger(3, count);
                                    state.bindInteger(4, old);
                                    state.step();
                                }
                            }
                        }
                        state.dispose();
                    }
                }
                long time = System.currentTimeMillis();
                database.executeFast(String.format(Locale.US, "DELETE FROM media_v4 WHERE mid IN(%s) AND uid = %d", ids, did)).stepThis().dispose();
            }
            database.executeFast(String.format(Locale.US, "DELETE FROM messages_seq WHERE mid IN(%s)", ids)).stepThis().dispose();
            if (!temp.isEmpty()) {
                if (dialogId == 0) {
                    database.executeFast("UPDATE media_counts_v2 SET old = 1 WHERE 1").stepThis().dispose();
                } else {
                    database.executeFast(String.format(Locale.US, "UPDATE media_counts_v2 SET old = 1 WHERE uid = %d", dialogId)).stepThis().dispose();
                }
            }
            getMediaDataController().clearBotKeyboard(0, messages);
            if (dialogsToUpdate.size() != 0) {
                resetAllUnreadCounters(false);
            }
            updateWidgets(dialogsIds);
        }
        return dialogsIds;
    } catch (Exception e) {
        FileLog.e(e);
    }
    return null;
}
Also used : LongSparseArray(androidx.collection.LongSparseArray) ArrayList(java.util.ArrayList) SQLiteCursor(org.telegram.SQLite.SQLiteCursor) TLRPC(org.telegram.tgnet.TLRPC) SQLitePreparedStatement(org.telegram.SQLite.SQLitePreparedStatement) Pair(android.util.Pair) NativeByteBuffer(org.telegram.tgnet.NativeByteBuffer) SQLiteException(org.telegram.SQLite.SQLiteException) AtomicLong(java.util.concurrent.atomic.AtomicLong) File(java.io.File)

Example 74 with SQLiteCursor

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

the class MessagesStorage method setDialogFlags.

public void setDialogFlags(long did, long flags) {
    storageQueue.postRunnable(() -> {
        try {
            int oldFlags = 0;
            SQLiteCursor cursor = database.queryFinalized("SELECT flags FROM dialog_settings WHERE did = " + did);
            if (cursor.next()) {
                oldFlags = cursor.intValue(0);
            }
            cursor.dispose();
            if (flags == oldFlags) {
                return;
            }
            database.executeFast(String.format(Locale.US, "REPLACE INTO dialog_settings VALUES(%d, %d)", did, flags)).stepThis().dispose();
            resetAllUnreadCounters(true);
        } catch (Exception e) {
            FileLog.e(e);
        }
    });
}
Also used : SQLiteCursor(org.telegram.SQLite.SQLiteCursor) SQLiteException(org.telegram.SQLite.SQLiteException)

Example 75 with SQLiteCursor

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

the class MessagesStorage method emptyMessagesMedia.

public void emptyMessagesMedia(long dialogId, ArrayList<Integer> mids) {
    storageQueue.postRunnable(() -> {
        try {
            ArrayList<File> filesToDelete = new ArrayList<>();
            ArrayList<String> namesToDelete = new ArrayList<>();
            ArrayList<Pair<Long, Integer>> idsToDelete = new ArrayList<>();
            ArrayList<TLRPC.Message> messages = new ArrayList<>();
            SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid, date, uid FROM messages_v2 WHERE mid IN (%s) AND uid = %d", TextUtils.join(",", mids), dialogId));
            while (cursor.next()) {
                NativeByteBuffer data = cursor.byteBufferValue(0);
                if (data != null) {
                    TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
                    message.readAttachPath(data, getUserConfig().clientUserId);
                    data.reuse();
                    if (message.media != null) {
                        if (!addFilesToDelete(message, filesToDelete, idsToDelete, namesToDelete, true)) {
                            continue;
                        } else {
                            if (message.media.document != null) {
                                message.media.document = new TLRPC.TL_documentEmpty();
                            } else if (message.media.photo != null) {
                                message.media.photo = new TLRPC.TL_photoEmpty();
                            }
                        }
                        message.media.flags = message.media.flags & ~1;
                        message.id = cursor.intValue(1);
                        message.date = cursor.intValue(2);
                        message.dialog_id = cursor.longValue(3);
                        messages.add(message);
                    }
                }
            }
            cursor.dispose();
            deleteFromDownloadQueue(idsToDelete, true);
            if (!messages.isEmpty()) {
                SQLitePreparedStatement state = database.executeFast("REPLACE INTO messages_v2 VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, 0)");
                for (int a = 0; a < messages.size(); a++) {
                    TLRPC.Message message = messages.get(a);
                    NativeByteBuffer data = new NativeByteBuffer(message.getObjectSize());
                    message.serializeToStream(data);
                    state.requery();
                    state.bindInteger(1, message.id);
                    state.bindLong(2, message.dialog_id);
                    state.bindInteger(3, MessageObject.getUnreadFlags(message));
                    state.bindInteger(4, message.send_state);
                    state.bindInteger(5, message.date);
                    state.bindByteBuffer(6, data);
                    state.bindInteger(7, (MessageObject.isOut(message) || message.from_scheduled ? 1 : 0));
                    state.bindInteger(8, message.ttl);
                    if ((message.flags & TLRPC.MESSAGE_FLAG_HAS_VIEWS) != 0) {
                        state.bindInteger(9, message.views);
                    } else {
                        state.bindInteger(9, getMessageMediaType(message));
                    }
                    int flags = 0;
                    if (message.stickerVerified == 0) {
                        flags |= 1;
                    } else if (message.stickerVerified == 2) {
                        flags |= 2;
                    }
                    state.bindInteger(10, flags);
                    state.bindInteger(11, message.mentioned ? 1 : 0);
                    state.bindInteger(12, message.forwards);
                    NativeByteBuffer repliesData = null;
                    if (message.replies != null) {
                        repliesData = new NativeByteBuffer(message.replies.getObjectSize());
                        message.replies.serializeToStream(repliesData);
                        state.bindByteBuffer(13, repliesData);
                    } else {
                        state.bindNull(13);
                    }
                    if (message.reply_to != null) {
                        state.bindInteger(14, message.reply_to.reply_to_top_id != 0 ? message.reply_to.reply_to_top_id : message.reply_to.reply_to_msg_id);
                    } else {
                        state.bindInteger(14, 0);
                    }
                    state.bindLong(15, MessageObject.getChannelId(message));
                    state.step();
                    data.reuse();
                    if (repliesData != null) {
                        repliesData.reuse();
                    }
                }
                state.dispose();
                AndroidUtilities.runOnUIThread(() -> {
                    for (int a = 0; a < messages.size(); a++) {
                        getNotificationCenter().postNotificationName(NotificationCenter.updateMessageMedia, messages.get(a));
                    }
                });
            }
            AndroidUtilities.runOnUIThread(() -> getFileLoader().cancelLoadFiles(namesToDelete));
            getFileLoader().deleteFiles(filesToDelete, 0);
        } catch (Exception e) {
            FileLog.e(e);
        }
    });
}
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) File(java.io.File) Pair(android.util.Pair)

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