michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: package org.mozilla.gecko.db; michael@0: michael@0: import org.mozilla.gecko.GeckoAppShell; michael@0: michael@0: import android.content.ContentValues; michael@0: import android.database.sqlite.SQLiteOpenHelper; michael@0: import android.text.TextUtils; michael@0: import android.util.Log; michael@0: michael@0: public class DBUtils { michael@0: private static final String LOGTAG = "GeckoDBUtils"; michael@0: michael@0: public static final String qualifyColumn(String table, String column) { michael@0: return table + "." + column; michael@0: } michael@0: michael@0: // This is available in Android >= 11. Implemented locally to be michael@0: // compatible with older versions. michael@0: public static String concatenateWhere(String a, String b) { michael@0: if (TextUtils.isEmpty(a)) { michael@0: return b; michael@0: } michael@0: michael@0: if (TextUtils.isEmpty(b)) { michael@0: return a; michael@0: } michael@0: michael@0: return "(" + a + ") AND (" + b + ")"; michael@0: } michael@0: michael@0: // This is available in Android >= 11. Implemented locally to be michael@0: // compatible with older versions. michael@0: public static String[] appendSelectionArgs(String[] originalValues, String[] newValues) { michael@0: if (originalValues == null || originalValues.length == 0) { michael@0: return newValues; michael@0: } michael@0: michael@0: if (newValues == null || newValues.length == 0) { michael@0: return originalValues; michael@0: } michael@0: michael@0: String[] result = new String[originalValues.length + newValues.length]; michael@0: System.arraycopy(originalValues, 0, result, 0, originalValues.length); michael@0: System.arraycopy(newValues, 0, result, originalValues.length, newValues.length); michael@0: michael@0: return result; michael@0: } michael@0: michael@0: public static void replaceKey(ContentValues aValues, String aOriginalKey, michael@0: String aNewKey, String aDefault) { michael@0: String value = aDefault; michael@0: if (aOriginalKey != null && aValues.containsKey(aOriginalKey)) { michael@0: value = aValues.get(aOriginalKey).toString(); michael@0: aValues.remove(aOriginalKey); michael@0: } michael@0: michael@0: if (!aValues.containsKey(aNewKey)) { michael@0: aValues.put(aNewKey, value); michael@0: } michael@0: } michael@0: michael@0: public static void ensureDatabaseIsNotLocked(SQLiteOpenHelper dbHelper, String databasePath) { michael@0: for (int retries = 0; retries < 5; retries++) { michael@0: try { michael@0: // Try a simple test and exit the loop michael@0: dbHelper.getWritableDatabase(); michael@0: return; michael@0: } catch (Exception e) { michael@0: // Things could get very bad if we don't find a way to unlock the DB michael@0: Log.d(LOGTAG, "Database is locked, trying to kill any zombie processes: " + databasePath); michael@0: GeckoAppShell.killAnyZombies(); michael@0: try { michael@0: Thread.sleep(retries * 100); michael@0: } catch (InterruptedException ie) { } michael@0: } michael@0: } michael@0: Log.d(LOGTAG, "Failed to unlock database"); michael@0: GeckoAppShell.listOfOpenFiles(); michael@0: } michael@0: michael@0: /** michael@0: * Verifies that 0-byte arrays aren't added as favicon or thumbnail data. michael@0: * @param values ContentValues of query michael@0: * @param columnName Name of data column to verify michael@0: */ michael@0: public static void stripEmptyByteArray(ContentValues values, String columnName) { michael@0: if (values.containsKey(columnName)) { michael@0: byte[] data = values.getAsByteArray(columnName); michael@0: if (data == null || data.length == 0) { michael@0: Log.w(LOGTAG, "Tried to insert an empty or non-byte-array image. Ignoring."); michael@0: values.putNull(columnName); michael@0: } michael@0: } michael@0: } michael@0: }