diff --git a/api/current.xml b/api/current.xml index 2b31a64541228..bafbb6894a6cc 100644 --- a/api/current.xml +++ b/api/current.xml @@ -55658,6 +55658,19 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -57300,7 +57396,7 @@ synchronized="false" static="false" final="false" - deprecated="not deprecated" + deprecated="deprecated" visibility="public" > @@ -57315,7 +57411,7 @@ synchronized="false" static="false" final="false" - deprecated="not deprecated" + deprecated="deprecated" visibility="public" > @@ -57330,7 +57426,7 @@ synchronized="false" static="false" final="false" - deprecated="not deprecated" + deprecated="deprecated" visibility="public" > @@ -57345,7 +57441,7 @@ synchronized="false" static="false" final="false" - deprecated="not deprecated" + deprecated="deprecated" visibility="public" > @@ -57756,6 +57852,19 @@ + + + + + + + + + * Returned column types are + * + *

+ * + * @param columnIndex the zero-based index of the target column. + * @return column value type + */ + int getType(int columnIndex); + /** * Returns true if the value in the indicated column is null. * diff --git a/core/java/android/database/CursorWindow.java b/core/java/android/database/CursorWindow.java index c756825a79855..39889b983e6cd 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); @@ -247,20 +244,43 @@ public class CursorWindow extends SQLiteClosable implements Parcelable { private native byte[] getBlob_native(int row, int col); + /** + * Returns data type of the given column's value. + *

+ * Returned column types are + *

+ *

+ * + * @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 */ + @Deprecated public boolean isBlob(int row, int col) { - acquireReference(); - try { - return isBlob_native(row - mStartPos, col); - } finally { - releaseReference(); - } + return getType(row, col) == Cursor.FIELD_TYPE_BLOB; } /** @@ -269,14 +289,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 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 633b2b3015772..2ac94707b607f 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 9bfbb74eeb274..af93eee4c7715 100644 --- a/core/java/android/database/DatabaseUtils.java +++ b/core/java/android/database/DatabaseUtils.java @@ -192,6 +192,37 @@ public class DatabaseUtils { } } + /** + * Returns data type of the given object's value. + *

+ * Returned values are + *

+ *

+ * + * @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 diff --git a/core/java/android/database/MatrixCursor.java b/core/java/android/database/MatrixCursor.java index d5c3a32d884d2..5c1b9689370ad 100644 --- a/core/java/android/database/MatrixCursor.java +++ b/core/java/android/database/MatrixCursor.java @@ -271,6 +271,11 @@ public class MatrixCursor extends AbstractCursor { 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; diff --git a/core/java/android/database/MergeCursor.java b/core/java/android/database/MergeCursor.java index cb6d7ac2ee200..2c25db765a2ba 100644 --- a/core/java/android/database/MergeCursor.java +++ b/core/java/android/database/MergeCursor.java @@ -128,6 +128,11 @@ public class MergeCursor extends AbstractCursor return mCursor.getDouble(column); } + @Override + public int getType(int column) { + return mCursor.getType(column); + } + @Override public boolean isNull(int column) { diff --git a/core/java/com/android/internal/database/SortCursor.java b/core/java/com/android/internal/database/SortCursor.java index 12248a227abff..00255128972c1 100644 --- a/core/java/com/android/internal/database/SortCursor.java +++ b/core/java/com/android/internal/database/SortCursor.java @@ -217,6 +217,11 @@ public class SortCursor extends AbstractCursor return mCursor.getDouble(column); } + @Override + public int getType(int column) { + return mCursor.getType(column); + } + @Override public boolean isNull(int column) { diff --git a/core/jni/android_database_CursorWindow.cpp b/core/jni/android_database_CursorWindow.cpp index fba6f0f668fae..55f5252761964 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 bda0d31fb9c79..4fbff2ac9476e 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 c817532d2f180..baa150a0e0e6b 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