SQLitePreparedStatementWrapper refactoring

This commit is contained in:
vivabelarus 2025-01-12 22:49:46 +03:00
parent 87f5e51e07
commit 413d688e4d
No known key found for this signature in database
GPG key ID: 49D91FD306D1018E
4 changed files with 65 additions and 39 deletions

View file

@ -0,0 +1,7 @@
package org.telegram.SQLite;
public enum DbSelector {
FILE_DB,
MEMORY_DB,
BOTH_DB
}

View file

@ -3,9 +3,8 @@ package org.telegram.SQLite;
import org.telegram.messenger.partisan.PartisanLog;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class SQLiteDatabaseWrapper extends SQLiteDatabase {
@ -18,11 +17,6 @@ public class SQLiteDatabaseWrapper extends SQLiteDatabase {
private final Set<String> onlyMemoryTables = new HashSet<>(Arrays.asList(
"messages_v2", "chats", "contacts", "dialogs", "messages_holes"
));
private enum DbSelector {
FILE_DB,
MEMORY_DB,
BOTH_DB
}
private final SQLiteDatabase fileDatabase;
private final SQLiteDatabase memoryDatabase;
@ -72,16 +66,16 @@ public class SQLiteDatabaseWrapper extends SQLiteDatabase {
void apply(SQLiteDatabase db) throws SQLiteException;
}
private <R> List<R> executeFunctionInSpecificDB(String sql, DbFunction<R> function) throws SQLiteException {
private <R> Map<DbSelector, R> executeFunctionInSpecificDB(String sql, DbFunction<R> function) throws SQLiteException {
return executeFunctionInSpecificDB(getDbSelectorBySqlQuery(sql), function);
}
private <R> List<R> executeFunctionInSpecificDB(DbSelector dbSelector, DbFunction<R> function) throws SQLiteException {
private <R> Map<DbSelector, R> executeFunctionInSpecificDB(DbSelector dbSelector, DbFunction<R> function) throws SQLiteException {
switch (dbSelector) {
case FILE_DB:
return Collections.singletonList(function.apply(fileDatabase));
return Map.of(dbSelector, function.apply(fileDatabase));
case MEMORY_DB:
return Collections.singletonList(function.apply(memoryDatabase));
return Map.of(dbSelector, function.apply(memoryDatabase));
case BOTH_DB:
default:
R memoryDbResult;
@ -93,7 +87,10 @@ public class SQLiteDatabaseWrapper extends SQLiteDatabase {
throw e;
}
fileDbResult = function.apply(fileDatabase);
return Arrays.asList(memoryDbResult, fileDbResult);
return Map.of(
DbSelector.MEMORY_DB, memoryDbResult,
DbSelector.FILE_DB, fileDbResult
);
}
}
@ -106,17 +103,19 @@ public class SQLiteDatabaseWrapper extends SQLiteDatabase {
@Override
public SQLitePreparedStatement executeFast(String sql) throws SQLiteException {
return new SQLitePreparedStatementMultiple(executeFunctionInSpecificDB(sql, db -> db.executeFast(sql)));
return new SQLitePreparedStatementWrapper(executeFunctionInSpecificDB(sql, db -> db.executeFast(sql)));
}
public SQLitePreparedStatementMultiple executeFastForBothDb(String sql) throws SQLiteException {
return new SQLitePreparedStatementMultiple(executeFunctionInSpecificDB(DbSelector.BOTH_DB, db -> db.executeFast(sql)));
public SQLitePreparedStatementWrapper executeFastForBothDb(String sql) throws SQLiteException {
return new SQLitePreparedStatementWrapper(executeFunctionInSpecificDB(DbSelector.BOTH_DB, db -> db.executeFast(sql)));
}
@Override
public Integer executeInt(String sql, Object... args) throws SQLiteException {
List<Integer> ints = executeFunctionInSpecificDB(sql, db -> db.executeInt(sql, args));
return ints.get(ints.size() - 1);
Map<DbSelector, Integer> ints = executeFunctionInSpecificDB(sql, db -> db.executeInt(sql, args));
return ints.containsKey(DbSelector.FILE_DB)
? ints.get(DbSelector.FILE_DB)
: ints.get(DbSelector.MEMORY_DB);
}
@Override
@ -126,8 +125,10 @@ public class SQLiteDatabaseWrapper extends SQLiteDatabase {
@Override
public SQLiteCursor queryFinalized(String sql, Object... args) throws SQLiteException {
List<SQLiteCursor> cursors = executeFunctionInSpecificDB(sql, db -> db.queryFinalized(sql, args));
return cursors.get(cursors.size() - 1);
Map<DbSelector, SQLiteCursor> cursors = executeFunctionInSpecificDB(sql, db -> db.queryFinalized(sql, args));
return cursors.containsKey(DbSelector.MEMORY_DB)
? cursors.get(DbSelector.MEMORY_DB)
: cursors.get(DbSelector.FILE_DB);
}
@Override

View file

@ -3,18 +3,18 @@ package org.telegram.SQLite;
import org.telegram.tgnet.NativeByteBuffer;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Map;
public class SQLitePreparedStatementMultiple extends SQLitePreparedStatement {
private final List<SQLitePreparedStatement> statements;
private int forceStatementIndex = -1;
public class SQLitePreparedStatementWrapper extends SQLitePreparedStatement {
private final Map<DbSelector, SQLitePreparedStatement> statements;
private DbSelector dbSelector = DbSelector.BOTH_DB;
public SQLitePreparedStatementMultiple(List<SQLitePreparedStatement> statements) {
public SQLitePreparedStatementWrapper(Map<DbSelector, SQLitePreparedStatement> statements) {
this.statements = statements;
}
public void setForcedStatementIndex(int forceStatementIndex) {
this.forceStatementIndex = forceStatementIndex;
public void setDbSelector(DbSelector dbSelector) {
this.dbSelector = dbSelector;
}
private interface StatementFunction<R> {
@ -30,12 +30,13 @@ public class SQLitePreparedStatementMultiple extends SQLitePreparedStatement {
if (statements.isEmpty()) {
throw new RuntimeException();
}
if (forceStatementIndex != -1) {
result = function.apply(statements.get(forceStatementIndex));
} else {
for (SQLitePreparedStatement statement : statements) {
if (dbSelector == DbSelector.BOTH_DB) {
for (SQLitePreparedStatement statement : statements.values()) {
result = function.apply(statement);
}
} else {
result = function.apply(statements.get(dbSelector));
}
return result;
}

View file

@ -29,12 +29,13 @@ import androidx.annotation.UiThread;
import androidx.collection.LongSparseArray;
import org.telegram.PhoneFormat.PhoneFormat;
import org.telegram.SQLite.DbSelector;
import org.telegram.SQLite.SQLiteCursor;
import org.telegram.SQLite.SQLiteDatabase;
import org.telegram.SQLite.SQLiteDatabaseWrapper;
import org.telegram.SQLite.SQLiteException;
import org.telegram.SQLite.SQLitePreparedStatement;
import org.telegram.SQLite.SQLitePreparedStatementMultiple;
import org.telegram.SQLite.SQLitePreparedStatementWrapper;
import org.telegram.messenger.fakepasscode.FakePasscodeUtils;
import org.telegram.messenger.fakepasscode.results.RemoveChatsResult;
import org.telegram.messenger.partisan.PartisanDatabaseMigrationHelper;
@ -4527,7 +4528,9 @@ public class MessagesStorage extends BaseController {
state = database.executeFastForBothDb("REPLACE INTO messages_v2 VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0, ?, ?, ?)");
for (int a = 0; a < messages.size(); a++) {
TLRPC.Message message = messages.get(a);
((SQLitePreparedStatementMultiple)state).setForcedStatementIndex(DialogObject.isEncryptedDialog(message.dialog_id) ? -1 : 0);
if (state instanceof SQLitePreparedStatementWrapper && !DialogObject.isEncryptedDialog(message.dialog_id)) {
((SQLitePreparedStatementWrapper)state).setDbSelector(DbSelector.MEMORY_DB);
}
MessageObject.normalizeFlags(message);
NativeByteBuffer data = new NativeByteBuffer(message.getObjectSize());
@ -9992,7 +9995,9 @@ public class MessagesStorage extends BaseController {
data5.reuse();
if (dialog != null) {
state = database.executeFastForBothDb("REPLACE INTO dialogs VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
((SQLitePreparedStatementMultiple)state).setForcedStatementIndex(DialogObject.isEncryptedDialog(dialog.id) ? -1 : 0);
if (state instanceof SQLitePreparedStatementWrapper && !DialogObject.isEncryptedDialog(dialog.id)) {
((SQLitePreparedStatementWrapper)state).setDbSelector(DbSelector.MEMORY_DB);
}
state.bindLong(1, dialog.id);
state.bindInteger(2, dialog.last_message_date);
state.bindInteger(3, dialog.unread_count);
@ -11662,7 +11667,9 @@ public class MessagesStorage extends BaseController {
for (int a = 0; a < messages.size(); a++) {
TLRPC.Message message = messages.get(a);
((SQLitePreparedStatementMultiple)state_messages).setForcedStatementIndex(DialogObject.isEncryptedDialog(message.dialog_id) ? -1 : 0);
if (state_messages instanceof SQLitePreparedStatementWrapper && !DialogObject.isEncryptedDialog(message.dialog_id)) {
((SQLitePreparedStatementWrapper)state_messages).setDbSelector(DbSelector.MEMORY_DB);
}
int messageId = message.id;
MessageObject.getDialogId(message);
@ -12485,7 +12492,9 @@ public class MessagesStorage extends BaseController {
state_dialogs_update_without_message.step();
}
} else {
((SQLitePreparedStatementMultiple)state_dialogs_replace).setForcedStatementIndex(DialogObject.isEncryptedDialog(message.dialog_id) ? -1 : 0);
if (state_dialogs_replace instanceof SQLitePreparedStatementWrapper && !DialogObject.isEncryptedDialog(message.dialog_id)) {
((SQLitePreparedStatementWrapper)state_dialogs_replace).setDbSelector(DbSelector.MEMORY_DB);
}
state_dialogs_replace.requery();
state_dialogs_replace.bindLong(1, key);
state_dialogs_replace.bindInteger(2, message != null && (!doNotUpdateDialogDate || dialog_date == 0) ? message.date : dialog_date);
@ -14839,7 +14848,9 @@ public class MessagesStorage extends BaseController {
}
} else {
state = database.executeFastForBothDb("REPLACE INTO messages_v2 VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0, ?, ?, ?)");
((SQLitePreparedStatementMultiple)state).setForcedStatementIndex(DialogObject.isEncryptedDialog(message.dialog_id) ? -1 : 0);
if (state instanceof SQLitePreparedStatementWrapper && !DialogObject.isEncryptedDialog(message.dialog_id)) {
((SQLitePreparedStatementWrapper)state).setDbSelector(DbSelector.MEMORY_DB);
}
}
state.requery();
@ -15289,7 +15300,9 @@ public class MessagesStorage extends BaseController {
state3.bindLong(8, dialogId);
} else {
state3 = database.executeFastForBothDb("REPLACE INTO dialogs VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
((SQLitePreparedStatementMultiple)state3).setForcedStatementIndex(DialogObject.isEncryptedDialog(dialogId) ? -1 : 0);
if (state3 instanceof SQLitePreparedStatementWrapper && !DialogObject.isEncryptedDialog(dialogId)) {
((SQLitePreparedStatementWrapper)state3).setDbSelector(DbSelector.MEMORY_DB);
}
state3.bindLong(1, dialogId);
state3.bindInteger(2, message.date);
state3.bindInteger(3, 0);
@ -16273,7 +16286,9 @@ public class MessagesStorage extends BaseController {
TLRPC.Message message = new_dialogMessage.get(dialog.id);
if (message != null) {
((SQLitePreparedStatementMultiple)state_messages).setForcedStatementIndex(DialogObject.isEncryptedDialog(dialog.id) ? -1 : 0);
if (state_messages instanceof SQLitePreparedStatementWrapper && !DialogObject.isEncryptedDialog(dialog.id)) {
((SQLitePreparedStatementWrapper)state_messages).setDbSelector(DbSelector.MEMORY_DB);
}
messageDate = Math.max(message.date, messageDate);
if (isValidKeyboardToSave(message)) {
@ -16378,7 +16393,9 @@ public class MessagesStorage extends BaseController {
}
}
((SQLitePreparedStatementMultiple)state_dialogs).setForcedStatementIndex(DialogObject.isEncryptedDialog(dialog.id) ? -1 : 0);
if (state_dialogs instanceof SQLitePreparedStatementWrapper && !DialogObject.isEncryptedDialog(dialog.id)) {
((SQLitePreparedStatementWrapper)state_dialogs).setDbSelector(DbSelector.MEMORY_DB);
}
state_dialogs.requery();
state_dialogs.bindLong(1, dialog.id);
state_dialogs.bindInteger(2, messageDate);