Convert MentionTable to kotlin.
This commit is contained in:
parent
791dc2724f
commit
9bd4e9524c
2 changed files with 174 additions and 176 deletions
|
@ -1,176 +0,0 @@
|
|||
package org.thoughtcrime.securesms.database;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.annimon.stream.Stream;
|
||||
|
||||
import org.thoughtcrime.securesms.database.model.Mention;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.signal.core.util.CursorUtil;
|
||||
import org.signal.core.util.SqlUtil;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class MentionTable extends DatabaseTable implements RecipientIdDatabaseReference, ThreadIdDatabaseReference {
|
||||
|
||||
public static final String TABLE_NAME = "mention";
|
||||
|
||||
private static final String ID = "_id";
|
||||
static final String THREAD_ID = "thread_id";
|
||||
public static final String MESSAGE_ID = "message_id";
|
||||
static final String RECIPIENT_ID = "recipient_id";
|
||||
private static final String RANGE_START = "range_start";
|
||||
private static final String RANGE_LENGTH = "range_length";
|
||||
|
||||
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + "(" + ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
|
||||
THREAD_ID + " INTEGER, " +
|
||||
MESSAGE_ID + " INTEGER, " +
|
||||
RECIPIENT_ID + " INTEGER, " +
|
||||
RANGE_START + " INTEGER, " +
|
||||
RANGE_LENGTH + " INTEGER)";
|
||||
|
||||
public static final String[] CREATE_INDEXES = new String[] {
|
||||
"CREATE INDEX IF NOT EXISTS mention_message_id_index ON " + TABLE_NAME + " (" + MESSAGE_ID + ");",
|
||||
"CREATE INDEX IF NOT EXISTS mention_recipient_id_thread_id_index ON " + TABLE_NAME + " (" + RECIPIENT_ID + ", " + THREAD_ID + ");"
|
||||
};
|
||||
|
||||
public MentionTable(@NonNull Context context, @NonNull SignalDatabase databaseHelper) {
|
||||
super(context, databaseHelper);
|
||||
}
|
||||
|
||||
public void insert(long threadId, long messageId, @NonNull Collection<Mention> mentions) {
|
||||
SQLiteDatabase db = databaseHelper.getSignalWritableDatabase();
|
||||
|
||||
db.beginTransaction();
|
||||
try {
|
||||
for (Mention mention : mentions) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(THREAD_ID, threadId);
|
||||
values.put(MESSAGE_ID, messageId);
|
||||
values.put(RECIPIENT_ID, mention.getRecipientId().toLong());
|
||||
values.put(RANGE_START, mention.getStart());
|
||||
values.put(RANGE_LENGTH, mention.getLength());
|
||||
db.insert(TABLE_NAME, null, values);
|
||||
}
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
public @NonNull List<Mention> getMentionsForMessage(long messageId) {
|
||||
SQLiteDatabase db = databaseHelper.getSignalReadableDatabase();
|
||||
List<Mention> mentions = new LinkedList<>();
|
||||
|
||||
try (Cursor cursor = db.query(TABLE_NAME, null, MESSAGE_ID + " = ?", SqlUtil.buildArgs(messageId), null, null, null)) {
|
||||
while (cursor != null && cursor.moveToNext()) {
|
||||
mentions.add(new Mention(RecipientId.from(CursorUtil.requireLong(cursor, RECIPIENT_ID)),
|
||||
CursorUtil.requireInt(cursor, RANGE_START),
|
||||
CursorUtil.requireInt(cursor, RANGE_LENGTH)));
|
||||
}
|
||||
}
|
||||
|
||||
return mentions;
|
||||
}
|
||||
|
||||
public @NonNull Map<Long, List<Mention>> getMentionsForMessages(@NonNull Collection<Long> messageIds) {
|
||||
SQLiteDatabase db = databaseHelper.getSignalReadableDatabase();
|
||||
String ids = TextUtils.join(",", messageIds);
|
||||
|
||||
try (Cursor cursor = db.query(TABLE_NAME, null, MESSAGE_ID + " IN (" + ids + ")", null, null, null, null)) {
|
||||
return readMentions(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
public @NonNull Map<Long, List<Mention>> getMentionsContainingRecipients(@NonNull Collection<RecipientId> recipientIds, long limit) {
|
||||
return getMentionsContainingRecipients(recipientIds, -1, limit);
|
||||
}
|
||||
|
||||
public @NonNull Map<Long, List<Mention>> getMentionsContainingRecipients(@NonNull Collection<RecipientId> recipientIds, long threadId, long limit) {
|
||||
SQLiteDatabase db = databaseHelper.getSignalReadableDatabase();
|
||||
String ids = TextUtils.join(",", Stream.of(recipientIds).map(RecipientId::serialize).toList());
|
||||
|
||||
String where = " WHERE " + RECIPIENT_ID + " IN (" + ids + ")";
|
||||
if (threadId != -1) {
|
||||
where += " AND " + THREAD_ID + " = " + threadId;
|
||||
}
|
||||
|
||||
String subSelect = "SELECT DISTINCT " + MESSAGE_ID +
|
||||
" FROM " + TABLE_NAME +
|
||||
where +
|
||||
" ORDER BY " + ID + " DESC" +
|
||||
" LIMIT " + limit;
|
||||
|
||||
String query = "SELECT *" +
|
||||
" FROM " + TABLE_NAME +
|
||||
" WHERE " + MESSAGE_ID +
|
||||
" IN (" + subSelect + ")";
|
||||
|
||||
try (Cursor cursor = db.rawQuery(query, null)) {
|
||||
return readMentions(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
void deleteMentionsForMessage(long messageId) {
|
||||
SQLiteDatabase db = databaseHelper.getSignalWritableDatabase();
|
||||
String where = MESSAGE_ID + " = ?";
|
||||
|
||||
db.delete(TABLE_NAME, where, SqlUtil.buildArgs(messageId));
|
||||
}
|
||||
|
||||
void deleteAbandonedMentions() {
|
||||
SQLiteDatabase db = databaseHelper.getSignalWritableDatabase();
|
||||
String where = MESSAGE_ID + " NOT IN (SELECT " + MessageTable.ID + " FROM " + MessageTable.TABLE_NAME + ") OR " + THREAD_ID + " NOT IN (SELECT " + ThreadTable.ID + " FROM " + ThreadTable.TABLE_NAME + " WHERE " + ThreadTable.ACTIVE + " = 1)";
|
||||
|
||||
db.delete(TABLE_NAME, where, null);
|
||||
}
|
||||
|
||||
void deleteAllMentions() {
|
||||
SQLiteDatabase db = databaseHelper.getSignalWritableDatabase();
|
||||
db.delete(TABLE_NAME, null, null);
|
||||
}
|
||||
|
||||
private @NonNull Map<Long, List<Mention>> readMentions(@Nullable Cursor cursor) {
|
||||
Map<Long, List<Mention>> mentions = new HashMap<>();
|
||||
while (cursor != null && cursor.moveToNext()) {
|
||||
long messageId = CursorUtil.requireLong(cursor, MESSAGE_ID);
|
||||
List<Mention> messageMentions = mentions.get(messageId);
|
||||
|
||||
if (messageMentions == null) {
|
||||
messageMentions = new LinkedList<>();
|
||||
mentions.put(messageId, messageMentions);
|
||||
}
|
||||
|
||||
messageMentions.add(new Mention(RecipientId.from(CursorUtil.requireLong(cursor, RECIPIENT_ID)),
|
||||
CursorUtil.requireInt(cursor, RANGE_START),
|
||||
CursorUtil.requireInt(cursor, RANGE_LENGTH)));
|
||||
}
|
||||
return mentions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remapRecipient(@NonNull RecipientId fromId, @NonNull RecipientId toId) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(RECIPIENT_ID, toId.serialize());
|
||||
getWritableDatabase().update(TABLE_NAME, values, RECIPIENT_ID + " = ?", SqlUtil.buildArgs(fromId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remapThread(long fromId, long toId) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(MentionTable.THREAD_ID, toId);
|
||||
|
||||
getWritableDatabase().update(TABLE_NAME, values, THREAD_ID + " = ?", SqlUtil.buildArgs(fromId));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,174 @@
|
|||
package org.thoughtcrime.securesms.database
|
||||
|
||||
import android.content.Context
|
||||
import android.database.Cursor
|
||||
import org.signal.core.util.delete
|
||||
import org.signal.core.util.deleteAll
|
||||
import org.signal.core.util.insertInto
|
||||
import org.signal.core.util.readToList
|
||||
import org.signal.core.util.requireInt
|
||||
import org.signal.core.util.requireLong
|
||||
import org.signal.core.util.select
|
||||
import org.signal.core.util.update
|
||||
import org.signal.core.util.withinTransaction
|
||||
import org.thoughtcrime.securesms.database.model.Mention
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
|
||||
class MentionTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTable(context, databaseHelper), RecipientIdDatabaseReference, ThreadIdDatabaseReference {
|
||||
|
||||
companion object {
|
||||
const val TABLE_NAME = "mention"
|
||||
const val ID = "_id"
|
||||
const val THREAD_ID = "thread_id"
|
||||
const val MESSAGE_ID = "message_id"
|
||||
const val RECIPIENT_ID = "recipient_id"
|
||||
const val RANGE_START = "range_start"
|
||||
const val RANGE_LENGTH = "range_length"
|
||||
|
||||
const val CREATE_TABLE = """
|
||||
CREATE TABLE $TABLE_NAME(
|
||||
$ID INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
$THREAD_ID INTEGER,
|
||||
$MESSAGE_ID INTEGER,
|
||||
$RECIPIENT_ID INTEGER,
|
||||
$RANGE_START INTEGER,
|
||||
$RANGE_LENGTH INTEGER
|
||||
)
|
||||
"""
|
||||
|
||||
val CREATE_INDEXES = arrayOf(
|
||||
"CREATE INDEX IF NOT EXISTS mention_message_id_index ON $TABLE_NAME ($MESSAGE_ID);",
|
||||
"CREATE INDEX IF NOT EXISTS mention_recipient_id_thread_id_index ON $TABLE_NAME ($RECIPIENT_ID, $THREAD_ID);"
|
||||
)
|
||||
}
|
||||
|
||||
fun insert(threadId: Long, messageId: Long, mentions: Collection<Mention>) {
|
||||
writableDatabase.withinTransaction { db ->
|
||||
for (mention in mentions) {
|
||||
db.insertInto(TABLE_NAME)
|
||||
.values(
|
||||
THREAD_ID to threadId,
|
||||
MESSAGE_ID to messageId,
|
||||
RECIPIENT_ID to mention.recipientId.toLong(),
|
||||
RANGE_START to mention.start,
|
||||
RANGE_LENGTH to mention.length
|
||||
)
|
||||
.run()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getMentionsForMessage(messageId: Long): List<Mention> {
|
||||
return readableDatabase
|
||||
.select()
|
||||
.from(TABLE_NAME)
|
||||
.where("$MESSAGE_ID = $messageId")
|
||||
.run()
|
||||
.readToList { cursor ->
|
||||
Mention(
|
||||
RecipientId.from(cursor.requireLong(RECIPIENT_ID)),
|
||||
cursor.requireInt(RANGE_START),
|
||||
cursor.requireInt(RANGE_LENGTH)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun getMentionsForMessages(messageIds: Collection<Long>): Map<Long, List<Mention>> {
|
||||
val ids = messageIds.joinToString(separator = ",") { it.toString() }
|
||||
|
||||
return readableDatabase
|
||||
.select()
|
||||
.from(TABLE_NAME)
|
||||
.where("$MESSAGE_ID IN ($ids)")
|
||||
.run()
|
||||
.use { cursor -> readMentions(cursor) }
|
||||
}
|
||||
|
||||
fun getMentionsContainingRecipients(recipientIds: Collection<RecipientId>, limit: Long): Map<Long, List<Mention>> {
|
||||
return getMentionsContainingRecipients(recipientIds, -1, limit)
|
||||
}
|
||||
|
||||
fun getMentionsContainingRecipients(recipientIds: Collection<RecipientId>, threadId: Long, limit: Long): Map<Long, List<Mention>> {
|
||||
val ids = recipientIds.joinToString(separator = ",") { it.serialize() }
|
||||
|
||||
var where = "$RECIPIENT_ID IN ($ids)"
|
||||
if (threadId != -1L) {
|
||||
where += " AND $THREAD_ID = $threadId"
|
||||
}
|
||||
|
||||
return readableDatabase
|
||||
.select()
|
||||
.from(TABLE_NAME)
|
||||
.where(
|
||||
"""
|
||||
$MESSAGE_ID IN (
|
||||
SELECT DISTINCT $MESSAGE_ID
|
||||
FROM $TABLE_NAME
|
||||
WHERE $where
|
||||
ORDER BY $ID DESC LIMIT $limit
|
||||
)
|
||||
"""
|
||||
)
|
||||
.run()
|
||||
.use { cursor -> readMentions(cursor) }
|
||||
}
|
||||
|
||||
fun deleteMentionsForMessage(messageId: Long) {
|
||||
writableDatabase
|
||||
.delete(TABLE_NAME)
|
||||
.where("$MESSAGE_ID = $messageId")
|
||||
.run()
|
||||
}
|
||||
|
||||
fun deleteAbandonedMentions() {
|
||||
writableDatabase
|
||||
.delete(TABLE_NAME)
|
||||
.where(
|
||||
"""
|
||||
$MESSAGE_ID NOT IN (
|
||||
SELECT $MessageTable.ID
|
||||
FROM ${MessageTable.TABLE_NAME}
|
||||
)
|
||||
OR $THREAD_ID NOT IN (
|
||||
SELECT ${ThreadTable.ID}
|
||||
FROM ${ThreadTable.TABLE_NAME}
|
||||
WHERE ${ThreadTable.ACTIVE} = 1
|
||||
)
|
||||
"""
|
||||
)
|
||||
.run()
|
||||
}
|
||||
|
||||
fun deleteAllMentions() {
|
||||
writableDatabase.deleteAll(TABLE_NAME)
|
||||
}
|
||||
|
||||
private fun readMentions(cursor: Cursor): Map<Long, List<Mention>> {
|
||||
return cursor.readToList {
|
||||
val messageId = it.requireLong(MESSAGE_ID)
|
||||
val mention = Mention(
|
||||
RecipientId.from(it.requireLong(RECIPIENT_ID)),
|
||||
it.requireInt(RANGE_START),
|
||||
it.requireInt(RANGE_LENGTH)
|
||||
)
|
||||
|
||||
messageId to mention
|
||||
}.groupBy({ it.first }, { it.second })
|
||||
}
|
||||
|
||||
override fun remapRecipient(fromId: RecipientId, toId: RecipientId) {
|
||||
writableDatabase
|
||||
.update(TABLE_NAME)
|
||||
.values(RECIPIENT_ID to toId.serialize())
|
||||
.where("$RECIPIENT_ID = ?", fromId)
|
||||
.run()
|
||||
}
|
||||
|
||||
override fun remapThread(fromId: Long, toId: Long) {
|
||||
writableDatabase
|
||||
.update(TABLE_NAME)
|
||||
.values(THREAD_ID to toId)
|
||||
.where("$THREAD_ID = $fromId")
|
||||
.run()
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue