summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVasu Nori <vnori@google.com>2010-05-18 11:54:31 -0700
committerVasu Nori <vnori@google.com>2010-06-02 17:40:41 -0700
commit8b0dd7da360d70920a37802eb455ba41500d3b45 (patch)
treed31a63e67bbfad53c2dfe4002795b73286b7c361
parent3e7432f823b9f0457e935614787cff4eb71a8f2b (diff)
downloadframeworks_base-8b0dd7da360d70920a37802eb455ba41500d3b45.zip
frameworks_base-8b0dd7da360d70920a37802eb455ba41500d3b45.tar.gz
frameworks_base-8b0dd7da360d70920a37802eb455ba41500d3b45.tar.bz2
add API to Cursor to get column value type
Change-Id: I3ef1bcdb2eb1c45f68e829ccb6e3ecde28076591
-rw-r--r--api/current.xml132
-rw-r--r--core/java/android/database/AbstractCursor.java4
-rw-r--r--core/java/android/database/AbstractWindowedCursor.java55
-rw-r--r--core/java/android/database/Cursor.java40
-rw-r--r--core/java/android/database/CursorWindow.java68
-rw-r--r--core/java/android/database/CursorWrapper.java4
-rw-r--r--core/java/android/database/DatabaseUtils.java31
-rw-r--r--core/java/android/database/MatrixCursor.java5
-rw-r--r--core/java/android/database/MergeCursor.java5
-rw-r--r--core/java/com/android/internal/database/SortCursor.java5
-rw-r--r--core/jni/android_database_CursorWindow.cpp17
-rw-r--r--include/binder/CursorWindow.h20
-rw-r--r--test-runner/src/android/test/mock/MockCursor.java4
13 files changed, 306 insertions, 84 deletions
diff --git a/api/current.xml b/api/current.xml
index 2b31a64..bafbb68 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -55658,6 +55658,19 @@
<parameter name="column" type="int">
</parameter>
</method>
+<method name="getType"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="column" type="int">
+</parameter>
+</method>
<method name="getUpdatedField"
return="java.lang.Object"
abstract="false"
@@ -56681,6 +56694,19 @@
<parameter name="columnIndex" type="int">
</parameter>
</method>
+<method name="getType"
+ return="int"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="columnIndex" type="int">
+</parameter>
+</method>
<method name="getWantsAllOnMoveCalls"
return="boolean"
abstract="true"
@@ -56921,6 +56947,61 @@
<parameter name="observer" type="android.database.DataSetObserver">
</parameter>
</method>
+<field name="FIELD_TYPE_BLOB"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="4"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FIELD_TYPE_FLOAT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FIELD_TYPE_INTEGER"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FIELD_TYPE_NULL"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FIELD_TYPE_STRING"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="3"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
</interface>
<class name="CursorIndexOutOfBoundsException"
extends="java.lang.IndexOutOfBoundsException"
@@ -57278,6 +57359,21 @@
<parameter name="col" type="int">
</parameter>
</method>
+<method name="getType"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="row" type="int">
+</parameter>
+<parameter name="col" type="int">
+</parameter>
+</method>
<method name="isBlob"
return="boolean"
abstract="false"
@@ -57285,7 +57381,7 @@
synchronized="false"
static="false"
final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
<parameter name="row" type="int">
@@ -57300,7 +57396,7 @@
synchronized="false"
static="false"
final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
<parameter name="row" type="int">
@@ -57315,7 +57411,7 @@
synchronized="false"
static="false"
final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
<parameter name="row" type="int">
@@ -57330,7 +57426,7 @@
synchronized="false"
static="false"
final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
<parameter name="row" type="int">
@@ -57345,7 +57441,7 @@
synchronized="false"
static="false"
final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
<parameter name="row" type="int">
@@ -57756,6 +57852,19 @@
<parameter name="columnIndex" type="int">
</parameter>
</method>
+<method name="getType"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="columnIndex" type="int">
+</parameter>
+</method>
<method name="getWantsAllOnMoveCalls"
return="boolean"
abstract="false"
@@ -155557,6 +155666,19 @@
<parameter name="columnIndex" type="int">
</parameter>
</method>
+<method name="getType"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="columnIndex" type="int">
+</parameter>
+</method>
<method name="getWantsAllOnMoveCalls"
return="boolean"
abstract="false"
diff --git a/core/java/android/database/AbstractCursor.java b/core/java/android/database/AbstractCursor.java
index 6170bae..b1f33ec 100644
--- a/core/java/android/database/AbstractCursor.java
+++ b/core/java/android/database/AbstractCursor.java
@@ -51,6 +51,10 @@ public abstract class AbstractCursor implements CrossProcessCursor {
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");
diff --git a/core/java/android/database/AbstractWindowedCursor.java b/core/java/android/database/AbstractWindowedCursor.java
index 27a02e2..e47d9ce 100644
--- a/core/java/android/database/AbstractWindowedCursor.java
+++ b/core/java/android/database/AbstractWindowedCursor.java
@@ -149,63 +149,36 @@ public abstract class AbstractWindowedCursor extends AbstractCursor
}
}
- return mWindow.isNull(mPos, columnIndex);
+ return mWindow.getType(mPos, columnIndex) == Cursor.FIELD_TYPE_NULL;
}
- public boolean isBlob(int columnIndex)
- {
- checkPosition();
-
- synchronized(mUpdatedRows) {
- if (isFieldUpdated(columnIndex)) {
- Object object = getUpdatedField(columnIndex);
- return object == null || object instanceof byte[];
- }
- }
-
- return mWindow.isBlob(mPos, columnIndex);
+ public boolean isBlob(int columnIndex) {
+ return getType(columnIndex) == Cursor.FIELD_TYPE_BLOB;
}
- public boolean isString(int columnIndex)
- {
- checkPosition();
-
- synchronized(mUpdatedRows) {
- if (isFieldUpdated(columnIndex)) {
- Object object = getUpdatedField(columnIndex);
- return object == null || object instanceof String;
- }
- }
-
- return mWindow.isString(mPos, columnIndex);
+ public boolean isString(int columnIndex) {
+ return getType(columnIndex) == Cursor.FIELD_TYPE_STRING;
}
- public boolean isLong(int columnIndex)
- {
- checkPosition();
-
- synchronized(mUpdatedRows) {
- if (isFieldUpdated(columnIndex)) {
- Object object = getUpdatedField(columnIndex);
- return object != null && (object instanceof Integer || object instanceof Long);
- }
- }
+ public boolean isLong(int columnIndex) {
+ return getType(columnIndex) == Cursor.FIELD_TYPE_INTEGER;
+ }
- return mWindow.isLong(mPos, columnIndex);
+ public boolean isFloat(int columnIndex) {
+ return getType(columnIndex) == Cursor.FIELD_TYPE_FLOAT;
}
- public boolean isFloat(int columnIndex)
+ @Override
+ public int getType(int columnIndex)
{
checkPosition();
-
synchronized(mUpdatedRows) {
if (isFieldUpdated(columnIndex)) {
- Object object = getUpdatedField(columnIndex);
- return object != null && (object instanceof Float || object instanceof Double);
+ return DatabaseUtils.getTypeOfObject(getUpdatedField(columnIndex));
}
}
- return mWindow.isFloat(mPos, columnIndex);
+ return mWindow.getType(mPos, columnIndex);
}
@Override
diff --git a/core/java/android/database/Cursor.java b/core/java/android/database/Cursor.java
index fee658a..c03c586 100644
--- a/core/java/android/database/Cursor.java
+++ b/core/java/android/database/Cursor.java
@@ -30,6 +30,25 @@ import java.util.Map;
* threads should perform its own synchronization when using the Cursor.
*/
public interface Cursor {
+ /*
+ * Values returned by {@link #getType(int)}.
+ * These should be consistent with the corresponding types defined in CursorWindow.h
+ */
+ /** Value returned by {@link #getType(int)} if the specified column is null */
+ static final int FIELD_TYPE_NULL = 0;
+
+ /** Value returned by {@link #getType(int)} if the specified column type is integer */
+ static final int FIELD_TYPE_INTEGER = 1;
+
+ /** Value returned by {@link #getType(int)} if the specified column type is float */
+ static final int FIELD_TYPE_FLOAT = 2;
+
+ /** Value returned by {@link #getType(int)} if the specified column type is string */
+ static final int FIELD_TYPE_STRING = 3;
+
+ /** Value returned by {@link #getType(int)} if the specified column type is blob */
+ static final int FIELD_TYPE_BLOB = 4;
+
/**
* Returns the numbers of rows in the cursor.
*
@@ -279,6 +298,27 @@ public interface Cursor {
double getDouble(int columnIndex);
/**
+ * Returns data type of the given column's value.
+ * The preferred type of the column is returned but the data may be converted to other types
+ * as documented in the get-type methods such as {@link #getInt(int)}, {@link #getFloat(int)}
+ * etc.
+ *<p>
+ * Returned column types are
+ * <ul>
+ * <li>{@link #FIELD_TYPE_NULL}</li>
+ * <li>{@link #FIELD_TYPE_INTEGER}</li>
+ * <li>{@link #FIELD_TYPE_FLOAT}</li>
+ * <li>{@link #FIELD_TYPE_STRING}</li>
+ * <li>{@link #FIELD_TYPE_BLOB}</li>
+ *</ul>
+ *</p>
+ *
+ * @param columnIndex the zero-based index of the target column.
+ * @return column value type
+ */
+ int getType(int columnIndex);
+
+ /**
* Returns <code>true</code> if the value in the indicated column is null.
*
* @param columnIndex the zero-based index of the target column.
diff --git a/core/java/android/database/CursorWindow.java b/core/java/android/database/CursorWindow.java
index c756825..39889b9 100644
--- a/core/java/android/database/CursorWindow.java
+++ b/core/java/android/database/CursorWindow.java
@@ -217,14 +217,11 @@ public class CursorWindow extends SQLiteClosable implements Parcelable {
* @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}
+ * @deprecated use {@link #getType(int, int)} instead
*/
+ @Deprecated
public boolean isNull(int row, int col) {
- acquireReference();
- try {
- return isNull_native(row - mStartPos, col);
- } finally {
- releaseReference();
- }
+ return getType(row, col) == Cursor.FIELD_TYPE_NULL;
}
private native boolean isNull_native(int row, int col);
@@ -248,35 +245,55 @@ public class CursorWindow extends SQLiteClosable implements Parcelable {
private native byte[] getBlob_native(int row, int col);
/**
- * Checks if a field contains either a blob or is null.
+ * 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 {@code true} if given field is {@code NULL} or a blob
+ * @return the value type
*/
- public boolean isBlob(int row, int col) {
+ public int getType(int row, int col) {
acquireReference();
try {
- return isBlob_native(row - mStartPos, col);
+ 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
+ */
+ @Deprecated
+ public boolean isBlob(int row, int col) {
+ return getType(row, col) == Cursor.FIELD_TYPE_BLOB;
+ }
+
+ /**
* Checks if a field contains a long
*
* @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
*/
+ @Deprecated
public boolean isLong(int row, int col) {
- acquireReference();
- try {
- return isInteger_native(row - mStartPos, col);
- } finally {
- releaseReference();
- }
+ return getType(row, col) == Cursor.FIELD_TYPE_INTEGER;
}
/**
@@ -285,14 +302,11 @@ public class CursorWindow extends SQLiteClosable implements Parcelable {
* @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
*/
+ @Deprecated
public boolean isFloat(int row, int col) {
- acquireReference();
- try {
- return isFloat_native(row - mStartPos, col);
- } finally {
- releaseReference();
- }
+ return getType(row, col) == Cursor.FIELD_TYPE_FLOAT;
}
/**
@@ -301,20 +315,18 @@ public class CursorWindow extends SQLiteClosable implements Parcelable {
* @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
*/
+ @Deprecated
public boolean isString(int row, int col) {
- acquireReference();
- try {
- return isString_native(row - mStartPos, col);
- } finally {
- releaseReference();
- }
+ return getType(row, col) == Cursor.FIELD_TYPE_STRING;
}
private native boolean isBlob_native(int row, int col);
private native boolean isString_native(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.
diff --git a/core/java/android/database/CursorWrapper.java b/core/java/android/database/CursorWrapper.java
index 633b2b3..2ac9470 100644
--- a/core/java/android/database/CursorWrapper.java
+++ b/core/java/android/database/CursorWrapper.java
@@ -130,6 +130,10 @@ public class CursorWrapper implements Cursor {
return mCursor.isLast();
}
+ public int getType(int columnIndex) {
+ return mCursor.getType(columnIndex);
+ }
+
public boolean isNull(int columnIndex) {
return mCursor.isNull(columnIndex);
}
diff --git a/core/java/android/database/DatabaseUtils.java b/core/java/android/database/DatabaseUtils.java
index 9bfbb74..af93eee 100644
--- a/core/java/android/database/DatabaseUtils.java
+++ b/core/java/android/database/DatabaseUtils.java
@@ -193,6 +193,37 @@ public class DatabaseUtils {
}
/**
+ * 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 Cursor.FIELD_TYPE_NULL;
+ } else if (obj instanceof byte[]) {
+ return Cursor.FIELD_TYPE_BLOB;
+ } else if (obj instanceof Float || obj instanceof Double) {
+ return Cursor.FIELD_TYPE_FLOAT;
+ } else if (obj instanceof Long || obj instanceof Integer) {
+ return Cursor.FIELD_TYPE_INTEGER;
+ } else {
+ return 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
* be escaped.
diff --git a/core/java/android/database/MatrixCursor.java b/core/java/android/database/MatrixCursor.java
index d5c3a32..5c1b968 100644
--- a/core/java/android/database/MatrixCursor.java
+++ b/core/java/android/database/MatrixCursor.java
@@ -272,6 +272,11 @@ public class MatrixCursor extends AbstractCursor {
}
@Override
+ public int getType(int column) {
+ return DatabaseUtils.getTypeOfObject(get(column));
+ }
+
+ @Override
public boolean isNull(int column) {
return get(column) == null;
}
diff --git a/core/java/android/database/MergeCursor.java b/core/java/android/database/MergeCursor.java
index cb6d7ac..2c25db7 100644
--- a/core/java/android/database/MergeCursor.java
+++ b/core/java/android/database/MergeCursor.java
@@ -129,6 +129,11 @@ public class MergeCursor extends AbstractCursor
}
@Override
+ public int getType(int column) {
+ return mCursor.getType(column);
+ }
+
+ @Override
public boolean isNull(int column)
{
return mCursor.isNull(column);
diff --git a/core/java/com/android/internal/database/SortCursor.java b/core/java/com/android/internal/database/SortCursor.java
index 12248a2..0025512 100644
--- a/core/java/com/android/internal/database/SortCursor.java
+++ b/core/java/com/android/internal/database/SortCursor.java
@@ -218,6 +218,11 @@ public class SortCursor extends AbstractCursor
}
@Override
+ public int getType(int column) {
+ return mCursor.getType(column);
+ }
+
+ @Override
public boolean isNull(int column)
{
return mCursor.isNull(column);
diff --git a/core/jni/android_database_CursorWindow.cpp b/core/jni/android_database_CursorWindow.cpp
index fba6f0f..55f5252 100644
--- a/core/jni/android_database_CursorWindow.cpp
+++ b/core/jni/android_database_CursorWindow.cpp
@@ -652,6 +652,22 @@ static void freeLastRow(JNIEnv * env, jobject object) {
window->freeLastRow();
}
+static jint getType_native(JNIEnv* env, jobject object, jint row, jint column)
+{
+ int32_t err;
+ CursorWindow * window = GET_WINDOW(env, object);
+ LOG_WINDOW("returning column type affinity 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 JNINativeMethod sMethods[] =
{
/* name, signature, funcPtr */
@@ -679,6 +695,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)
diff --git a/include/binder/CursorWindow.h b/include/binder/CursorWindow.h
index bda0d31..4fbff2a 100644
--- a/include/binder/CursorWindow.h
+++ b/include/binder/CursorWindow.h
@@ -1,16 +1,16 @@
/*
* Copyright (C) 2006 The Android Open Source Project
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
* limitations under the License.
*/
@@ -80,11 +80,11 @@ typedef struct
} data;
} __attribute__((packed)) field_slot_t;
+#define FIELD_TYPE_NULL 0
#define FIELD_TYPE_INTEGER 1
#define FIELD_TYPE_FLOAT 2
#define FIELD_TYPE_STRING 3
#define FIELD_TYPE_BLOB 4
-#define FIELD_TYPE_NULL 5
/**
* This class stores a set of rows from a database in a buffer. The begining of the
@@ -170,7 +170,7 @@ public:
row_slot_t * allocRowSlot();
row_slot_t * getRowSlot(int row);
-
+
/**
* return NULL if Failed to find rowSlot or
* Invalid rowSlot
diff --git a/test-runner/src/android/test/mock/MockCursor.java b/test-runner/src/android/test/mock/MockCursor.java
index c817532..baa150a 100644
--- a/test-runner/src/android/test/mock/MockCursor.java
+++ b/test-runner/src/android/test/mock/MockCursor.java
@@ -191,4 +191,8 @@ public class MockCursor implements Cursor {
public void unregisterDataSetObserver(DataSetObserver observer) {
throw new UnsupportedOperationException("unimplemented mock method");
}
+
+ public int getType(int columnIndex) {
+ throw new UnsupportedOperationException("unimplemented mock method");
+ }
} \ No newline at end of file