|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
|
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 package org.mozilla.gecko.db; |
|
6 |
|
7 import org.mozilla.gecko.GeckoAppShell; |
|
8 |
|
9 import android.content.ContentValues; |
|
10 import android.database.sqlite.SQLiteOpenHelper; |
|
11 import android.text.TextUtils; |
|
12 import android.util.Log; |
|
13 |
|
14 public class DBUtils { |
|
15 private static final String LOGTAG = "GeckoDBUtils"; |
|
16 |
|
17 public static final String qualifyColumn(String table, String column) { |
|
18 return table + "." + column; |
|
19 } |
|
20 |
|
21 // This is available in Android >= 11. Implemented locally to be |
|
22 // compatible with older versions. |
|
23 public static String concatenateWhere(String a, String b) { |
|
24 if (TextUtils.isEmpty(a)) { |
|
25 return b; |
|
26 } |
|
27 |
|
28 if (TextUtils.isEmpty(b)) { |
|
29 return a; |
|
30 } |
|
31 |
|
32 return "(" + a + ") AND (" + b + ")"; |
|
33 } |
|
34 |
|
35 // This is available in Android >= 11. Implemented locally to be |
|
36 // compatible with older versions. |
|
37 public static String[] appendSelectionArgs(String[] originalValues, String[] newValues) { |
|
38 if (originalValues == null || originalValues.length == 0) { |
|
39 return newValues; |
|
40 } |
|
41 |
|
42 if (newValues == null || newValues.length == 0) { |
|
43 return originalValues; |
|
44 } |
|
45 |
|
46 String[] result = new String[originalValues.length + newValues.length]; |
|
47 System.arraycopy(originalValues, 0, result, 0, originalValues.length); |
|
48 System.arraycopy(newValues, 0, result, originalValues.length, newValues.length); |
|
49 |
|
50 return result; |
|
51 } |
|
52 |
|
53 public static void replaceKey(ContentValues aValues, String aOriginalKey, |
|
54 String aNewKey, String aDefault) { |
|
55 String value = aDefault; |
|
56 if (aOriginalKey != null && aValues.containsKey(aOriginalKey)) { |
|
57 value = aValues.get(aOriginalKey).toString(); |
|
58 aValues.remove(aOriginalKey); |
|
59 } |
|
60 |
|
61 if (!aValues.containsKey(aNewKey)) { |
|
62 aValues.put(aNewKey, value); |
|
63 } |
|
64 } |
|
65 |
|
66 public static void ensureDatabaseIsNotLocked(SQLiteOpenHelper dbHelper, String databasePath) { |
|
67 for (int retries = 0; retries < 5; retries++) { |
|
68 try { |
|
69 // Try a simple test and exit the loop |
|
70 dbHelper.getWritableDatabase(); |
|
71 return; |
|
72 } catch (Exception e) { |
|
73 // Things could get very bad if we don't find a way to unlock the DB |
|
74 Log.d(LOGTAG, "Database is locked, trying to kill any zombie processes: " + databasePath); |
|
75 GeckoAppShell.killAnyZombies(); |
|
76 try { |
|
77 Thread.sleep(retries * 100); |
|
78 } catch (InterruptedException ie) { } |
|
79 } |
|
80 } |
|
81 Log.d(LOGTAG, "Failed to unlock database"); |
|
82 GeckoAppShell.listOfOpenFiles(); |
|
83 } |
|
84 |
|
85 /** |
|
86 * Verifies that 0-byte arrays aren't added as favicon or thumbnail data. |
|
87 * @param values ContentValues of query |
|
88 * @param columnName Name of data column to verify |
|
89 */ |
|
90 public static void stripEmptyByteArray(ContentValues values, String columnName) { |
|
91 if (values.containsKey(columnName)) { |
|
92 byte[] data = values.getAsByteArray(columnName); |
|
93 if (data == null || data.length == 0) { |
|
94 Log.w(LOGTAG, "Tried to insert an empty or non-byte-array image. Ignoring."); |
|
95 values.putNull(columnName); |
|
96 } |
|
97 } |
|
98 } |
|
99 } |