Skip to content

Commit 3507936

Browse files
Add support for rawQuery to binding parameters via an Object array.
1 parent 1176881 commit 3507936

File tree

3 files changed

+106
-2
lines changed

3 files changed

+106
-2
lines changed

src/net/sqlcipher/database/SQLiteDatabase.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1785,6 +1785,53 @@ public Cursor rawQuery(String sql, String[] selectionArgs) {
17851785
return rawQueryWithFactory(null, sql, selectionArgs, null);
17861786
}
17871787

1788+
1789+
/**
1790+
* Runs the provided SQL and returns a {@link Cursor} over the result set.
1791+
*
1792+
* @param sql the SQL query. The SQL string must not be ; terminated
1793+
* @param args You may include ?s in where clause in the query,
1794+
* which will be replaced by the values from args. The
1795+
* values will be bound by their type.
1796+
*
1797+
* @return A {@link Cursor} object, which is positioned before the first entry. Note that
1798+
* {@link Cursor}s are not synchronized, see the documentation for more details.
1799+
*
1800+
* @throws SQLiteException if there is an issue executing the sql or the SQL string is invalid
1801+
* @throws IllegalStateException if the database is not open
1802+
*/
1803+
public Cursor rawQuery(String sql, Object[] args) {
1804+
if (!isOpen()) {
1805+
throw new IllegalStateException("database not open");
1806+
}
1807+
long timeStart = 0;
1808+
if (Config.LOGV || mSlowQueryThreshold != -1) {
1809+
timeStart = System.currentTimeMillis();
1810+
}
1811+
SQLiteDirectCursorDriver driver = new SQLiteDirectCursorDriver(this, sql, null);
1812+
Cursor cursor = null;
1813+
try {
1814+
cursor = driver.query(mFactory, args);
1815+
} finally {
1816+
if (Config.LOGV || mSlowQueryThreshold != -1) {
1817+
// Force query execution
1818+
int count = -1;
1819+
if (cursor != null) {
1820+
count = cursor.getCount();
1821+
}
1822+
1823+
long duration = System.currentTimeMillis() - timeStart;
1824+
1825+
if (Config.LOGV || duration >= mSlowQueryThreshold) {
1826+
Log.v(TAG,
1827+
"query (" + duration + " ms): " + driver.toString() +
1828+
", args are <redacted>, count is " + count);
1829+
}
1830+
}
1831+
}
1832+
return new CrossProcessCursorWrapper(cursor);
1833+
}
1834+
17881835
/**
17891836
* Runs the provided SQL and returns a cursor over the result set.
17901837
*

src/net/sqlcipher/database/SQLiteDirectCursorDriver.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,24 @@ public SQLiteDirectCursorDriver(SQLiteDatabase db, String sql, String editTable)
3737
mSql = sql;
3838
}
3939

40+
public Cursor query(CursorFactory factory, Object[] args) {
41+
SQLiteQuery query = new SQLiteQuery(mDatabase, mSql, 0, args);
42+
try {
43+
query.bindArguments(args);
44+
if (factory == null) {
45+
mCursor = new SQLiteCursor(mDatabase, this, mEditTable, query);
46+
} else {
47+
mCursor = factory.newCursor(mDatabase, this, mEditTable, query);
48+
}
49+
mQuery = query;
50+
query = null;
51+
return mCursor;
52+
} finally {
53+
// Make sure this object is cleaned up if something happens
54+
if (query != null) query.close();
55+
}
56+
}
57+
4058
public Cursor query(CursorFactory factory, String[] selectionArgs) {
4159
// Compile the query
4260
SQLiteQuery query = new SQLiteQuery(mDatabase, mSql, 0, selectionArgs);

src/net/sqlcipher/database/SQLiteQuery.java

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public class SQLiteQuery extends SQLiteProgram {
3535

3636
/** Args to bind on requery */
3737
private String[] mBindArgs;
38+
private Object[] mObjectBindArgs;
3839

3940
private boolean mClosed = false;
4041

@@ -52,6 +53,13 @@ public class SQLiteQuery extends SQLiteProgram {
5253
mBindArgs = bindArgs;
5354
}
5455

56+
SQLiteQuery(SQLiteDatabase db, String query, int offsetIndex, Object[] bindArgs) {
57+
super(db, query);
58+
mOffsetIndex = offsetIndex;
59+
mObjectBindArgs = bindArgs;
60+
mBindArgs = new String[mObjectBindArgs.length];
61+
}
62+
5563
/**
5664
* Reads rows into a buffer. This method acquires the database lock.
5765
*
@@ -142,8 +150,12 @@ public void close() {
142150
if (mBindArgs != null) {
143151
int len = mBindArgs.length;
144152
try {
145-
for (int i = 0; i < len; i++) {
146-
super.bindString(i + 1, mBindArgs[i]);
153+
if(mObjectBindArgs != null) {
154+
bindArguments(mObjectBindArgs);
155+
} else {
156+
for (int i = 0; i < len; i++) {
157+
super.bindString(i + 1, mBindArgs[i]);
158+
}
147159
}
148160
} catch (SQLiteMisuseException e) {
149161
StringBuilder errMsg = new StringBuilder("mSql " + mSql);
@@ -183,6 +195,33 @@ public void bindString(int index, String value) {
183195
if (!mClosed) super.bindString(index, value);
184196
}
185197

198+
public void bindArguments(Object[] args){
199+
if(args != null && args.length > 0){
200+
for(int i = 0; i < args.length; i++){
201+
Object value = args[i];
202+
if(value == null){
203+
bindNull(i + 1);
204+
} else if (value instanceof Double) {
205+
bindDouble(i + 1, (Double)value);
206+
} else if (value instanceof Float) {
207+
float number = ((Number)value).floatValue();
208+
bindDouble(i + 1, new Double(number));
209+
} else if (value instanceof Long) {
210+
bindLong(i + 1, (Long)value);
211+
} else if(value instanceof Integer) {
212+
int number = ((Number) value).intValue();
213+
bindLong(i + 1, new Long(number));
214+
} else if (value instanceof Boolean) {
215+
bindLong(i + 1, (Boolean)value ? 1 : 0);
216+
} else if (value instanceof byte[]) {
217+
bindBlob(i + 1, (byte[])value);
218+
} else {
219+
bindString(i + 1, value.toString());
220+
}
221+
}
222+
}
223+
}
224+
186225
private final native int native_fill_window(CursorWindow window,
187226
int startPos, int offsetParam, int maxRead, int lastPos);
188227

0 commit comments

Comments
 (0)