147 lines
4.2 KiB
Java
147 lines
4.2 KiB
Java
package org.thoughtcrime.securesms.util;
|
|
|
|
import android.content.ContentValues;
|
|
import android.database.Cursor;
|
|
|
|
import androidx.annotation.NonNull;
|
|
|
|
import net.sqlcipher.database.SQLiteDatabase;
|
|
|
|
import org.thoughtcrime.securesms.recipients.RecipientId;
|
|
import org.whispersystems.libsignal.util.guava.Preconditions;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Collection;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
|
|
public final class SqlUtil {
|
|
private SqlUtil() {}
|
|
|
|
|
|
public static boolean tableExists(@NonNull SQLiteDatabase db, @NonNull String table) {
|
|
try (Cursor cursor = db.rawQuery("SELECT name FROM sqlite_master WHERE type=? AND name=?", new String[] { "table", table })) {
|
|
return cursor != null && cursor.moveToNext();
|
|
}
|
|
}
|
|
|
|
public static boolean columnExists(@NonNull SQLiteDatabase db, @NonNull String table, @NonNull String column) {
|
|
try (Cursor cursor = db.rawQuery("PRAGMA table_info(" + table + ")", null)) {
|
|
int nameColumnIndex = cursor.getColumnIndexOrThrow("name");
|
|
|
|
while (cursor.moveToNext()) {
|
|
String name = cursor.getString(nameColumnIndex);
|
|
|
|
if (name.equals(column)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public static String[] buildArgs(Object... objects) {
|
|
String[] args = new String[objects.length];
|
|
|
|
for (int i = 0; i < objects.length; i++) {
|
|
if (objects[i] == null) {
|
|
throw new NullPointerException("Cannot have null arg!");
|
|
} else if (objects[i] instanceof RecipientId) {
|
|
args[i] = ((RecipientId) objects[i]).serialize();
|
|
} else {
|
|
args[i] = objects[i].toString();
|
|
}
|
|
}
|
|
|
|
return args;
|
|
}
|
|
|
|
/**
|
|
* Returns an updated query and args pairing that will only update rows that would *actually*
|
|
* change. In other words, if {@link SQLiteDatabase#update(String, ContentValues, String, String[])}
|
|
* returns > 0, then you know something *actually* changed.
|
|
*/
|
|
public static @NonNull Query buildTrueUpdateQuery(@NonNull String selection,
|
|
@NonNull String[] args,
|
|
@NonNull ContentValues contentValues)
|
|
{
|
|
StringBuilder qualifier = new StringBuilder();
|
|
Set<Map.Entry<String, Object>> valueSet = contentValues.valueSet();
|
|
List<String> fullArgs = new ArrayList<>(args.length + valueSet.size());
|
|
|
|
fullArgs.addAll(Arrays.asList(args));
|
|
|
|
int i = 0;
|
|
|
|
for (Map.Entry<String, Object> entry : valueSet) {
|
|
if (entry.getValue() != null) {
|
|
qualifier.append(entry.getKey()).append(" != ? OR ").append(entry.getKey()).append(" IS NULL");
|
|
fullArgs.add(String.valueOf(entry.getValue()));
|
|
} else {
|
|
qualifier.append(entry.getKey()).append(" NOT NULL");
|
|
}
|
|
|
|
if (i != valueSet.size() - 1) {
|
|
qualifier.append(" OR ");
|
|
}
|
|
|
|
i++;
|
|
}
|
|
|
|
return new Query("(" + selection + ") AND (" + qualifier + ")", fullArgs.toArray(new String[0]));
|
|
}
|
|
|
|
public static @NonNull Query buildCollectionQuery(@NonNull String column, @NonNull Collection<? extends Object> values) {
|
|
Preconditions.checkArgument(values.size() > 0);
|
|
|
|
StringBuilder query = new StringBuilder();
|
|
Object[] args = new Object[values.size()];
|
|
|
|
int i = 0;
|
|
|
|
for (Object value : values) {
|
|
query.append("?");
|
|
args[i] = value;
|
|
|
|
if (i != values.size() - 1) {
|
|
query.append(", ");
|
|
}
|
|
|
|
i++;
|
|
}
|
|
|
|
return new Query(column + " IN (" + query.toString() + ")", buildArgs(args));
|
|
}
|
|
|
|
public static String[] appendArg(@NonNull String[] args, String addition) {
|
|
String[] output = new String[args.length + 1];
|
|
|
|
System.arraycopy(args, 0, output, 0, args.length);
|
|
output[output.length - 1] = addition;
|
|
|
|
return output;
|
|
}
|
|
|
|
public static class Query {
|
|
private final String where;
|
|
private final String[] whereArgs;
|
|
|
|
private Query(@NonNull String where, @NonNull String[] whereArgs) {
|
|
this.where = where;
|
|
this.whereArgs = whereArgs;
|
|
}
|
|
|
|
public String getWhere() {
|
|
return where;
|
|
}
|
|
|
|
public String[] getWhereArgs() {
|
|
return whereArgs;
|
|
}
|
|
}
|
|
}
|