Skip to content

Add cursor changes to get the type of retrieved data (API 11) #80

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 2, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions jni/net_sqlcipher_CursorWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,22 @@ LOG_WINDOW("Checking if column is an integer for %d,%d from %p", row, column, wi
return field.type == FIELD_TYPE_INTEGER;
}

static jint getType_native(JNIEnv* env, jobject object, jint row, jint column)
{
int32_t err;
CursorWindow * window = GET_WINDOW(env, object);
LOG_WINDOW("Getting type for %d,%d from %p", row, column, window);

field_slot_t field;
err = window->read_field_slot(row, column, &field);
if (err != 0) {
throwExceptionWithRowCol(env, row, column);
return NULL;
}

return field.type;
}

static jboolean isFloat_native(JNIEnv* env, jobject object, jint row, jint column)
{
int32_t err;
Expand Down Expand Up @@ -677,6 +693,7 @@ static JNINativeMethod sMethods[] =
{"isString_native", "(II)Z", (void *)isString_native},
{"isFloat_native", "(II)Z", (void *)isFloat_native},
{"isInteger_native", "(II)Z", (void *)isInteger_native},
{"getType_native", "(II)I", (void *)getType_native},
};

int register_android_database_CursorWindow(JNIEnv * env)
Expand Down
18 changes: 17 additions & 1 deletion src/net/sqlcipher/AbstractCursor.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ public abstract class AbstractCursor implements android.database.CrossProcessCur
abstract public double getDouble(int column);
abstract public boolean isNull(int column);

public int getType(int column) {
throw new UnsupportedOperationException();
}

// TODO implement getBlob in all cursor types
public byte[] getBlob(int column) {
throw new UnsupportedOperationException("getBlob is not supported");
Expand Down Expand Up @@ -151,6 +155,8 @@ public void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer) {
result.getChars(0, result.length(), data, 0);
}
buffer.sizeCopied = result.length();
} else {
buffer.sizeCopied = 0;
}
}

