2011-12-16 15:11:09 -08:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
package org.mozilla.gecko.db;
|
|
|
|
|
2012-04-25 14:24:48 -07:00
|
|
|
import org.mozilla.gecko.GeckoAppShell;
|
2011-12-16 15:11:09 -08:00
|
|
|
import org.mozilla.gecko.sync.Utils;
|
|
|
|
|
|
|
|
import android.content.ContentValues;
|
2012-04-25 14:24:48 -07:00
|
|
|
import android.content.Context;
|
|
|
|
import android.database.sqlite.SQLiteDatabase;
|
|
|
|
import android.database.sqlite.SQLiteOpenHelper;
|
|
|
|
import android.os.Build;
|
2011-12-16 15:11:09 -08:00
|
|
|
import android.text.TextUtils;
|
|
|
|
import android.util.Base64;
|
|
|
|
import android.util.Log;
|
|
|
|
import java.util.UUID;
|
|
|
|
|
|
|
|
import java.util.Random;
|
|
|
|
|
|
|
|
public class DBUtils {
|
2012-04-25 14:24:48 -07:00
|
|
|
private static final String LOGTAG = "GeckoDBUtils";
|
|
|
|
|
2011-12-16 15:11:09 -08:00
|
|
|
public static final String qualifyColumn(String table, String column) {
|
|
|
|
return table + "." + column;
|
|
|
|
}
|
|
|
|
|
|
|
|
// This is available in Android >= 11. Implemented locally to be
|
|
|
|
// compatible with older versions.
|
|
|
|
public static String concatenateWhere(String a, String b) {
|
|
|
|
if (TextUtils.isEmpty(a)) {
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (TextUtils.isEmpty(b)) {
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
|
|
|
return "(" + a + ") AND (" + b + ")";
|
|
|
|
}
|
|
|
|
|
|
|
|
// This is available in Android >= 11. Implemented locally to be
|
|
|
|
// compatible with older versions.
|
|
|
|
public static String[] appendSelectionArgs(String[] originalValues, String[] newValues) {
|
|
|
|
if (originalValues == null || originalValues.length == 0) {
|
|
|
|
return newValues;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (newValues == null || newValues.length == 0) {
|
|
|
|
return originalValues;
|
|
|
|
}
|
|
|
|
|
|
|
|
String[] result = new String[originalValues.length + newValues.length];
|
|
|
|
System.arraycopy(originalValues, 0, result, 0, originalValues.length);
|
|
|
|
System.arraycopy(newValues, 0, result, originalValues.length, newValues.length);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void replaceKey(ContentValues aValues, String aOriginalKey,
|
|
|
|
String aNewKey, String aDefault) {
|
|
|
|
String value = aDefault;
|
|
|
|
if (aOriginalKey != null && aValues.containsKey(aOriginalKey)) {
|
|
|
|
value = aValues.get(aOriginalKey).toString();
|
|
|
|
aValues.remove(aOriginalKey);
|
|
|
|
}
|
|
|
|
|
2012-03-08 10:25:44 -08:00
|
|
|
if (!aValues.containsKey(aNewKey)) {
|
2011-12-16 15:11:09 -08:00
|
|
|
aValues.put(aNewKey, value);
|
|
|
|
}
|
|
|
|
}
|
2012-04-25 14:24:48 -07:00
|
|
|
|
|
|
|
public static void ensureDatabaseIsNotLocked(SQLiteOpenHelper dbHelper, String databasePath) {
|
|
|
|
SQLiteDatabase db = dbHelper.getWritableDatabase();
|
|
|
|
|
|
|
|
// The returned writable database is read-only, this probably means that the
|
|
|
|
// database is permanently locked due to a crash or a non-clean quit in Fennec.
|
|
|
|
// We can assume it's safe to forcefully unlock the database file in this case
|
|
|
|
// as all database access happens through this content provider (see bug 741718).
|
|
|
|
if (db.isReadOnly()) {
|
|
|
|
// Close read-only connection, we don't want to use it
|
|
|
|
dbHelper.close();
|
|
|
|
|
|
|
|
Log.d(LOGTAG, "Database is in read-only mode, trying to forcefully unlock the database file: " + databasePath);
|
|
|
|
|
|
|
|
// Forcefully unlock the database file
|
|
|
|
GeckoAppShell.unlockDatabaseFile(databasePath);
|
|
|
|
|
|
|
|
// TODO: maybe check if the connection is still read-only and let the
|
|
|
|
// user know that the device needs rebooting?
|
|
|
|
}
|
|
|
|
}
|
2011-12-16 15:11:09 -08:00
|
|
|
}
|