Expand Down Expand Up @@ -205,7 +211,7 @@ public final boolean moveToPosition(int position) {
* @param window
*/
public void fillWindow(int position, android.database.CursorWindow window) {
if (position < 0 || position > getCount()) {
if (position < 0 || position >= getCount()) {
return;
}
window.acquireReference();
Expand Down Expand Up @@ -523,6 +529,10 @@ public void setNotificationUri(ContentResolver cr, Uri notifyUri) {
}
}

public Uri getNotificationUri() {
return mNotifyUri;
}

public boolean getWantsAllOnMoveCalls() {
return false;
}
Expand Down Expand Up @@ -630,6 +640,12 @@ public void onChange(boolean selfChange) {
protected int mRowIdColumnIndex;

protected int mPos;

/**
* If {@link #mRowIdColumnIndex} is not -1 this contains contains the value of
* the column at {@link #mRowIdColumnIndex} for the current row this cursor is
* pointing at.
*/
protected Long mCurrentRowID;
protected ContentResolver mContentResolver;
protected boolean mClosed = false;
Expand Down
6 changes: 6 additions & 0 deletions src/net/sqlcipher/AbstractWindowedCursor.java
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,12 @@ public boolean isFloat(int columnIndex)
return mWindow.isFloat(mPos, columnIndex);
}

@Override
public int getType(int columnIndex) {
checkPosition();
return mWindow.getType(mPos, columnIndex);
}

@Override
protected void checkPosition()
{
Expand Down
98 changes: 95 additions & 3 deletions src/net/sqlcipher/CursorWindow.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,28 @@
package net.sqlcipher;

import android.database.CharArrayBuffer;
import android.database.Cursor;

import android.content.res.Resources;
import android.database.sqlite.SQLiteClosable;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Process;
import android.util.Log;
import android.util.SparseIntArray;

/**
* A buffer containing multiple cursor rows.
*/
public class CursorWindow extends android.database.CursorWindow implements Parcelable {
/** The pointer to the native window class */
@SuppressWarnings("unused")

/** The pointer to the native window class. set by the native methods in
* android_database_CursorWindow.cpp
*/
private int nWindow;

private int mStartPos;
Expand Down Expand Up @@ -227,9 +239,9 @@ public boolean isNull(int row, int col) {
releaseReference();
}
}

private native boolean isNull_native(int row, int col);

/**
* Returns a byte array for the given field.
*
Expand All @@ -246,14 +258,50 @@ public byte[] getBlob(int row, int col) {
}
}

/**
* Returns the value at (<code>row</code>, <code>col</code>) as a <code>byte</code> array.
*
* <p>If the value is null, then <code>null</code> is returned. If the
* type of column <code>col</code> is a string type, then the result
* is the array of bytes that make up the internal representation of the
* string value. If the type of column <code>col</code> is integral or floating-point,
* then an {@link SQLiteException} is thrown.
*/
private native byte[] getBlob_native(int row, int col);

/**
* Returns data type of the given column's value.
*<p>
* Returned column types are
* <ul>
* <li>{@link Cursor#FIELD_TYPE_NULL}</li>
* <li>{@link Cursor#FIELD_TYPE_INTEGER}</li>
* <li>{@link Cursor#FIELD_TYPE_FLOAT}</li>
* <li>{@link Cursor#FIELD_TYPE_STRING}</li>
* <li>{@link Cursor#FIELD_TYPE_BLOB}</li>
*</ul>
*</p>
*
* @param row the row to read from, row - getStartPosition() being the actual row in the window
* @param col the column to read from
* @return the value type
*/
public int getType(int row, int col) {
acquireReference();
try {
return getType_native(row - mStartPos, col);
} finally {
releaseReference();
}
}

/**
* Checks if a field contains either a blob or is null.
*
* @param row the row to read from, row - getStartPosition() being the actual row in the window
* @param col the column to read from
* @return {@code true} if given field is {@code NULL} or a blob
* @deprecated use {@link #getType(int, int)} instead
*/
public boolean isBlob(int row, int col) {
acquireReference();
Expand All @@ -270,6 +318,7 @@ public boolean isBlob(int row, int col) {
* @param row the row to read from, row - getStartPosition() being the actual row in the window
* @param col the column to read from
* @return {@code true} if given field is a long
* @deprecated use {@link #getType(int, int)} instead
*/
public boolean isLong(int row, int col) {
acquireReference();
Expand All @@ -286,6 +335,7 @@ public boolean isLong(int row, int col) {
* @param row the row to read from, row - getStartPosition() being the actual row in the window
* @param col the column to read from
* @return {@code true} if given field is a float
* @deprecated use {@link #getType(int, int)} instead
*/
public boolean isFloat(int row, int col) {
acquireReference();
Expand All @@ -302,6 +352,7 @@ public boolean isFloat(int row, int col) {
* @param row the row to read from, row - getStartPosition() being the actual row in the window
* @param col the column to read from
* @return {@code true} if given field is {@code NULL} or a String
* @deprecated use {@link #getType(int, int)} instead
*/
public boolean isString(int row, int col) {
acquireReference();
Expand All @@ -317,6 +368,8 @@ public boolean isString(int row, int col) {
private native boolean isInteger_native(int row, int col);
private native boolean isFloat_native(int row, int col);

private native int getType_native(int row, int col);

/**
* Returns a String for the given field.
*
Expand All @@ -333,6 +386,19 @@ public String getString(int row, int col) {
}
}

/**
* Returns the value at (<code>row</code>, <code>col</code>) as a <code>String</code>.
*
* <p>If the value is null, then <code>null</code> is returned. If the
* type of column <code>col</code> is integral, then the result is the string
* that is obtained by formatting the integer value with the <code>printf</code>
* family of functions using format specifier <code>%lld</code>. If the
* type of column <code>col</code> is floating-point, then the result is the string
* that is obtained by formatting the floating-point value with the
* <code>printf</code> family of functions using format specifier <code>%g</code>.
* If the type of column <code>col</code> is a blob type, then an
* {@link SQLiteException} is thrown.
*/
private native String getString_native(int row, int col);

/**
Expand Down Expand Up @@ -384,6 +450,17 @@ public long getLong(int row, int col) {
}
}

/**
* Returns the value at (<code>row</code>, <code>col</code>) as a <code>long</code>.
*
* <p>If the value is null, then <code>0L</code> is returned. If the
* type of column <code>col</code> is a string type, then the result
* is the <code>long</code> that is obtained by parsing the string value with
* <code>strtoll</code>. If the type of column <code>col</code> is
* floating-point, then the result is the floating-point value casted to a <code>long</code>.
* If the type of column <code>col</code> is a blob type, then an
* {@link SQLiteException} is thrown.
*/
private native long getLong_native(int row, int col);

/**
Expand All @@ -403,6 +480,17 @@ public double getDouble(int row, int col) {
}
}

/**
* Returns the value at (<code>row</code>, <code>col</code>) as a <code>double</code>.
*
* <p>If the value is null, then <code>0.0</code> is returned. If the
* type of column <code>col</code> is a string type, then the result
* is the <code>double</code> that is obtained by parsing the string value with
* <code>strtod</code>. If the type of column <code>col</code> is
* integral, then the result is the integer value casted to a <code>double</code>.
* If the type of column <code>col</code> is a blob type, then an
* {@link SQLiteException} is thrown.
*/
private native double getDouble_native(int row, int col);

/**
Expand Down Expand Up @@ -485,6 +573,9 @@ public void close() {
@Override
protected void finalize() {
// Just in case someone forgot to call close...
if (nWindow == 0) {
return;
}
close_native();
}

Expand Down Expand Up @@ -534,6 +625,7 @@ public CursorWindow(Parcel source,int foo) {
@Override
protected void onAllReferencesReleased() {
close_native();
super.onAllReferencesReleased();

super.onAllReferencesReleased();
}
}
31 changes: 31 additions & 0 deletions src/net/sqlcipher/DatabaseUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,37 @@ public static void bindObjectToProgram(SQLiteProgram prog, int index,
}
}

/**
* Returns data type of the given object's value.
*<p>
* Returned values are
* <ul>
* <li>{@link Cursor#FIELD_TYPE_NULL}</li>
* <li>{@link Cursor#FIELD_TYPE_INTEGER}</li>
* <li>{@link Cursor#FIELD_TYPE_FLOAT}</li>
* <li>{@link Cursor#FIELD_TYPE_STRING}</li>
* <li>{@link Cursor#FIELD_TYPE_BLOB}</li>
*</ul>
*</p>
*
* @param obj the object whose value type is to be returned
* @return object value type
* @hide
*/
public static int getTypeOfObject(Object obj) {
if (obj == null) {
return 0; /* Cursor.FIELD_TYPE_NULL */
} else if (obj instanceof byte[]) {
return 4; /* Cursor.FIELD_TYPE_BLOB */
} else if (obj instanceof Float || obj instanceof Double) {
return 2; /* Cursor.FIELD_TYPE_FLOAT */
} else if (obj instanceof Long || obj instanceof Integer) {
return 1; /* Cursor.FIELD_TYPE_INTEGER */
} else {
return 3; /* Cursor.FIELD_TYPE_STRING */
}
}

/**
* Appends an SQL string to the given StringBuilder, including the opening
* and closing single quotes. Any single quotes internal to sqlString will
Expand Down
5 changes: 5 additions & 0 deletions src/net/sqlcipher/MatrixCursor.java
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,11 @@ public double getDouble(int column) {
return Double.parseDouble(value.toString());
}

@Override
public int getType(int column) {
return DatabaseUtils.getTypeOfObject(get(column));
}

@Override
public boolean isNull(int column) {
return get(column) == null;
Expand Down