summaryrefslogtreecommitdiffstats
path: root/core/java/android/database
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:45 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:45 -0800
commitd83a98f4ce9cfa908f5c54bbd70f03eec07e7553 (patch)
tree4b825dc642cb6eb9a060e54bf8d69288fbee4904 /core/java/android/database
parent076357b8567458d4b6dfdcf839ef751634cd2bfb (diff)
downloadframeworks_base-d83a98f4ce9cfa908f5c54bbd70f03eec07e7553.zip
frameworks_base-d83a98f4ce9cfa908f5c54bbd70f03eec07e7553.tar.gz
frameworks_base-d83a98f4ce9cfa908f5c54bbd70f03eec07e7553.tar.bz2
auto import from //depot/cupcake/@135843
Diffstat (limited to 'core/java/android/database')
-rw-r--r--core/java/android/database/AbstractCursor.java636
-rw-r--r--core/java/android/database/AbstractWindowedCursor.java204
-rw-r--r--core/java/android/database/BulkCursorNative.java440
-rw-r--r--core/java/android/database/BulkCursorToCursorAdaptor.java256
-rw-r--r--core/java/android/database/CharArrayBuffer.java33
-rw-r--r--core/java/android/database/ContentObservable.java56
-rw-r--r--core/java/android/database/ContentObserver.java138
-rw-r--r--core/java/android/database/CrossProcessCursor.java42
-rw-r--r--core/java/android/database/Cursor.java587
-rw-r--r--core/java/android/database/CursorIndexOutOfBoundsException.java31
-rw-r--r--core/java/android/database/CursorJoiner.java265
-rw-r--r--core/java/android/database/CursorToBulkCursorAdaptor.java233
-rw-r--r--core/java/android/database/CursorWindow.java483
-rw-r--r--core/java/android/database/CursorWrapper.java305
-rw-r--r--core/java/android/database/DataSetObservable.java47
-rw-r--r--core/java/android/database/DataSetObserver.java41
-rw-r--r--core/java/android/database/DatabaseUtils.java1018
-rw-r--r--core/java/android/database/IBulkCursor.java90
-rwxr-xr-xcore/java/android/database/IContentObserver.aidl31
-rw-r--r--core/java/android/database/MatrixCursor.java267
-rw-r--r--core/java/android/database/MergeCursor.java257
-rw-r--r--core/java/android/database/Observable.java78
-rw-r--r--core/java/android/database/SQLException.java30
-rw-r--r--core/java/android/database/StaleDataException.java34
-rw-r--r--core/java/android/database/package.html14
-rw-r--r--core/java/android/database/sqlite/SQLiteAbortException.java30
-rw-r--r--core/java/android/database/sqlite/SQLiteClosable.java55
-rw-r--r--core/java/android/database/sqlite/SQLiteConstraintException.java28
-rw-r--r--core/java/android/database/sqlite/SQLiteCursor.java606
-rw-r--r--core/java/android/database/sqlite/SQLiteCursorDriver.java58
-rw-r--r--core/java/android/database/sqlite/SQLiteDatabase.java1675
-rw-r--r--core/java/android/database/sqlite/SQLiteDatabaseCorruptException.java28
-rw-r--r--core/java/android/database/sqlite/SQLiteDebug.java107
-rw-r--r--core/java/android/database/sqlite/SQLiteDirectCursorDriver.java97
-rw-r--r--core/java/android/database/sqlite/SQLiteDiskIOException.java29
-rw-r--r--core/java/android/database/sqlite/SQLiteDoneException.java31
-rw-r--r--core/java/android/database/sqlite/SQLiteException.java30
-rw-r--r--core/java/android/database/sqlite/SQLiteFullException.java28
-rw-r--r--core/java/android/database/sqlite/SQLiteMisuseException.java25
-rw-r--r--core/java/android/database/sqlite/SQLiteOpenHelper.java229
-rw-r--r--core/java/android/database/sqlite/SQLiteProgram.java264
-rw-r--r--core/java/android/database/sqlite/SQLiteQuery.java194
-rw-r--r--core/java/android/database/sqlite/SQLiteQueryBuilder.java520
-rw-r--r--core/java/android/database/sqlite/SQLiteStatement.java146
-rw-r--r--core/java/android/database/sqlite/package.html20
45 files changed, 0 insertions, 9816 deletions
diff --git a/core/java/android/database/AbstractCursor.java b/core/java/android/database/AbstractCursor.java
deleted file mode 100644
index 76f0860..0000000
--- a/core/java/android/database/AbstractCursor.java
+++ /dev/null
@@ -1,636 +0,0 @@
-/*
- * 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database;
-
-import android.content.ContentResolver;
-import android.net.Uri;
-import android.util.Config;
-import android.util.Log;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-
-import java.lang.ref.WeakReference;
-import java.lang.UnsupportedOperationException;
-import java.util.HashMap;
-import java.util.Map;
-
-
-/**
- * This is an abstract cursor class that handles a lot of the common code
- * that all cursors need to deal with and is provided for convenience reasons.
- */
-public abstract class AbstractCursor implements CrossProcessCursor {
- private static final String TAG = "Cursor";
-
- DataSetObservable mDataSetObservable = new DataSetObservable();
- ContentObservable mContentObservable = new ContentObservable();
-
- /* -------------------------------------------------------- */
- /* These need to be implemented by subclasses */
- abstract public int getCount();
-
- abstract public String[] getColumnNames();
-
- abstract public String getString(int column);
- abstract public short getShort(int column);
- abstract public int getInt(int column);
- abstract public long getLong(int column);
- abstract public float getFloat(int column);
- abstract public double getDouble(int column);
- abstract public boolean isNull(int column);
-
- // TODO implement getBlob in all cursor types
- public byte[] getBlob(int column) {
- throw new UnsupportedOperationException("getBlob is not supported");
- }
- /* -------------------------------------------------------- */
- /* Methods that may optionally be implemented by subclasses */
-
- /**
- * returns a pre-filled window, return NULL if no such window
- */
- public CursorWindow getWindow() {
- return null;
- }
-
- public int getColumnCount() {
- return getColumnNames().length;
- }
-
- public void deactivate() {
- deactivateInternal();
- }
-
- /**
- * @hide
- */
- public void deactivateInternal() {
- if (mSelfObserver != null) {
- mContentResolver.unregisterContentObserver(mSelfObserver);
- mSelfObserverRegistered = false;
- }
- mDataSetObservable.notifyInvalidated();
- }
-
- public boolean requery() {
- if (mSelfObserver != null && mSelfObserverRegistered == false) {
- mContentResolver.registerContentObserver(mNotifyUri, true, mSelfObserver);
- mSelfObserverRegistered = true;
- }
- mDataSetObservable.notifyChanged();
- return true;
- }
-
- public boolean isClosed() {
- return mClosed;
- }
-
- public void close() {
- mClosed = true;
- mContentObservable.unregisterAll();
- deactivateInternal();
- }
-
- /**
- * @hide
- * @deprecated
- */
- public boolean commitUpdates(Map<? extends Long,? extends Map<String,Object>> values) {
- return false;
- }
-
- /**
- * @hide
- * @deprecated
- */
- public boolean deleteRow() {
- return false;
- }
-
- /**
- * This function is called every time the cursor is successfully scrolled
- * to a new position, giving the subclass a chance to update any state it
- * may have. If it returns false the move function will also do so and the
- * cursor will scroll to the beforeFirst position.
- *
- * @param oldPosition the position that we're moving from
- * @param newPosition the position that we're moving to
- * @return true if the move is successful, false otherwise
- */
- public boolean onMove(int oldPosition, int newPosition) {
- return true;
- }
-
-
- public void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer) {
- // Default implementation, uses getString
- String result = getString(columnIndex);
- if (result != null) {
- char[] data = buffer.data;
- if (data == null || data.length < result.length()) {
- buffer.data = result.toCharArray();
- } else {
- result.getChars(0, result.length(), data, 0);
- }
- buffer.sizeCopied = result.length();
- }
- }
-
- /* -------------------------------------------------------- */
- /* Implementation */
- public AbstractCursor() {
- mPos = -1;
- mRowIdColumnIndex = -1;
- mCurrentRowID = null;
- mUpdatedRows = new HashMap<Long, Map<String, Object>>();
- }
-
- public final int getPosition() {
- return mPos;
- }
-
- public final boolean moveToPosition(int position) {
- // Make sure position isn't past the end of the cursor
- final int count = getCount();
- if (position >= count) {
- mPos = count;
- return false;
- }
-
- // Make sure position isn't before the beginning of the cursor
- if (position < 0) {
- mPos = -1;
- return false;
- }
-
- // Check for no-op moves, and skip the rest of the work for them
- if (position == mPos) {
- return true;
- }
-
- boolean result = onMove(mPos, position);
- if (result == false) {
- mPos = -1;
- } else {
- mPos = position;
- if (mRowIdColumnIndex != -1) {
- mCurrentRowID = Long.valueOf(getLong(mRowIdColumnIndex));
- }
- }
-
- return result;
- }
-
- /**
- * Copy data from cursor to CursorWindow
- * @param position start position of data
- * @param window
- */
- public void fillWindow(int position, CursorWindow window) {
- if (position < 0 || position > getCount()) {
- return;
- }
- window.acquireReference();
- try {
- int oldpos = mPos;
- mPos = position - 1;
- window.clear();
- window.setStartPosition(position);
- int columnNum = getColumnCount();
- window.setNumColumns(columnNum);
- while (moveToNext() && window.allocRow()) {
- for (int i = 0; i < columnNum; i++) {
- String field = getString(i);
- if (field != null) {
- if (!window.putString(field, mPos, i)) {
- window.freeLastRow();
- break;
- }
- } else {
- if (!window.putNull(mPos, i)) {
- window.freeLastRow();
- break;
- }
- }
- }
- }
-
- mPos = oldpos;
- } catch (IllegalStateException e){
- // simply ignore it
- } finally {
- window.releaseReference();
- }
- }
-
- public final boolean move(int offset) {
- return moveToPosition(mPos + offset);
- }
-
- public final boolean moveToFirst() {
- return moveToPosition(0);
- }
-
- public final boolean moveToLast() {
- return moveToPosition(getCount() - 1);
- }
-
- public final boolean moveToNext() {
- return moveToPosition(mPos + 1);
- }
-
- public final boolean moveToPrevious() {
- return moveToPosition(mPos - 1);
- }
-
- public final boolean isFirst() {
- return mPos == 0 && getCount() != 0;
- }
-
- public final boolean isLast() {
- int cnt = getCount();
- return mPos == (cnt - 1) && cnt != 0;
- }
-
- public final boolean isBeforeFirst() {
- if (getCount() == 0) {
- return true;
- }
- return mPos == -1;
- }
-
- public final boolean isAfterLast() {
- if (getCount() == 0) {
- return true;
- }
- return mPos == getCount();
- }
-
- public int getColumnIndex(String columnName) {
- // Hack according to bug 903852
- final int periodIndex = columnName.lastIndexOf('.');
- if (periodIndex != -1) {
- Exception e = new Exception();
- Log.e(TAG, "requesting column name with table name -- " + columnName, e);
- columnName = columnName.substring(periodIndex + 1);
- }
-
- String columnNames[] = getColumnNames();
- int length = columnNames.length;
- for (int i = 0; i < length; i++) {
- if (columnNames[i].equalsIgnoreCase(columnName)) {
- return i;
- }
- }
-
- if (Config.LOGV) {
- if (getCount() > 0) {
- Log.w("AbstractCursor", "Unknown column " + columnName);
- }
- }
- return -1;
- }
-
- public int getColumnIndexOrThrow(String columnName) {
- final int index = getColumnIndex(columnName);
- if (index < 0) {
- throw new IllegalArgumentException("column '" + columnName + "' does not exist");
- }
- return index;
- }
-
- public String getColumnName(int columnIndex) {
- return getColumnNames()[columnIndex];
- }
-
- /**
- * @hide
- * @deprecated
- */
- public boolean updateBlob(int columnIndex, byte[] value) {
- return update(columnIndex, value);
- }
-
- /**
- * @hide
- * @deprecated
- */
- public boolean updateString(int columnIndex, String value) {
- return update(columnIndex, value);
- }
-
- /**
- * @hide
- * @deprecated
- */
- public boolean updateShort(int columnIndex, short value) {
- return update(columnIndex, Short.valueOf(value));
- }
-
- /**
- * @hide
- * @deprecated
- */
- public boolean updateInt(int columnIndex, int value) {
- return update(columnIndex, Integer.valueOf(value));
- }
-
- /**
- * @hide
- * @deprecated
- */
- public boolean updateLong(int columnIndex, long value) {
- return update(columnIndex, Long.valueOf(value));
- }
-
- /**
- * @hide
- * @deprecated
- */
- public boolean updateFloat(int columnIndex, float value) {
- return update(columnIndex, Float.valueOf(value));
- }
-
- /**
- * @hide
- * @deprecated
- */
- public boolean updateDouble(int columnIndex, double value) {
- return update(columnIndex, Double.valueOf(value));
- }
-
- /**
- * @hide
- * @deprecated
- */
- public boolean updateToNull(int columnIndex) {
- return update(columnIndex, null);
- }
-
- /**
- * @hide
- * @deprecated
- */
- public boolean update(int columnIndex, Object obj) {
- if (!supportsUpdates()) {
- return false;
- }
-
- // Long.valueOf() returns null sometimes!
-// Long rowid = Long.valueOf(getLong(mRowIdColumnIndex));
- Long rowid = new Long(getLong(mRowIdColumnIndex));
- if (rowid == null) {
- throw new IllegalStateException("null rowid. mRowIdColumnIndex = " + mRowIdColumnIndex);
- }
-
- synchronized(mUpdatedRows) {
- Map<String, Object> row = mUpdatedRows.get(rowid);
- if (row == null) {
- row = new HashMap<String, Object>();
- mUpdatedRows.put(rowid, row);
- }
- row.put(getColumnNames()[columnIndex], obj);
- }
-
- return true;
- }
-
- /**
- * Returns <code>true</code> if there are pending updates that have not yet been committed.
- *
- * @return <code>true</code> if there are pending updates that have not yet been committed.
- * @hide
- * @deprecated
- */
- public boolean hasUpdates() {
- synchronized(mUpdatedRows) {
- return mUpdatedRows.size() > 0;
- }
- }
-
- /**
- * @hide
- * @deprecated
- */
- public void abortUpdates() {
- synchronized(mUpdatedRows) {
- mUpdatedRows.clear();
- }
- }
-
- /**
- * @hide
- * @deprecated
- */
- public boolean commitUpdates() {
- return commitUpdates(null);
- }
-
- /**
- * @hide
- * @deprecated
- */
- public boolean supportsUpdates() {
- return mRowIdColumnIndex != -1;
- }
-
- public void registerContentObserver(ContentObserver observer) {
- mContentObservable.registerObserver(observer);
- }
-
- public void unregisterContentObserver(ContentObserver observer) {
- // cursor will unregister all observers when it close
- if (!mClosed) {
- mContentObservable.unregisterObserver(observer);
- }
- }
-
- /**
- * @hide pending API council approval
- */
- protected void notifyDataSetChange() {
- mDataSetObservable.notifyChanged();
- }
-
- /**
- * @hide pending API council approval
- */
- protected DataSetObservable getDataSetObservable() {
- return mDataSetObservable;
-
- }
- public void registerDataSetObserver(DataSetObserver observer) {
- mDataSetObservable.registerObserver(observer);
-
- }
-
- public void unregisterDataSetObserver(DataSetObserver observer) {
- mDataSetObservable.unregisterObserver(observer);
- }
-
- /**
- * Subclasses must call this method when they finish committing updates to notify all
- * observers.
- *
- * @param selfChange
- */
- protected void onChange(boolean selfChange) {
- synchronized (mSelfObserverLock) {
- mContentObservable.dispatchChange(selfChange);
- if (mNotifyUri != null && selfChange) {
- mContentResolver.notifyChange(mNotifyUri, mSelfObserver);
- }
- }
- }
-
- /**
- * Specifies a content URI to watch for changes.
- *
- * @param cr The content resolver from the caller's context.
- * @param notifyUri The URI to watch for changes. This can be a
- * specific row URI, or a base URI for a whole class of content.
- */
- public void setNotificationUri(ContentResolver cr, Uri notifyUri) {
- synchronized (mSelfObserverLock) {
- mNotifyUri = notifyUri;
- mContentResolver = cr;
- if (mSelfObserver != null) {
- mContentResolver.unregisterContentObserver(mSelfObserver);
- }
- mSelfObserver = new SelfContentObserver(this);
- mContentResolver.registerContentObserver(mNotifyUri, true, mSelfObserver);
- mSelfObserverRegistered = true;
- }
- }
-
- public boolean getWantsAllOnMoveCalls() {
- return false;
- }
-
- public Bundle getExtras() {
- return Bundle.EMPTY;
- }
-
- public Bundle respond(Bundle extras) {
- return Bundle.EMPTY;
- }
-
- /**
- * This function returns true if the field has been updated and is
- * used in conjunction with {@link #getUpdatedField} to allow subclasses to
- * support reading uncommitted updates. NOTE: This function and
- * {@link #getUpdatedField} should be called together inside of a
- * block synchronized on mUpdatedRows.
- *
- * @param columnIndex the column index of the field to check
- * @return true if the field has been updated, false otherwise
- */
- protected boolean isFieldUpdated(int columnIndex) {
- if (mRowIdColumnIndex != -1 && mUpdatedRows.size() > 0) {
- Map<String, Object> updates = mUpdatedRows.get(mCurrentRowID);
- if (updates != null && updates.containsKey(getColumnNames()[columnIndex])) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * This function returns the uncommitted updated value for the field
- * at columnIndex. NOTE: This function and {@link #isFieldUpdated} should
- * be called together inside of a block synchronized on mUpdatedRows.
- *
- * @param columnIndex the column index of the field to retrieve
- * @return the updated value
- */
- protected Object getUpdatedField(int columnIndex) {
- Map<String, Object> updates = mUpdatedRows.get(mCurrentRowID);
- return updates.get(getColumnNames()[columnIndex]);
- }
-
- /**
- * This function throws CursorIndexOutOfBoundsException if
- * the cursor position is out of bounds. Subclass implementations of
- * the get functions should call this before attempting
- * to retrieve data.
- *
- * @throws CursorIndexOutOfBoundsException
- */
- protected void checkPosition() {
- if (-1 == mPos || getCount() == mPos) {
- throw new CursorIndexOutOfBoundsException(mPos, getCount());
- }
- }
-
- @Override
- protected void finalize() {
- if (mSelfObserver != null && mSelfObserverRegistered == true) {
- mContentResolver.unregisterContentObserver(mSelfObserver);
- }
- }
-
- /**
- * Cursors use this class to track changes others make to their URI.
- */
- protected static class SelfContentObserver extends ContentObserver {
- WeakReference<AbstractCursor> mCursor;
-
- public SelfContentObserver(AbstractCursor cursor) {
- super(null);
- mCursor = new WeakReference<AbstractCursor>(cursor);
- }
-
- @Override
- public boolean deliverSelfNotifications() {
- return false;
- }
-
- @Override
- public void onChange(boolean selfChange) {
- AbstractCursor cursor = mCursor.get();
- if (cursor != null) {
- cursor.onChange(false);
- }
- }
- }
-
- /**
- * This HashMap contains a mapping from Long rowIDs to another Map
- * that maps from String column names to new values. A NULL value means to
- * remove an existing value, and all numeric values are in their class
- * forms, i.e. Integer, Long, Float, etc.
- */
- protected HashMap<Long, Map<String, Object>> mUpdatedRows;
-
- /**
- * This must be set to the index of the row ID column by any
- * subclass that wishes to support updates.
- */
- protected int mRowIdColumnIndex;
-
- protected int mPos;
- protected Long mCurrentRowID;
- protected ContentResolver mContentResolver;
- protected boolean mClosed = false;
- private Uri mNotifyUri;
- private ContentObserver mSelfObserver;
- final private Object mSelfObserverLock = new Object();
- private boolean mSelfObserverRegistered;
-}
diff --git a/core/java/android/database/AbstractWindowedCursor.java b/core/java/android/database/AbstractWindowedCursor.java
deleted file mode 100644
index 4ac0aef..0000000
--- a/core/java/android/database/AbstractWindowedCursor.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database;
-
-/**
- * A base class for Cursors that store their data in {@link CursorWindow}s.
- */
-public abstract class AbstractWindowedCursor extends AbstractCursor
-{
- @Override
- public byte[] getBlob(int columnIndex)
- {
- checkPosition();
-
- synchronized(mUpdatedRows) {
- if (isFieldUpdated(columnIndex)) {
- return (byte[])getUpdatedField(columnIndex);
- }
- }
-
- return mWindow.getBlob(mPos, columnIndex);
- }
-
- @Override
- public String getString(int columnIndex)
- {
- checkPosition();
-
- synchronized(mUpdatedRows) {
- if (isFieldUpdated(columnIndex)) {
- return (String)getUpdatedField(columnIndex);
- }
- }
-
- return mWindow.getString(mPos, columnIndex);
- }
-
- @Override
- public void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer)
- {
- checkPosition();
-
- synchronized(mUpdatedRows) {
- if (isFieldUpdated(columnIndex)) {
- super.copyStringToBuffer(columnIndex, buffer);
- }
- }
-
- mWindow.copyStringToBuffer(mPos, columnIndex, buffer);
- }
-
- @Override
- public short getShort(int columnIndex)
- {
- checkPosition();
-
- synchronized(mUpdatedRows) {
- if (isFieldUpdated(columnIndex)) {
- Number value = (Number)getUpdatedField(columnIndex);
- return value.shortValue();
- }
- }
-
- return mWindow.getShort(mPos, columnIndex);
- }
-
- @Override
- public int getInt(int columnIndex)
- {
- checkPosition();
-
- synchronized(mUpdatedRows) {
- if (isFieldUpdated(columnIndex)) {
- Number value = (Number)getUpdatedField(columnIndex);
- return value.intValue();
- }
- }
-
- return mWindow.getInt(mPos, columnIndex);
- }
-
- @Override
- public long getLong(int columnIndex)
- {
- checkPosition();
-
- synchronized(mUpdatedRows) {
- if (isFieldUpdated(columnIndex)) {
- Number value = (Number)getUpdatedField(columnIndex);
- return value.longValue();
- }
- }
-
- return mWindow.getLong(mPos, columnIndex);
- }
-
- @Override
- public float getFloat(int columnIndex)
- {
- checkPosition();
-
- synchronized(mUpdatedRows) {
- if (isFieldUpdated(columnIndex)) {
- Number value = (Number)getUpdatedField(columnIndex);
- return value.floatValue();
- }
- }
-
- return mWindow.getFloat(mPos, columnIndex);
- }
-
- @Override
- public double getDouble(int columnIndex)
- {
- checkPosition();
-
- synchronized(mUpdatedRows) {
- if (isFieldUpdated(columnIndex)) {
- Number value = (Number)getUpdatedField(columnIndex);
- return value.doubleValue();
- }
- }
-
- return mWindow.getDouble(mPos, columnIndex);
- }
-
- @Override
- public boolean isNull(int columnIndex)
- {
- checkPosition();
-
- synchronized(mUpdatedRows) {
- if (isFieldUpdated(columnIndex)) {
- return getUpdatedField(columnIndex) == null;
- }
- }
-
- return mWindow.isNull(mPos, columnIndex);
- }
-
- 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);
- }
-
- @Override
- protected void checkPosition()
- {
- super.checkPosition();
-
- if (mWindow == null) {
- throw new StaleDataException("Access closed cursor");
- }
- }
-
- @Override
- public CursorWindow getWindow() {
- return mWindow;
- }
-
- /**
- * Set a new cursor window to cursor, usually set a remote cursor window
- * @param window cursor window
- */
- public void setWindow(CursorWindow window) {
- if (mWindow != null) {
- mWindow.close();
- }
- mWindow = window;
- }
-
- public boolean hasWindow() {
- return mWindow != null;
- }
-
- /**
- * This needs be updated in {@link #onMove} by subclasses, and
- * needs to be set to NULL when the contents of the cursor change.
- */
- protected CursorWindow mWindow;
-}
diff --git a/core/java/android/database/BulkCursorNative.java b/core/java/android/database/BulkCursorNative.java
deleted file mode 100644
index baa94d8..0000000
--- a/core/java/android/database/BulkCursorNative.java
+++ /dev/null
@@ -1,440 +0,0 @@
-/*
- * 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database;
-
-import android.os.Binder;
-import android.os.RemoteException;
-import android.os.IBinder;
-import android.os.Parcel;
-import android.os.Bundle;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Native implementation of the bulk cursor. This is only for use in implementing
- * IPC, application code should use the Cursor interface.
- *
- * {@hide}
- */
-public abstract class BulkCursorNative extends Binder implements IBulkCursor
-{
- public BulkCursorNative()
- {
- attachInterface(this, descriptor);
- }
-
- /**
- * Cast a Binder object into a content resolver interface, generating
- * a proxy if needed.
- */
- static public IBulkCursor asInterface(IBinder obj)
- {
- if (obj == null) {
- return null;
- }
- IBulkCursor in = (IBulkCursor)obj.queryLocalInterface(descriptor);
- if (in != null) {
- return in;
- }
-
- return new BulkCursorProxy(obj);
- }
-
- @Override
- public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
- throws RemoteException {
- try {
- switch (code) {
- case GET_CURSOR_WINDOW_TRANSACTION: {
- data.enforceInterface(IBulkCursor.descriptor);
- int startPos = data.readInt();
- CursorWindow window = getWindow(startPos);
- if (window == null) {
- reply.writeInt(0);
- return true;
- }
- reply.writeNoException();
- reply.writeInt(1);
- window.writeToParcel(reply, 0);
- return true;
- }
-
- case COUNT_TRANSACTION: {
- data.enforceInterface(IBulkCursor.descriptor);
- int count = count();
- reply.writeNoException();
- reply.writeInt(count);
- return true;
- }
-
- case GET_COLUMN_NAMES_TRANSACTION: {
- data.enforceInterface(IBulkCursor.descriptor);
- String[] columnNames = getColumnNames();
- reply.writeNoException();
- reply.writeInt(columnNames.length);
- int length = columnNames.length;
- for (int i = 0; i < length; i++) {
- reply.writeString(columnNames[i]);
- }
- return true;
- }
-
- case DEACTIVATE_TRANSACTION: {
- data.enforceInterface(IBulkCursor.descriptor);
- deactivate();
- reply.writeNoException();
- return true;
- }
-
- case CLOSE_TRANSACTION: {
- data.enforceInterface(IBulkCursor.descriptor);
- close();
- reply.writeNoException();
- return true;
- }
-
- case REQUERY_TRANSACTION: {
- data.enforceInterface(IBulkCursor.descriptor);
- IContentObserver observer =
- IContentObserver.Stub.asInterface(data.readStrongBinder());
- CursorWindow window = CursorWindow.CREATOR.createFromParcel(data);
- int count = requery(observer, window);
- reply.writeNoException();
- reply.writeInt(count);
- reply.writeBundle(getExtras());
- return true;
- }
-
- case UPDATE_ROWS_TRANSACTION: {
- data.enforceInterface(IBulkCursor.descriptor);
- // TODO - what ClassLoader should be passed to readHashMap?
- // TODO - switch to Bundle
- HashMap<Long, Map<String, Object>> values = data.readHashMap(null);
- boolean result = updateRows(values);
- reply.writeNoException();
- reply.writeInt((result == true ? 1 : 0));
- return true;
- }
-
- case DELETE_ROW_TRANSACTION: {
- data.enforceInterface(IBulkCursor.descriptor);
- int position = data.readInt();
- boolean result = deleteRow(position);
- reply.writeNoException();
- reply.writeInt((result == true ? 1 : 0));
- return true;
- }
-
- case ON_MOVE_TRANSACTION: {
- data.enforceInterface(IBulkCursor.descriptor);
- int position = data.readInt();
- onMove(position);
- reply.writeNoException();
- return true;
- }
-
- case WANTS_ON_MOVE_TRANSACTION: {
- data.enforceInterface(IBulkCursor.descriptor);
- boolean result = getWantsAllOnMoveCalls();
- reply.writeNoException();
- reply.writeInt(result ? 1 : 0);
- return true;
- }
-
- case GET_EXTRAS_TRANSACTION: {
- data.enforceInterface(IBulkCursor.descriptor);
- Bundle extras = getExtras();
- reply.writeNoException();
- reply.writeBundle(extras);
- return true;
- }
-
- case RESPOND_TRANSACTION: {
- data.enforceInterface(IBulkCursor.descriptor);
- Bundle extras = data.readBundle();
- Bundle returnExtras = respond(extras);
- reply.writeNoException();
- reply.writeBundle(returnExtras);
- return true;
- }
- }
- } catch (Exception e) {
- DatabaseUtils.writeExceptionToParcel(reply, e);
- return true;
- }
-
- return super.onTransact(code, data, reply, flags);
- }
-
- public IBinder asBinder()
- {
- return this;
- }
-}
-
-
-final class BulkCursorProxy implements IBulkCursor {
- private IBinder mRemote;
- private Bundle mExtras;
-
- public BulkCursorProxy(IBinder remote)
- {
- mRemote = remote;
- mExtras = null;
- }
-
- public IBinder asBinder()
- {
- return mRemote;
- }
-
- public CursorWindow getWindow(int startPos) throws RemoteException
- {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
-
- data.writeInterfaceToken(IBulkCursor.descriptor);
-
- data.writeInt(startPos);
-
- mRemote.transact(GET_CURSOR_WINDOW_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
-
- CursorWindow window = null;
- if (reply.readInt() == 1) {
- window = CursorWindow.newFromParcel(reply);
- }
-
- data.recycle();
- reply.recycle();
-
- return window;
- }
-
- public void onMove(int position) throws RemoteException {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
-
- data.writeInterfaceToken(IBulkCursor.descriptor);
-
- data.writeInt(position);
-
- mRemote.transact(ON_MOVE_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
-
- data.recycle();
- reply.recycle();
- }
-
- public int count() throws RemoteException
- {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
-
- data.writeInterfaceToken(IBulkCursor.descriptor);
-
- boolean result = mRemote.transact(COUNT_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
-
- int count;
- if (result == false) {
- count = -1;
- } else {
- count = reply.readInt();
- }
- data.recycle();
- reply.recycle();
- return count;
- }
-
- public String[] getColumnNames() throws RemoteException
- {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
-
- data.writeInterfaceToken(IBulkCursor.descriptor);
-
- mRemote.transact(GET_COLUMN_NAMES_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
-
- String[] columnNames = null;
- int numColumns = reply.readInt();
- columnNames = new String[numColumns];
- for (int i = 0; i < numColumns; i++) {
- columnNames[i] = reply.readString();
- }
-
- data.recycle();
- reply.recycle();
- return columnNames;
- }
-
- public void deactivate() throws RemoteException
- {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
-
- data.writeInterfaceToken(IBulkCursor.descriptor);
-
- mRemote.transact(DEACTIVATE_TRANSACTION, data, reply, 0);
- DatabaseUtils.readExceptionFromParcel(reply);
-
- data.recycle();
- reply.recycle();
- }
-
- public void close() throws RemoteException
- {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
-
- data.writeInterfaceToken(IBulkCursor.descriptor);
-
- mRemote.transact(CLOSE_TRANSACTION, data, reply, 0);
- DatabaseUtils.readExceptionFromParcel(reply);
-
- data.recycle();
- reply.recycle();
- }
-
- public int requery(IContentObserver observer, CursorWindow window) throws RemoteException {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
-
- data.writeInterfaceToken(IBulkCursor.descriptor);
-
- data.writeStrongInterface(observer);
- window.writeToParcel(data, 0);
-
- boolean result = mRemote.transact(REQUERY_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
-
- int count;
- if (!result) {
- count = -1;
- } else {
- count = reply.readInt();
- mExtras = reply.readBundle();
- }
-
- data.recycle();
- reply.recycle();
-
- return count;
- }
-
- public boolean updateRows(Map values) throws RemoteException
- {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
-
- data.writeInterfaceToken(IBulkCursor.descriptor);
-
- data.writeMap(values);
-
- mRemote.transact(UPDATE_ROWS_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
-
- boolean result = (reply.readInt() == 1 ? true : false);
-
- data.recycle();
- reply.recycle();
-
- return result;
- }
-
- public boolean deleteRow(int position) throws RemoteException
- {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
-
- data.writeInterfaceToken(IBulkCursor.descriptor);
-
- data.writeInt(position);
-
- mRemote.transact(DELETE_ROW_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
-
- boolean result = (reply.readInt() == 1 ? true : false);
-
- data.recycle();
- reply.recycle();
-
- return result;
- }
-
- public boolean getWantsAllOnMoveCalls() throws RemoteException {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
-
- data.writeInterfaceToken(IBulkCursor.descriptor);
-
- mRemote.transact(WANTS_ON_MOVE_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
-
- int result = reply.readInt();
- data.recycle();
- reply.recycle();
- return result != 0;
- }
-
- public Bundle getExtras() throws RemoteException {
- if (mExtras == null) {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
-
- data.writeInterfaceToken(IBulkCursor.descriptor);
-
- mRemote.transact(GET_EXTRAS_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
-
- mExtras = reply.readBundle();
- data.recycle();
- reply.recycle();
- }
- return mExtras;
- }
-
- public Bundle respond(Bundle extras) throws RemoteException {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
-
- data.writeInterfaceToken(IBulkCursor.descriptor);
-
- data.writeBundle(extras);
-
- mRemote.transact(RESPOND_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
-
- Bundle returnExtras = reply.readBundle();
- data.recycle();
- reply.recycle();
- return returnExtras;
- }
-}
-
diff --git a/core/java/android/database/BulkCursorToCursorAdaptor.java b/core/java/android/database/BulkCursorToCursorAdaptor.java
deleted file mode 100644
index c26810a..0000000
--- a/core/java/android/database/BulkCursorToCursorAdaptor.java
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database;
-
-import android.os.RemoteException;
-import android.os.Bundle;
-import android.util.Log;
-
-import java.util.Map;
-
-/**
- * Adapts an {@link IBulkCursor} to a {@link Cursor} for use in the local
- * process.
- *
- * {@hide}
- */
-public final class BulkCursorToCursorAdaptor extends AbstractWindowedCursor {
- private static final String TAG = "BulkCursor";
-
- private SelfContentObserver mObserverBridge;
- private IBulkCursor mBulkCursor;
- private int mCount;
- private String[] mColumns;
- private boolean mWantsAllOnMoveCalls;
-
- public void set(IBulkCursor bulkCursor) {
- mBulkCursor = bulkCursor;
-
- try {
- mCount = mBulkCursor.count();
- mWantsAllOnMoveCalls = mBulkCursor.getWantsAllOnMoveCalls();
-
- // Search for the rowID column index and set it for our parent
- mColumns = mBulkCursor.getColumnNames();
- int length = mColumns.length;
- for (int i = 0; i < length; i++) {
- if (mColumns[i].equals("_id")) {
- mRowIdColumnIndex = i;
- break;
- }
- }
- } catch (RemoteException ex) {
- Log.e(TAG, "Setup failed because the remote process is dead");
- }
- }
-
- /**
- * Gets a SelfDataChangeOberserver that can be sent to a remote
- * process to receive change notifications over IPC.
- *
- * @return A SelfContentObserver hooked up to this Cursor
- */
- public synchronized IContentObserver getObserver() {
- if (mObserverBridge == null) {
- mObserverBridge = new SelfContentObserver(this);
- }
- return mObserverBridge.getContentObserver();
- }
-
- @Override
- public int getCount() {
- return mCount;
- }
-
- @Override
- public boolean onMove(int oldPosition, int newPosition) {
- try {
- // Make sure we have the proper window
- if (mWindow != null) {
- if (newPosition < mWindow.getStartPosition() ||
- newPosition >= (mWindow.getStartPosition() + mWindow.getNumRows())) {
- mWindow = mBulkCursor.getWindow(newPosition);
- } else if (mWantsAllOnMoveCalls) {
- mBulkCursor.onMove(newPosition);
- }
- } else {
- mWindow = mBulkCursor.getWindow(newPosition);
- }
- } catch (RemoteException ex) {
- // We tried to get a window and failed
- Log.e(TAG, "Unable to get window because the remote process is dead");
- return false;
- }
-
- // Couldn't obtain a window, something is wrong
- if (mWindow == null) {
- return false;
- }
-
- return true;
- }
-
- @Override
- public void deactivate() {
- // This will call onInvalidated(), so make sure to do it before calling release,
- // which is what actually makes the data set invalid.
- super.deactivate();
-
- try {
- mBulkCursor.deactivate();
- } catch (RemoteException ex) {
- Log.w(TAG, "Remote process exception when deactivating");
- }
- mWindow = null;
- }
-
- @Override
- public void close() {
- super.close();
- try {
- mBulkCursor.close();
- } catch (RemoteException ex) {
- Log.w(TAG, "Remote process exception when closing");
- }
- mWindow = null;
- }
-
- @Override
- public boolean requery() {
- try {
- int oldCount = mCount;
- //TODO get the window from a pool somewhere to avoid creating the memory dealer
- mCount = mBulkCursor.requery(getObserver(), new CursorWindow(
- false /* the window will be accessed across processes */));
- if (mCount != -1) {
- mPos = -1;
- mWindow = null;
-
- // super.requery() will call onChanged. Do it here instead of relying on the
- // observer from the far side so that observers can see a correct value for mCount
- // when responding to onChanged.
- super.requery();
- return true;
- } else {
- deactivate();
- return false;
- }
- } catch (Exception ex) {
- Log.e(TAG, "Unable to requery because the remote process exception " + ex.getMessage());
- deactivate();
- return false;
- }
- }
-
- /**
- * @hide
- * @deprecated
- */
- @Override
- public boolean deleteRow() {
- try {
- boolean result = mBulkCursor.deleteRow(mPos);
- if (result != false) {
- // The window contains the old value, discard it
- mWindow = null;
-
- // Fix up the position
- mCount = mBulkCursor.count();
- if (mPos < mCount) {
- int oldPos = mPos;
- mPos = -1;
- moveToPosition(oldPos);
- } else {
- mPos = mCount;
- }
-
- // Send the change notification
- onChange(true);
- }
- return result;
- } catch (RemoteException ex) {
- Log.e(TAG, "Unable to delete row because the remote process is dead");
- return false;
- }
- }
-
- @Override
- public String[] getColumnNames() {
- return mColumns;
- }
-
- /**
- * @hide
- * @deprecated
- */
- @Override
- public boolean commitUpdates(Map<? extends Long,
- ? extends Map<String,Object>> additionalValues) {
- if (!supportsUpdates()) {
- Log.e(TAG, "commitUpdates not supported on this cursor, did you include the _id column?");
- return false;
- }
-
- synchronized(mUpdatedRows) {
- if (additionalValues != null) {
- mUpdatedRows.putAll(additionalValues);
- }
-
- if (mUpdatedRows.size() <= 0) {
- return false;
- }
-
- try {
- boolean result = mBulkCursor.updateRows(mUpdatedRows);
-
- if (result == true) {
- mUpdatedRows.clear();
-
- // Send the change notification
- onChange(true);
- }
- return result;
- } catch (RemoteException ex) {
- Log.e(TAG, "Unable to commit updates because the remote process is dead");
- return false;
- }
- }
- }
-
- @Override
- public Bundle getExtras() {
- try {
- return mBulkCursor.getExtras();
- } catch (RemoteException e) {
- // This should never happen because the system kills processes that are using remote
- // cursors when the provider process is killed.
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public Bundle respond(Bundle extras) {
- try {
- return mBulkCursor.respond(extras);
- } catch (RemoteException e) {
- // This should never happen because the system kills processes that are using remote
- // cursors when the provider process is killed.
- throw new RuntimeException(e);
- }
- }
-}
-
diff --git a/core/java/android/database/CharArrayBuffer.java b/core/java/android/database/CharArrayBuffer.java
deleted file mode 100644
index 73781b7..0000000
--- a/core/java/android/database/CharArrayBuffer.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2008 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database;
-
-/**
- * This is used for {@link Cursor#copyStringToBuffer}
- */
-public final class CharArrayBuffer {
- public CharArrayBuffer(int size) {
- data = new char[size];
- }
-
- public CharArrayBuffer(char[] buf) {
- data = buf;
- }
-
- public char[] data; // In and out parameter
- public int sizeCopied; // Out parameter
-}
diff --git a/core/java/android/database/ContentObservable.java b/core/java/android/database/ContentObservable.java
deleted file mode 100644
index 8d7b7c5..0000000
--- a/core/java/android/database/ContentObservable.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2007 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database;
-
-/**
- * A specialization of Observable for ContentObserver that provides methods for
- * invoking the various callback methods of ContentObserver.
- */
-public class ContentObservable extends Observable<ContentObserver> {
-
- @Override
- public void registerObserver(ContentObserver observer) {
- super.registerObserver(observer);
- }
-
- /**
- * invokes dispatchUpdate on each observer, unless the observer doesn't want
- * self-notifications and the update is from a self-notification
- * @param selfChange
- */
- public void dispatchChange(boolean selfChange) {
- synchronized(mObservers) {
- for (ContentObserver observer : mObservers) {
- if (!selfChange || observer.deliverSelfNotifications()) {
- observer.dispatchChange(selfChange);
- }
- }
- }
- }
-
- /**
- * invokes onChange on each observer
- * @param selfChange
- */
- public void notifyChange(boolean selfChange) {
- synchronized(mObservers) {
- for (ContentObserver observer : mObservers) {
- observer.onChange(selfChange);
- }
- }
- }
-}
diff --git a/core/java/android/database/ContentObserver.java b/core/java/android/database/ContentObserver.java
deleted file mode 100644
index 3b829a3..0000000
--- a/core/java/android/database/ContentObserver.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2007 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database;
-
-import android.os.Handler;
-
-/**
- * Receives call backs for changes to content. Must be implemented by objects which are added
- * to a {@link ContentObservable}.
- */
-public abstract class ContentObserver {
-
- private Transport mTransport;
-
- // Protects mTransport
- private Object lock = new Object();
-
- /* package */ Handler mHandler;
-
- private final class NotificationRunnable implements Runnable {
-
- private boolean mSelf;
-
- public NotificationRunnable(boolean self) {
- mSelf = self;
- }
-
- public void run() {
- ContentObserver.this.onChange(mSelf);
- }
- }
-
- private static final class Transport extends IContentObserver.Stub {
- ContentObserver mContentObserver;
-
- public Transport(ContentObserver contentObserver) {
- mContentObserver = contentObserver;
- }
-
- public boolean deliverSelfNotifications() {
- ContentObserver contentObserver = mContentObserver;
- if (contentObserver != null) {
- return contentObserver.deliverSelfNotifications();
- }
- return false;
- }
-
- public void onChange(boolean selfChange) {
- ContentObserver contentObserver = mContentObserver;
- if (contentObserver != null) {
- contentObserver.dispatchChange(selfChange);
- }
- }
-
- public void releaseContentObserver() {
- mContentObserver = null;
- }
- }
-
- /**
- * onChange() will happen on the provider Handler.
- *
- * @param handler The handler to run {@link #onChange} on.
- */
- public ContentObserver(Handler handler) {
- mHandler = handler;
- }
-
- /**
- * Gets access to the binder transport object. Not for public consumption.
- *
- * {@hide}
- */
- public IContentObserver getContentObserver() {
- synchronized(lock) {
- if (mTransport == null) {
- mTransport = new Transport(this);
- }
- return mTransport;
- }
- }
-
- /**
- * Gets access to the binder transport object, and unlinks the transport object
- * from the ContentObserver. Not for public consumption.
- *
- * {@hide}
- */
- public IContentObserver releaseContentObserver() {
- synchronized(lock) {
- Transport oldTransport = mTransport;
- if (oldTransport != null) {
- oldTransport.releaseContentObserver();
- mTransport = null;
- }
- return oldTransport;
- }
- }
-
- /**
- * Returns true if this observer is interested in notifications for changes
- * made through the cursor the observer is registered with.
- */
- public boolean deliverSelfNotifications() {
- return false;
- }
-
- /**
- * This method is called when a change occurs to the cursor that
- * is being observed.
- *
- * @param selfChange true if the update was caused by a call to <code>commit</code> on the
- * cursor that is being observed.
- */
- public void onChange(boolean selfChange) {}
-
- public final void dispatchChange(boolean selfChange) {
- if (mHandler == null) {
- onChange(selfChange);
- } else {
- mHandler.post(new NotificationRunnable(selfChange));
- }
- }
-}
diff --git a/core/java/android/database/CrossProcessCursor.java b/core/java/android/database/CrossProcessCursor.java
deleted file mode 100644
index 77ba3a5..0000000
--- a/core/java/android/database/CrossProcessCursor.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2008 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database;
-
-public interface CrossProcessCursor extends Cursor{
- /**
- * returns a pre-filled window, return NULL if no such window
- */
- CursorWindow getWindow();
-
- /**
- * copies cursor data into the window start at pos
- */
- void fillWindow(int pos, CursorWindow winow);
-
- /**
- * This function is called every time the cursor is successfully scrolled
- * to a new position, giving the subclass a chance to update any state it
- * may have. If it returns false the move function will also do so and the
- * cursor will scroll to the beforeFirst position.
- *
- * @param oldPosition the position that we're moving from
- * @param newPosition the position that we're moving to
- * @return true if the move is successful, false otherwise
- */
- boolean onMove(int oldPosition, int newPosition);
-
-}
diff --git a/core/java/android/database/Cursor.java b/core/java/android/database/Cursor.java
deleted file mode 100644
index 79178f4..0000000
--- a/core/java/android/database/Cursor.java
+++ /dev/null
@@ -1,587 +0,0 @@
-/*
- * 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database;
-
-import android.content.ContentResolver;
-import android.net.Uri;
-import android.os.Bundle;
-
-import java.util.Map;
-
-/**
- * This interface provides random read-write access to the result set returned
- * by a database query.
- */
-public interface Cursor {
- /**
- * Returns the numbers of rows in the cursor.
- *
- * @return the number of rows in the cursor.
- */
- int getCount();
-
- /**
- * Returns the current position of the cursor in the row set.
- * The value is zero-based. When the row set is first returned the cursor
- * will be at positon -1, which is before the first row. After the
- * last row is returned another call to next() will leave the cursor past
- * the last entry, at a position of count().
- *
- * @return the current cursor position.
- */
- int getPosition();
-
- /**
- * Move the cursor by a relative amount, forward or backward, from the
- * current position. Positive offsets move forwards, negative offsets move
- * backwards. If the final position is outside of the bounds of the result
- * set then the resultant position will be pinned to -1 or count() depending
- * on whether the value is off the front or end of the set, respectively.
- *
- * <p>This method will return true if the requested destination was
- * reachable, otherwise, it returns false. For example, if the cursor is at
- * currently on the second entry in the result set and move(-5) is called,
- * the position will be pinned at -1, and false will be returned.
- *
- * @param offset the offset to be applied from the current position.
- * @return whether the requested move fully succeeded.
- */
- boolean move(int offset);
-
- /**
- * Move the cursor to an absolute position. The valid
- * range of values is -1 &lt;= position &lt;= count.
- *
- * <p>This method will return true if the request destination was reachable,
- * otherwise, it returns false.
- *
- * @param position the zero-based position to move to.
- * @return whether the requested move fully succeeded.
- */
- boolean moveToPosition(int position);
-
- /**
- * Move the cursor to the first row.
- *
- * <p>This method will return false if the cursor is empty.
- *
- * @return whether the move succeeded.
- */
- boolean moveToFirst();
-
- /**
- * Move the cursor to the last row.
- *
- * <p>This method will return false if the cursor is empty.
- *
- * @return whether the move succeeded.
- */
- boolean moveToLast();
-
- /**
- * Move the cursor to the next row.
- *
- * <p>This method will return false if the cursor is already past the
- * last entry in the result set.
- *
- * @return whether the move succeeded.
- */
- boolean moveToNext();
-
- /**
- * Move the cursor to the previous row.
- *
- * <p>This method will return false if the cursor is already before the
- * first entry in the result set.
- *
- * @return whether the move succeeded.
- */
- boolean moveToPrevious();
-
- /**
- * Returns whether the cursor is pointing to the first row.
- *
- * @return whether the cursor is pointing at the first entry.
- */
- boolean isFirst();
-
- /**
- * Returns whether the cursor is pointing to the last row.
- *
- * @return whether the cursor is pointing at the last entry.
- */
- boolean isLast();
-
- /**
- * Returns whether the cursor is pointing to the position before the first
- * row.
- *
- * @return whether the cursor is before the first result.
- */
- boolean isBeforeFirst();
-
- /**
- * Returns whether the cursor is pointing to the position after the last
- * row.
- *
- * @return whether the cursor is after the last result.
- */
- boolean isAfterLast();
-
- /**
- * Removes the row at the current cursor position from the underlying data
- * store. After this method returns the cursor will be pointing to the row
- * after the row that is deleted. This has the side effect of decrementing
- * the result of count() by one.
- * <p>
- * The query must have the row ID column in its selection, otherwise this
- * call will fail.
- *
- * @hide
- * @return whether the record was successfully deleted.
- * @deprecated use {@link ContentResolver#delete(Uri, String, String[])}
- */
- @Deprecated
- boolean deleteRow();
-
- /**
- * Returns the zero-based index for the given column name, or -1 if the column doesn't exist.
- * If you expect the column to exist use {@link #getColumnIndexOrThrow(String)} instead, which
- * will make the error more clear.
- *
- * @param columnName the name of the target column.
- * @return the zero-based column index for the given column name, or -1 if
- * the column name does not exist.
- * @see #getColumnIndexOrThrow(String)
- */
- int getColumnIndex(String columnName);
-
- /**
- * Returns the zero-based index for the given column name, or throws
- * {@link IllegalArgumentException} if the column doesn't exist. If you're not sure if
- * a column will exist or not use {@link #getColumnIndex(String)} and check for -1, which
- * is more efficient than catching the exceptions.
- *
- * @param columnName the name of the target column.
- * @return the zero-based column index for the given column name
- * @see #getColumnIndex(String)
- * @throws IllegalArgumentException if the column does not exist
- */
- int getColumnIndexOrThrow(String columnName) throws IllegalArgumentException;
-
- /**
- * Returns the column name at the given zero-based column index.
- *
- * @param columnIndex the zero-based index of the target column.
- * @return the column name for the given column index.
- */
- String getColumnName(int columnIndex);
-
- /**
- * Returns a string array holding the names of all of the columns in the
- * result set in the order in which they were listed in the result.
- *
- * @return the names of the columns returned in this query.
- */
- String[] getColumnNames();
-
- /**
- * Return total number of columns
- * @return number of columns
- */
- int getColumnCount();
-
- /**
- * Returns the value of the requested column as a byte array.
- *
- * <p>If the native content of that column is not blob exception may throw
- *
- * @param columnIndex the zero-based index of the target column.
- * @return the value of that column as a byte array.
- */
- byte[] getBlob(int columnIndex);
-
- /**
- * Returns the value of the requested column as a String.
- *
- * <p>If the native content of that column is not text the result will be
- * the result of passing the column value to String.valueOf(x).
- *
- * @param columnIndex the zero-based index of the target column.
- * @return the value of that column as a String.
- */
- String getString(int columnIndex);
-
- /**
- * Retrieves the requested column text and stores it in the buffer provided.
- * If the buffer size is not sufficient, a new char buffer will be allocated
- * and assigned to CharArrayBuffer.data
- * @param columnIndex the zero-based index of the target column.
- * if the target column is null, return buffer
- * @param buffer the buffer to copy the text into.
- */
- void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer);
-
- /**
- * Returns the value of the requested column as a short.
- *
- * <p>If the native content of that column is not numeric the result will be
- * the result of passing the column value to Short.valueOf(x).
- *
- * @param columnIndex the zero-based index of the target column.
- * @return the value of that column as a short.
- */
- short getShort(int columnIndex);
-
- /**
- * Returns the value of the requested column as an int.
- *
- * <p>If the native content of that column is not numeric the result will be
- * the result of passing the column value to Integer.valueOf(x).
- *
- * @param columnIndex the zero-based index of the target column.
- * @return the value of that column as an int.
- */
- int getInt(int columnIndex);
-
- /**
- * Returns the value of the requested column as a long.
- *
- * <p>If the native content of that column is not numeric the result will be
- * the result of passing the column value to Long.valueOf(x).
- *
- * @param columnIndex the zero-based index of the target column.
- * @return the value of that column as a long.
- */
- long getLong(int columnIndex);
-
- /**
- * Returns the value of the requested column as a float.
- *
- * <p>If the native content of that column is not numeric the result will be
- * the result of passing the column value to Float.valueOf(x).
- *
- * @param columnIndex the zero-based index of the target column.
- * @return the value of that column as a float.
- */
- float getFloat(int columnIndex);
-
- /**
- * Returns the value of the requested column as a double.
- *
- * <p>If the native content of that column is not numeric the result will be
- * the result of passing the column value to Double.valueOf(x).
- *
- * @param columnIndex the zero-based index of the target column.
- * @return the value of that column as a double.
- */
- double getDouble(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.
- * @return whether the column value is null.
- */
- boolean isNull(int columnIndex);
-
- /**
- * Returns <code>true</code> if the cursor supports updates.
- *
- * @return whether the cursor supports updates.
- * @hide
- * @deprecated use the {@link ContentResolver} update methods instead of the Cursor
- * update methods
- */
- @Deprecated
- boolean supportsUpdates();
-
- /**
- * Returns <code>true</code> if there are pending updates that have not yet been committed.
- *
- * @return <code>true</code> if there are pending updates that have not yet been committed.
- * @hide
- * @deprecated use the {@link ContentResolver} update methods instead of the Cursor
- * update methods
- */
- @Deprecated
- boolean hasUpdates();
-
- /**
- * Updates the value for the given column in the row the cursor is
- * currently pointing at. Updates are not committed to the backing store
- * until {@link #commitUpdates()} is called.
- *
- * @param columnIndex the zero-based index of the target column.
- * @param value the new value.
- * @return whether the operation succeeded.
- * @hide
- * @deprecated use the {@link ContentResolver} update methods instead of the Cursor
- * update methods
- */
- @Deprecated
- boolean updateBlob(int columnIndex, byte[] value);
-
- /**
- * Updates the value for the given column in the row the cursor is
- * currently pointing at. Updates are not committed to the backing store
- * until {@link #commitUpdates()} is called.
- *
- * @param columnIndex the zero-based index of the target column.
- * @param value the new value.
- * @return whether the operation succeeded.
- * @hide
- * @deprecated use the {@link ContentResolver} update methods instead of the Cursor
- * update methods
- */
- @Deprecated
- boolean updateString(int columnIndex, String value);
-
- /**
- * Updates the value for the given column in the row the cursor is
- * currently pointing at. Updates are not committed to the backing store
- * until {@link #commitUpdates()} is called.
- *
- * @param columnIndex the zero-based index of the target column.
- * @param value the new value.
- * @return whether the operation succeeded.
- * @hide
- * @deprecated use the {@link ContentResolver} update methods instead of the Cursor
- * update methods
- */
- @Deprecated
- boolean updateShort(int columnIndex, short value);
-
- /**
- * Updates the value for the given column in the row the cursor is
- * currently pointing at. Updates are not committed to the backing store
- * until {@link #commitUpdates()} is called.
- *
- * @param columnIndex the zero-based index of the target column.
- * @param value the new value.
- * @return whether the operation succeeded.
- * @hide
- * @deprecated use the {@link ContentResolver} update methods instead of the Cursor
- * update methods
- */
- @Deprecated
- boolean updateInt(int columnIndex, int value);
-
- /**
- * Updates the value for the given column in the row the cursor is
- * currently pointing at. Updates are not committed to the backing store
- * until {@link #commitUpdates()} is called.
- *
- * @param columnIndex the zero-based index of the target column.
- * @param value the new value.
- * @return whether the operation succeeded.
- * @hide
- * @deprecated use the {@link ContentResolver} update methods instead of the Cursor
- * update methods
- */
- @Deprecated
- boolean updateLong(int columnIndex, long value);
-
- /**
- * Updates the value for the given column in the row the cursor is
- * currently pointing at. Updates are not committed to the backing store
- * until {@link #commitUpdates()} is called.
- *
- * @param columnIndex the zero-based index of the target column.
- * @param value the new value.
- * @return whether the operation succeeded.
- * @hide
- * @deprecated use the {@link ContentResolver} update methods instead of the Cursor
- * update methods
- */
- @Deprecated
- boolean updateFloat(int columnIndex, float value);
-
- /**
- * Updates the value for the given column in the row the cursor is
- * currently pointing at. Updates are not committed to the backing store
- * until {@link #commitUpdates()} is called.
- *
- * @param columnIndex the zero-based index of the target column.
- * @param value the new value.
- * @return whether the operation succeeded.
- * @hide
- * @deprecated use the {@link ContentResolver} update methods instead of the Cursor
- * update methods
- */
- @Deprecated
- boolean updateDouble(int columnIndex, double value);
-
- /**
- * Removes the value for the given column in the row the cursor is
- * currently pointing at. Updates are not committed to the backing store
- * until {@link #commitUpdates()} is called.
- *
- * @param columnIndex the zero-based index of the target column.
- * @return whether the operation succeeded.
- * @hide
- * @deprecated use the {@link ContentResolver} update methods instead of the Cursor
- * update methods
- */
- @Deprecated
- boolean updateToNull(int columnIndex);
-
- /**
- * Atomically commits all updates to the backing store. After completion,
- * this method leaves the data in an inconsistent state and you should call
- * {@link #requery} before reading data from the cursor again.
- *
- * @return whether the operation succeeded.
- * @hide
- * @deprecated use the {@link ContentResolver} update methods instead of the Cursor
- * update methods
- */
- @Deprecated
- boolean commitUpdates();
-
- /**
- * Atomically commits all updates to the backing store, as well as the
- * updates included in values. After completion,
- * this method leaves the data in an inconsistent state and you should call
- * {@link #requery} before reading data from the cursor again.
- *
- * @param values A map from row IDs to Maps associating column names with
- * updated values. A null value indicates the field should be
- removed.
- * @return whether the operation succeeded.
- * @hide
- * @deprecated use the {@link ContentResolver} update methods instead of the Cursor
- * update methods
- */
- @Deprecated
- boolean commitUpdates(Map<? extends Long,
- ? extends Map<String,Object>> values);
-
- /**
- * Reverts all updates made to the cursor since the last call to
- * commitUpdates.
- * @hide
- * @deprecated use the {@link ContentResolver} update methods instead of the Cursor
- * update methods
- */
- @Deprecated
- void abortUpdates();
-
- /**
- * Deactivates the Cursor, making all calls on it fail until {@link #requery} is called.
- * Inactive Cursors use fewer resources than active Cursors.
- * Calling {@link #requery} will make the cursor active again.
- */
- void deactivate();
-
- /**
- * Performs the query that created the cursor again, refreshing its
- * contents. This may be done at any time, including after a call to {@link
- * #deactivate}.
- *
- * @return true if the requery succeeded, false if not, in which case the
- * cursor becomes invalid.
- */
- boolean requery();
-
- /**
- * Closes the Cursor, releasing all of its resources and making it completely invalid.
- * Unlike {@link #deactivate()} a call to {@link #requery()} will not make the Cursor valid
- * again.
- */
- void close();
-
- /**
- * return true if the cursor is closed
- * @return true if the cursor is closed.
- */
- boolean isClosed();
-
- /**
- * Register an observer that is called when changes happen to the content backing this cursor.
- * Typically the data set won't change until {@link #requery()} is called.
- *
- * @param observer the object that gets notified when the content backing the cursor changes.
- * @see #unregisterContentObserver(ContentObserver)
- */
- void registerContentObserver(ContentObserver observer);
-
- /**
- * Unregister an observer that has previously been registered with this
- * cursor via {@link #registerContentObserver}.
- *
- * @param observer the object to unregister.
- * @see #registerContentObserver(ContentObserver)
- */
- void unregisterContentObserver(ContentObserver observer);
-
- /**
- * Register an observer that is called when changes happen to the contents
- * of the this cursors data set, for example, when the data set is changed via
- * {@link #requery()}, {@link #deactivate()}, or {@link #close()}.
- *
- * @param observer the object that gets notified when the cursors data set changes.
- * @see #unregisterDataSetObserver(DataSetObserver)
- */
- void registerDataSetObserver(DataSetObserver observer);
-
- /**
- * Unregister an observer that has previously been registered with this
- * cursor via {@link #registerContentObserver}.
- *
- * @param observer the object to unregister.
- * @see #registerDataSetObserver(DataSetObserver)
- */
- void unregisterDataSetObserver(DataSetObserver observer);
-
- /**
- * Register to watch a content URI for changes. This can be the URI of a specific data row (for
- * example, "content://my_provider_type/23"), or a a generic URI for a content type.
- *
- * @param cr The content resolver from the caller's context. The listener attached to
- * this resolver will be notified.
- * @param uri The content URI to watch.
- */
- void setNotificationUri(ContentResolver cr, Uri uri);
-
- /**
- * onMove() will only be called across processes if this method returns true.
- * @return whether all cursor movement should result in a call to onMove().
- */
- boolean getWantsAllOnMoveCalls();
-
- /**
- * Returns a bundle of extra values. This is an optional way for cursors to provide out-of-band
- * metadata to their users. One use of this is for reporting on the progress of network requests
- * that are required to fetch data for the cursor.
- *
- * <p>These values may only change when requery is called.
- * @return cursor-defined values, or Bundle.EMTPY if there are no values. Never null.
- */
- Bundle getExtras();
-
- /**
- * This is an out-of-band way for the the user of a cursor to communicate with the cursor. The
- * structure of each bundle is entirely defined by the cursor.
- *
- * <p>One use of this is to tell a cursor that it should retry its network request after it
- * reported an error.
- * @param extras extra values, or Bundle.EMTPY. Never null.
- * @return extra values, or Bundle.EMTPY. Never null.
- */
- Bundle respond(Bundle extras);
-}
diff --git a/core/java/android/database/CursorIndexOutOfBoundsException.java b/core/java/android/database/CursorIndexOutOfBoundsException.java
deleted file mode 100644
index 1f77d00..0000000
--- a/core/java/android/database/CursorIndexOutOfBoundsException.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database;
-
-/**
- * An exception indicating that a cursor is out of bounds.
- */
-public class CursorIndexOutOfBoundsException extends IndexOutOfBoundsException {
-
- public CursorIndexOutOfBoundsException(int index, int size) {
- super("Index " + index + " requested, with a size of " + size);
- }
-
- public CursorIndexOutOfBoundsException(String message) {
- super(message);
- }
-}
diff --git a/core/java/android/database/CursorJoiner.java b/core/java/android/database/CursorJoiner.java
deleted file mode 100644
index e3c2988..0000000
--- a/core/java/android/database/CursorJoiner.java
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Copyright (C) 2008 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database;
-
-import java.util.Iterator;
-
-/**
- * Does a join on two cursors using the specified columns. The cursors must already
- * be sorted on each of the specified columns in ascending order. This joiner only
- * supports the case where the tuple of key column values is unique.
- * <p>
- * Typical usage:
- *
- * <pre>
- * CursorJoiner joiner = new CursorJoiner(cursorA, keyColumnsofA, cursorB, keyColumnsofB);
- * for (CursorJointer.Result joinerResult : joiner) {
- * switch (joinerResult) {
- * case LEFT:
- * // handle case where a row in cursorA is unique
- * break;
- * case RIGHT:
- * // handle case where a row in cursorB is unique
- * break;
- * case BOTH:
- * // handle case where a row with the same key is in both cursors
- * break;
- * }
- * }
- * </pre>
- */
-public final class CursorJoiner
- implements Iterator<CursorJoiner.Result>, Iterable<CursorJoiner.Result> {
- private Cursor mCursorLeft;
- private Cursor mCursorRight;
- private boolean mCompareResultIsValid;
- private Result mCompareResult;
- private int[] mColumnsLeft;
- private int[] mColumnsRight;
- private String[] mValues;
-
- /**
- * The result of a call to next().
- */
- public enum Result {
- /** The row currently pointed to by the left cursor is unique */
- RIGHT,
- /** The row currently pointed to by the right cursor is unique */
- LEFT,
- /** The rows pointed to by both cursors are the same */
- BOTH
- }
-
- /**
- * Initializes the CursorJoiner and resets the cursors to the first row. The left and right
- * column name arrays must have the same number of columns.
- * @param cursorLeft The left cursor to compare
- * @param columnNamesLeft The column names to compare from the left cursor
- * @param cursorRight The right cursor to compare
- * @param columnNamesRight The column names to compare from the right cursor
- */
- public CursorJoiner(
- Cursor cursorLeft, String[] columnNamesLeft,
- Cursor cursorRight, String[] columnNamesRight) {
- if (columnNamesLeft.length != columnNamesRight.length) {
- throw new IllegalArgumentException(
- "you must have the same number of columns on the left and right, "
- + columnNamesLeft.length + " != " + columnNamesRight.length);
- }
-
- mCursorLeft = cursorLeft;
- mCursorRight = cursorRight;
-
- mCursorLeft.moveToFirst();
- mCursorRight.moveToFirst();
-
- mCompareResultIsValid = false;
-
- mColumnsLeft = buildColumnIndiciesArray(cursorLeft, columnNamesLeft);
- mColumnsRight = buildColumnIndiciesArray(cursorRight, columnNamesRight);
-
- mValues = new String[mColumnsLeft.length * 2];
- }
-
- public Iterator<Result> iterator() {
- return this;
- }
-
- /**
- * Lookup the indicies of the each column name and return them in an array.
- * @param cursor the cursor that contains the columns
- * @param columnNames the array of names to lookup
- * @return an array of column indices
- */
- private int[] buildColumnIndiciesArray(Cursor cursor, String[] columnNames) {
- int[] columns = new int[columnNames.length];
- for (int i = 0; i < columnNames.length; i++) {
- columns[i] = cursor.getColumnIndexOrThrow(columnNames[i]);
- }
- return columns;
- }
-
- /**
- * Returns whether or not there are more rows to compare using next().
- * @return true if there are more rows to compare
- */
- public boolean hasNext() {
- if (mCompareResultIsValid) {
- switch (mCompareResult) {
- case BOTH:
- return !mCursorLeft.isLast() || !mCursorRight.isLast();
-
- case LEFT:
- return !mCursorLeft.isLast() || !mCursorRight.isAfterLast();
-
- case RIGHT:
- return !mCursorLeft.isAfterLast() || !mCursorRight.isLast();
-
- default:
- throw new IllegalStateException("bad value for mCompareResult, "
- + mCompareResult);
- }
- } else {
- return !mCursorLeft.isAfterLast() || !mCursorRight.isAfterLast();
- }
- }
-
- /**
- * Returns the comparison result of the next row from each cursor. If one cursor
- * has no more rows but the other does then subsequent calls to this will indicate that
- * the remaining rows are unique.
- * <p>
- * The caller must check that hasNext() returns true before calling this.
- * <p>
- * Once next() has been called the cursors specified in the result of the call to
- * next() are guaranteed to point to the row that was indicated. Reading values
- * from the cursor that was not indicated in the call to next() will result in
- * undefined behavior.
- * @return LEFT, if the row pointed to by the left cursor is unique, RIGHT
- * if the row pointed to by the right cursor is unique, BOTH if the rows in both
- * cursors are the same.
- */
- public Result next() {
- if (!hasNext()) {
- throw new IllegalStateException("you must only call next() when hasNext() is true");
- }
- incrementCursors();
- assert hasNext();
-
- boolean hasLeft = !mCursorLeft.isAfterLast();
- boolean hasRight = !mCursorRight.isAfterLast();
-
- if (hasLeft && hasRight) {
- populateValues(mValues, mCursorLeft, mColumnsLeft, 0 /* start filling at index 0 */);
- populateValues(mValues, mCursorRight, mColumnsRight, 1 /* start filling at index 1 */);
- switch (compareStrings(mValues)) {
- case -1:
- mCompareResult = Result.LEFT;
- break;
- case 0:
- mCompareResult = Result.BOTH;
- break;
- case 1:
- mCompareResult = Result.RIGHT;
- break;
- }
- } else if (hasLeft) {
- mCompareResult = Result.LEFT;
- } else {
- assert hasRight;
- mCompareResult = Result.RIGHT;
- }
- mCompareResultIsValid = true;
- return mCompareResult;
- }
-
- public void remove() {
- throw new UnsupportedOperationException("not implemented");
- }
-
- /**
- * Reads the strings from the cursor that are specifed in the columnIndicies
- * array and saves them in values beginning at startingIndex, skipping a slot
- * for each value. If columnIndicies has length 3 and startingIndex is 1, the
- * values will be stored in slots 1, 3, and 5.
- * @param values the String[] to populate
- * @param cursor the cursor from which to read
- * @param columnIndicies the indicies of the values to read from the cursor
- * @param startingIndex the slot in which to start storing values, and must be either 0 or 1.
- */
- private static void populateValues(String[] values, Cursor cursor, int[] columnIndicies,
- int startingIndex) {
- assert startingIndex == 0 || startingIndex == 1;
- for (int i = 0; i < columnIndicies.length; i++) {
- values[startingIndex + i*2] = cursor.getString(columnIndicies[i]);
- }
- }
-
- /**
- * Increment the cursors past the rows indicated in the most recent call to next().
- * This will only have an affect once per call to next().
- */
- private void incrementCursors() {
- if (mCompareResultIsValid) {
- switch (mCompareResult) {
- case LEFT:
- mCursorLeft.moveToNext();
- break;
- case RIGHT:
- mCursorRight.moveToNext();
- break;
- case BOTH:
- mCursorLeft.moveToNext();
- mCursorRight.moveToNext();
- break;
- }
- mCompareResultIsValid = false;
- }
- }
-
- /**
- * Compare the values. Values contains n pairs of strings. If all the pairs of strings match
- * then returns 0. Otherwise returns the comparison result of the first non-matching pair
- * of values, -1 if the first of the pair is less than the second of the pair or 1 if it
- * is greater.
- * @param values the n pairs of values to compare
- * @return -1, 0, or 1 as described above.
- */
- private static int compareStrings(String... values) {
- if ((values.length % 2) != 0) {
- throw new IllegalArgumentException("you must specify an even number of values");
- }
-
- for (int index = 0; index < values.length; index+=2) {
- if (values[index] == null) {
- if (values[index+1] == null) continue;
- return -1;
- }
-
- if (values[index+1] == null) {
- return 1;
- }
-
- int comp = values[index].compareTo(values[index+1]);
- if (comp != 0) {
- return comp < 0 ? -1 : 1;
- }
- }
-
- return 0;
- }
-}
diff --git a/core/java/android/database/CursorToBulkCursorAdaptor.java b/core/java/android/database/CursorToBulkCursorAdaptor.java
deleted file mode 100644
index 19ad946..0000000
--- a/core/java/android/database/CursorToBulkCursorAdaptor.java
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database;
-
-import android.database.sqlite.SQLiteMisuseException;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Config;
-import android.util.Log;
-
-import java.util.Map;
-
-
-/**
- * Wraps a BulkCursor around an existing Cursor making it remotable.
- *
- * {@hide}
- */
-public final class CursorToBulkCursorAdaptor extends BulkCursorNative
- implements IBinder.DeathRecipient {
- private static final String TAG = "Cursor";
- private final CrossProcessCursor mCursor;
- private CursorWindow mWindow;
- private final String mProviderName;
- private final boolean mReadOnly;
- private ContentObserverProxy mObserver;
-
- private static final class ContentObserverProxy extends ContentObserver
- {
- protected IContentObserver mRemote;
-
- public ContentObserverProxy(IContentObserver remoteObserver, DeathRecipient recipient) {
- super(null);
- mRemote = remoteObserver;
- try {
- remoteObserver.asBinder().linkToDeath(recipient, 0);
- } catch (RemoteException e) {
- // Do nothing, the far side is dead
- }
- }
-
- public boolean unlinkToDeath(DeathRecipient recipient) {
- return mRemote.asBinder().unlinkToDeath(recipient, 0);
- }
-
- @Override
- public boolean deliverSelfNotifications() {
- // The far side handles the self notifications.
- return false;
- }
-
- @Override
- public void onChange(boolean selfChange) {
- try {
- mRemote.onChange(selfChange);
- } catch (RemoteException ex) {
- // Do nothing, the far side is dead
- }
- }
- }
-
- public CursorToBulkCursorAdaptor(Cursor cursor, IContentObserver observer, String providerName,
- boolean allowWrite, CursorWindow window) {
- try {
- mCursor = (CrossProcessCursor) cursor;
- if (mCursor instanceof AbstractWindowedCursor) {
- AbstractWindowedCursor windowedCursor = (AbstractWindowedCursor) cursor;
- if (windowedCursor.hasWindow()) {
- if (Log.isLoggable(TAG, Log.VERBOSE) || Config.LOGV) {
- Log.v(TAG, "Cross process cursor has a local window before setWindow in "
- + providerName, new RuntimeException());
- }
- }
- windowedCursor.setWindow(window);
- } else {
- mWindow = window;
- mCursor.fillWindow(0, window);
- }
- } catch (ClassCastException e) {
- // TODO Implement this case.
- throw new UnsupportedOperationException(
- "Only CrossProcessCursor cursors are supported across process for now", e);
- }
- mProviderName = providerName;
- mReadOnly = !allowWrite;
-
- createAndRegisterObserverProxy(observer);
- }
-
- public void binderDied() {
- mCursor.close();
- if (mWindow != null) {
- mWindow.close();
- }
- }
-
- public CursorWindow getWindow(int startPos) {
- mCursor.moveToPosition(startPos);
-
- if (mWindow != null) {
- if (startPos < mWindow.getStartPosition() ||
- startPos >= (mWindow.getStartPosition() + mWindow.getNumRows())) {
- mCursor.fillWindow(startPos, mWindow);
- }
- return mWindow;
- } else {
- return ((AbstractWindowedCursor)mCursor).getWindow();
- }
- }
-
- public void onMove(int position) {
- mCursor.onMove(mCursor.getPosition(), position);
- }
-
- public int count() {
- return mCursor.getCount();
- }
-
- public String[] getColumnNames() {
- return mCursor.getColumnNames();
- }
-
- public void deactivate() {
- maybeUnregisterObserverProxy();
- mCursor.deactivate();
- }
-
- public void close() {
- maybeUnregisterObserverProxy();
- mCursor.deactivate();
-
- }
-
- public int requery(IContentObserver observer, CursorWindow window) {
- if (mWindow == null) {
- ((AbstractWindowedCursor)mCursor).setWindow(window);
- }
- try {
- if (!mCursor.requery()) {
- return -1;
- }
- } catch (IllegalStateException e) {
- IllegalStateException leakProgram = new IllegalStateException(
- mProviderName + " Requery misuse db, mCursor isClosed:" +
- mCursor.isClosed(), e);
- throw leakProgram;
- }
-
- if (mWindow != null) {
- mCursor.fillWindow(0, window);
- mWindow = window;
- }
- maybeUnregisterObserverProxy();
- createAndRegisterObserverProxy(observer);
- return mCursor.getCount();
- }
-
- public boolean getWantsAllOnMoveCalls() {
- return mCursor.getWantsAllOnMoveCalls();
- }
-
- /**
- * Create a ContentObserver from the observer and register it as an observer on the
- * underlying cursor.
- * @param observer the IContentObserver that wants to monitor the cursor
- * @throws IllegalStateException if an observer is already registered
- */
- private void createAndRegisterObserverProxy(IContentObserver observer) {
- if (mObserver != null) {
- throw new IllegalStateException("an observer is already registered");
- }
- mObserver = new ContentObserverProxy(observer, this);
- mCursor.registerContentObserver(mObserver);
- }
-
- /** Unregister the observer if it is already registered. */
- private void maybeUnregisterObserverProxy() {
- if (mObserver != null) {
- mCursor.unregisterContentObserver(mObserver);
- mObserver.unlinkToDeath(this);
- mObserver = null;
- }
- }
-
- public boolean updateRows(Map<? extends Long, ? extends Map<String, Object>> values) {
- if (mReadOnly) {
- Log.w("ContentProvider", "Permission Denial: modifying "
- + mProviderName
- + " from pid=" + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return false;
- }
- return mCursor.commitUpdates(values);
- }
-
- public boolean deleteRow(int position) {
- if (mReadOnly) {
- Log.w("ContentProvider", "Permission Denial: modifying "
- + mProviderName
- + " from pid=" + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return false;
- }
- if (mCursor.moveToPosition(position) == false) {
- return false;
- }
- return mCursor.deleteRow();
- }
-
- public Bundle getExtras() {
- return mCursor.getExtras();
- }
-
- public Bundle respond(Bundle extras) {
- return mCursor.respond(extras);
- }
-}
diff --git a/core/java/android/database/CursorWindow.java b/core/java/android/database/CursorWindow.java
deleted file mode 100644
index 8e26730..0000000
--- a/core/java/android/database/CursorWindow.java
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- * 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database;
-
-import android.database.sqlite.SQLiteClosable;
-import android.os.IBinder;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * A buffer containing multiple cursor rows.
- */
-public class CursorWindow extends SQLiteClosable implements Parcelable {
- /** The pointer to the native window class */
- @SuppressWarnings("unused")
- private int nWindow;
-
- private int mStartPos;
-
- /**
- * Creates a new empty window.
- *
- * @param localWindow true if this window will be used in this process only
- */
- public CursorWindow(boolean localWindow) {
- mStartPos = 0;
- native_init(localWindow);
- }
-
- /**
- * Returns the starting position of this window within the entire
- * Cursor's result set.
- *
- * @return the starting position of this window within the entire
- * Cursor's result set.
- */
- public int getStartPosition() {
- return mStartPos;
- }
-
- /**
- * Set the start position of cursor window
- * @param pos
- */
- public void setStartPosition(int pos) {
- mStartPos = pos;
- }
-
- /**
- * Returns the number of rows in this window.
- *
- * @return the number of rows in this window.
- */
- public int getNumRows() {
- acquireReference();
- try {
- return getNumRows_native();
- } finally {
- releaseReference();
- }
- }
-
- private native int getNumRows_native();
- /**
- * Set number of Columns
- * @param columnNum
- * @return true if success
- */
- public boolean setNumColumns(int columnNum) {
- acquireReference();
- try {
- return setNumColumns_native(columnNum);
- } finally {
- releaseReference();
- }
- }
-
- private native boolean setNumColumns_native(int columnNum);
-
- /**
- * Allocate a row in cursor window
- * @return false if cursor window is out of memory
- */
- public boolean allocRow(){
- acquireReference();
- try {
- return allocRow_native();
- } finally {
- releaseReference();
- }
- }
-
- private native boolean allocRow_native();
-
- /**
- * Free the last row
- */
- public void freeLastRow(){
- acquireReference();
- try {
- freeLastRow_native();
- } finally {
- releaseReference();
- }
- }
-
- private native void freeLastRow_native();
-
- /**
- * copy byte array to cursor window
- * @param value
- * @param row
- * @param col
- * @return false if fail to copy
- */
- public boolean putBlob(byte[] value, int row, int col) {
- acquireReference();
- try {
- return putBlob_native(value, row - mStartPos, col);
- } finally {
- releaseReference();
- }
- }
-
- private native boolean putBlob_native(byte[] value, int row, int col);
-
- /**
- * Copy String to cursor window
- * @param value
- * @param row
- * @param col
- * @return false if fail to copy
- */
- public boolean putString(String value, int row, int col) {
- acquireReference();
- try {
- return putString_native(value, row - mStartPos, col);
- } finally {
- releaseReference();
- }
- }
-
- private native boolean putString_native(String value, int row, int col);
-
- /**
- * Copy integer to cursor window
- * @param value
- * @param row
- * @param col
- * @return false if fail to copy
- */
- public boolean putLong(long value, int row, int col) {
- acquireReference();
- try {
- return putLong_native(value, row - mStartPos, col);
- } finally {
- releaseReference();
- }
- }
-
- private native boolean putLong_native(long value, int row, int col);
-
-
- /**
- * Copy double to cursor window
- * @param value
- * @param row
- * @param col
- * @return false if fail to copy
- */
- public boolean putDouble(double value, int row, int col) {
- acquireReference();
- try {
- return putDouble_native(value, row - mStartPos, col);
- } finally {
- releaseReference();
- }
- }
-
- private native boolean putDouble_native(double value, int row, int col);
-
- /**
- * Set the [row, col] value to NULL
- * @param row
- * @param col
- * @return false if fail to copy
- */
- public boolean putNull(int row, int col) {
- acquireReference();
- try {
- return putNull_native(row - mStartPos, col);
- } finally {
- releaseReference();
- }
- }
-
- private native boolean putNull_native(int row, int col);
-
-
- /**
- * Returns {@code true} if given field is {@code 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}
- */
- public boolean isNull(int row, int col) {
- acquireReference();
- try {
- return isNull_native(row - mStartPos, col);
- } finally {
- releaseReference();
- }
- }
-
- private native boolean isNull_native(int row, int col);
-
- /**
- * Returns a byte array for the given field.
- *
- * @param row the row to read from, row - getStartPosition() being the actual row in the window
- * @param col the column to read from
- * @return a String value for the given field
- */
- public byte[] getBlob(int row, int col) {
- acquireReference();
- try {
- return getBlob_native(row - mStartPos, col);
- } finally {
- releaseReference();
- }
- }
-
- private native byte[] getBlob_native(int row, int col);
-
- /**
- * 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
- */
- public boolean isBlob(int row, int col) {
- acquireReference();
- try {
- return isBlob_native(row - mStartPos, col);
- } finally {
- releaseReference();
- }
- }
-
- private native boolean isBlob_native(int row, int col);
-
- /**
- * Returns a String for the given field.
- *
- * @param row the row to read from, row - getStartPosition() being the actual row in the window
- * @param col the column to read from
- * @return a String value for the given field
- */
- public String getString(int row, int col) {
- acquireReference();
- try {
- return getString_native(row - mStartPos, col);
- } finally {
- releaseReference();
- }
- }
-
- private native String getString_native(int row, int col);
-
- /**
- * copy the text for the given field in the provided char array.
- *
- * @param row the row to read from, row - getStartPosition() being the actual row in the window
- * @param col the column to read from
- * @param buffer the CharArrayBuffer to copy the text into,
- * If the requested string is larger than the buffer
- * a new char buffer will be created to hold the string. and assigne to
- * CharArrayBuffer.data
- */
- public void copyStringToBuffer(int row, int col, CharArrayBuffer buffer) {
- if (buffer == null) {
- throw new IllegalArgumentException("CharArrayBuffer should not be null");
- }
- if (buffer.data == null) {
- buffer.data = new char[64];
- }
- acquireReference();
- try {
- char[] newbuf = copyStringToBuffer_native(
- row - mStartPos, col, buffer.data.length, buffer);
- if (newbuf != null) {
- buffer.data = newbuf;
- }
- } finally {
- releaseReference();
- }
- }
-
- private native char[] copyStringToBuffer_native(
- int row, int col, int bufferSize, CharArrayBuffer buffer);
-
- /**
- * Returns a long for the given field.
- * row is 0 based
- *
- * @param row the row to read from, row - getStartPosition() being the actual row in the window
- * @param col the column to read from
- * @return a long value for the given field
- */
- public long getLong(int row, int col) {
- acquireReference();
- try {
- return getLong_native(row - mStartPos, col);
- } finally {
- releaseReference();
- }
- }
-
- private native long getLong_native(int row, int col);
-
- /**
- * Returns a double for the given field.
- * row is 0 based
- *
- * @param row the row to read from, row - getStartPosition() being the actual row in the window
- * @param col the column to read from
- * @return a double value for the given field
- */
- public double getDouble(int row, int col) {
- acquireReference();
- try {
- return getDouble_native(row - mStartPos, col);
- } finally {
- releaseReference();
- }
- }
-
- private native double getDouble_native(int row, int col);
-
- /**
- * Returns a short for the given field.
- * row is 0 based
- *
- * @param row the row to read from, row - getStartPosition() being the actual row in the window
- * @param col the column to read from
- * @return a short value for the given field
- */
- public short getShort(int row, int col) {
- acquireReference();
- try {
- return (short) getLong_native(row - mStartPos, col);
- } finally {
- releaseReference();
- }
- }
-
- /**
- * Returns an int for the given field.
- *
- * @param row the row to read from, row - getStartPosition() being the actual row in the window
- * @param col the column to read from
- * @return an int value for the given field
- */
- public int getInt(int row, int col) {
- acquireReference();
- try {
- return (int) getLong_native(row - mStartPos, col);
- } finally {
- releaseReference();
- }
- }
-
- /**
- * Returns a float for the given field.
- * row is 0 based
- *
- * @param row the row to read from, row - getStartPosition() being the actual row in the window
- * @param col the column to read from
- * @return a float value for the given field
- */
- public float getFloat(int row, int col) {
- acquireReference();
- try {
- return (float) getDouble_native(row - mStartPos, col);
- } finally {
- releaseReference();
- }
- }
-
- /**
- * Clears out the existing contents of the window, making it safe to reuse
- * for new data. Note that the number of columns in the window may NOT
- * change across a call to clear().
- */
- public void clear() {
- acquireReference();
- try {
- mStartPos = 0;
- native_clear();
- } finally {
- releaseReference();
- }
- }
-
- /** Clears out the native side of things */
- private native void native_clear();
-
- /**
- * Cleans up the native resources associated with the window.
- */
- public void close() {
- releaseReference();
- }
-
- private native void close_native();
-
- @Override
- protected void finalize() {
- // Just in case someone forgot to call close...
- close_native();
- }
-
- public static final Parcelable.Creator<CursorWindow> CREATOR
- = new Parcelable.Creator<CursorWindow>() {
- public CursorWindow createFromParcel(Parcel source) {
- return new CursorWindow(source);
- }
-
- public CursorWindow[] newArray(int size) {
- return new CursorWindow[size];
- }
- };
-
- public static CursorWindow newFromParcel(Parcel p) {
- return CREATOR.createFromParcel(p);
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeStrongBinder(native_getBinder());
- dest.writeInt(mStartPos);
- }
-
- private CursorWindow(Parcel source) {
- IBinder nativeBinder = source.readStrongBinder();
- mStartPos = source.readInt();
-
- native_init(nativeBinder);
- }
-
- /** Get the binder for the native side of the window */
- private native IBinder native_getBinder();
-
- /** Does the native side initialization for an empty window */
- private native void native_init(boolean localOnly);
-
- /** Does the native side initialization with an existing binder from another process */
- private native void native_init(IBinder nativeBinder);
-
- @Override
- protected void onAllReferencesReleased() {
- close_native();
- }
-}
diff --git a/core/java/android/database/CursorWrapper.java b/core/java/android/database/CursorWrapper.java
deleted file mode 100644
index f0aa7d7..0000000
--- a/core/java/android/database/CursorWrapper.java
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database;
-
-import android.content.ContentResolver;
-import android.database.CharArrayBuffer;
-import android.net.Uri;
-import android.os.Bundle;
-
-import java.util.Map;
-
-/**
- * Wrapper class for Cursor that delegates all calls to the actual cursor object
- */
-
-public class CursorWrapper implements Cursor {
-
- public CursorWrapper(Cursor cursor) {
- mCursor = cursor;
- }
-
- /**
- * @hide
- * @deprecated
- */
- public void abortUpdates() {
- mCursor.abortUpdates();
- }
-
- public void close() {
- mCursor.close();
- }
-
- public boolean isClosed() {
- return mCursor.isClosed();
- }
-
- /**
- * @hide
- * @deprecated
- */
- public boolean commitUpdates() {
- return mCursor.commitUpdates();
- }
-
- /**
- * @hide
- * @deprecated
- */
- public boolean commitUpdates(
- Map<? extends Long, ? extends Map<String, Object>> values) {
- return mCursor.commitUpdates(values);
- }
-
- public int getCount() {
- return mCursor.getCount();
- }
-
- public void deactivate() {
- mCursor.deactivate();
- }
-
- /**
- * @hide
- * @deprecated
- */
- public boolean deleteRow() {
- return mCursor.deleteRow();
- }
-
- public boolean moveToFirst() {
- return mCursor.moveToFirst();
- }
-
- public int getColumnCount() {
- return mCursor.getColumnCount();
- }
-
- public int getColumnIndex(String columnName) {
- return mCursor.getColumnIndex(columnName);
- }
-
- public int getColumnIndexOrThrow(String columnName)
- throws IllegalArgumentException {
- return mCursor.getColumnIndexOrThrow(columnName);
- }
-
- public String getColumnName(int columnIndex) {
- return mCursor.getColumnName(columnIndex);
- }
-
- public String[] getColumnNames() {
- return mCursor.getColumnNames();
- }
-
- public double getDouble(int columnIndex) {
- return mCursor.getDouble(columnIndex);
- }
-
- public Bundle getExtras() {
- return mCursor.getExtras();
- }
-
- public float getFloat(int columnIndex) {
- return mCursor.getFloat(columnIndex);
- }
-
- public int getInt(int columnIndex) {
- return mCursor.getInt(columnIndex);
- }
-
- public long getLong(int columnIndex) {
- return mCursor.getLong(columnIndex);
- }
-
- public short getShort(int columnIndex) {
- return mCursor.getShort(columnIndex);
- }
-
- public String getString(int columnIndex) {
- return mCursor.getString(columnIndex);
- }
-
- public void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer) {
- mCursor.copyStringToBuffer(columnIndex, buffer);
- }
-
- public byte[] getBlob(int columnIndex) {
- return mCursor.getBlob(columnIndex);
- }
-
- public boolean getWantsAllOnMoveCalls() {
- return mCursor.getWantsAllOnMoveCalls();
- }
-
- /**
- * @hide
- * @deprecated
- */
- public boolean hasUpdates() {
- return mCursor.hasUpdates();
- }
-
- public boolean isAfterLast() {
- return mCursor.isAfterLast();
- }
-
- public boolean isBeforeFirst() {
- return mCursor.isBeforeFirst();
- }
-
- public boolean isFirst() {
- return mCursor.isFirst();
- }
-
- public boolean isLast() {
- return mCursor.isLast();
- }
-
- public boolean isNull(int columnIndex) {
- return mCursor.isNull(columnIndex);
- }
-
- public boolean moveToLast() {
- return mCursor.moveToLast();
- }
-
- public boolean move(int offset) {
- return mCursor.move(offset);
- }
-
- public boolean moveToPosition(int position) {
- return mCursor.moveToPosition(position);
- }
-
- public boolean moveToNext() {
- return mCursor.moveToNext();
- }
-
- public int getPosition() {
- return mCursor.getPosition();
- }
-
- public boolean moveToPrevious() {
- return mCursor.moveToPrevious();
- }
-
- public void registerContentObserver(ContentObserver observer) {
- mCursor.registerContentObserver(observer);
- }
-
- public void registerDataSetObserver(DataSetObserver observer) {
- mCursor.registerDataSetObserver(observer);
- }
-
- public boolean requery() {
- return mCursor.requery();
- }
-
- public Bundle respond(Bundle extras) {
- return mCursor.respond(extras);
- }
-
- public void setNotificationUri(ContentResolver cr, Uri uri) {
- mCursor.setNotificationUri(cr, uri);
- }
-
- /**
- * @hide
- * @deprecated
- */
- public boolean supportsUpdates() {
- return mCursor.supportsUpdates();
- }
-
- public void unregisterContentObserver(ContentObserver observer) {
- mCursor.unregisterContentObserver(observer);
- }
-
- public void unregisterDataSetObserver(DataSetObserver observer) {
- mCursor.unregisterDataSetObserver(observer);
- }
-
- /**
- * @hide
- * @deprecated
- */
- public boolean updateDouble(int columnIndex, double value) {
- return mCursor.updateDouble(columnIndex, value);
- }
-
- /**
- * @hide
- * @deprecated
- */
- public boolean updateFloat(int columnIndex, float value) {
- return mCursor.updateFloat(columnIndex, value);
- }
-
- /**
- * @hide
- * @deprecated
- */
- public boolean updateInt(int columnIndex, int value) {
- return mCursor.updateInt(columnIndex, value);
- }
-
- /**
- * @hide
- * @deprecated
- */
- public boolean updateLong(int columnIndex, long value) {
- return mCursor.updateLong(columnIndex, value);
- }
-
- /**
- * @hide
- * @deprecated
- */
- public boolean updateShort(int columnIndex, short value) {
- return mCursor.updateShort(columnIndex, value);
- }
-
- /**
- * @hide
- * @deprecated
- */
- public boolean updateString(int columnIndex, String value) {
- return mCursor.updateString(columnIndex, value);
- }
-
- /**
- * @hide
- * @deprecated
- */
- public boolean updateBlob(int columnIndex, byte[] value) {
- return mCursor.updateBlob(columnIndex, value);
- }
-
- /**
- * @hide
- * @deprecated
- */
- public boolean updateToNull(int columnIndex) {
- return mCursor.updateToNull(columnIndex);
- }
-
- private Cursor mCursor;
-
-}
-
diff --git a/core/java/android/database/DataSetObservable.java b/core/java/android/database/DataSetObservable.java
deleted file mode 100644
index 9200e81..0000000
--- a/core/java/android/database/DataSetObservable.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2007 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database;
-
-/**
- * A specialization of Observable for DataSetObserver that provides methods for
- * invoking the various callback methods of DataSetObserver.
- */
-public class DataSetObservable extends Observable<DataSetObserver> {
- /**
- * Invokes onChanged on each observer. Called when the data set being observed has
- * changed, and which when read contains the new state of the data.
- */
- public void notifyChanged() {
- synchronized(mObservers) {
- for (DataSetObserver observer : mObservers) {
- observer.onChanged();
- }
- }
- }
-
- /**
- * Invokes onInvalidated on each observer. Called when the data set being monitored
- * has changed such that it is no longer valid.
- */
- public void notifyInvalidated() {
- synchronized (mObservers) {
- for (DataSetObserver observer : mObservers) {
- observer.onInvalidated();
- }
- }
- }
-}
diff --git a/core/java/android/database/DataSetObserver.java b/core/java/android/database/DataSetObserver.java
deleted file mode 100644
index 28616c8..0000000
--- a/core/java/android/database/DataSetObserver.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2007 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database;
-
-/**
- * Receives call backs when a data set has been changed, or made invalid. The typically data sets
- * that are observed are {@link Cursor}s or {@link android.widget.Adapter}s.
- * DataSetObserver must be implemented by objects which are added to a DataSetObservable.
- */
-public abstract class DataSetObserver {
- /**
- * This method is called when the entire data set has changed,
- * most likely through a call to {@link Cursor#requery()} on a {@link Cursor}.
- */
- public void onChanged() {
- // Do nothing
- }
-
- /**
- * This method is called when the entire data becomes invalid,
- * most likely through a call to {@link Cursor#deactivate()} or {@link Cursor#close()} on a
- * {@link Cursor}.
- */
- public void onInvalidated() {
- // Do nothing
- }
-}
diff --git a/core/java/android/database/DatabaseUtils.java b/core/java/android/database/DatabaseUtils.java
deleted file mode 100644
index 10f3806..0000000
--- a/core/java/android/database/DatabaseUtils.java
+++ /dev/null
@@ -1,1018 +0,0 @@
-/*
- * 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database;
-
-import org.apache.commons.codec.binary.Hex;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.sqlite.SQLiteAbortException;
-import android.database.sqlite.SQLiteConstraintException;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteDatabaseCorruptException;
-import android.database.sqlite.SQLiteDiskIOException;
-import android.database.sqlite.SQLiteException;
-import android.database.sqlite.SQLiteFullException;
-import android.database.sqlite.SQLiteProgram;
-import android.database.sqlite.SQLiteStatement;
-import android.os.Parcel;
-import android.text.TextUtils;
-import android.util.Config;
-import android.util.Log;
-
-import java.io.FileNotFoundException;
-import java.io.PrintStream;
-import java.text.Collator;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Static utility methods for dealing with databases and {@link Cursor}s.
- */
-public class DatabaseUtils {
- private static final String TAG = "DatabaseUtils";
-
- private static final boolean DEBUG = false;
- private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV;
-
- private static final String[] countProjection = new String[]{"count(*)"};
-
- /**
- * Special function for writing an exception result at the header of
- * a parcel, to be used when returning an exception from a transaction.
- * exception will be re-thrown by the function in another process
- * @param reply Parcel to write to
- * @param e The Exception to be written.
- * @see Parcel#writeNoException
- * @see Parcel#writeException
- */
- public static final void writeExceptionToParcel(Parcel reply, Exception e) {
- int code = 0;
- boolean logException = true;
- if (e instanceof FileNotFoundException) {
- code = 1;
- logException = false;
- } else if (e instanceof IllegalArgumentException) {
- code = 2;
- } else if (e instanceof UnsupportedOperationException) {
- code = 3;
- } else if (e instanceof SQLiteAbortException) {
- code = 4;
- } else if (e instanceof SQLiteConstraintException) {
- code = 5;
- } else if (e instanceof SQLiteDatabaseCorruptException) {
- code = 6;
- } else if (e instanceof SQLiteFullException) {
- code = 7;
- } else if (e instanceof SQLiteDiskIOException) {
- code = 8;
- } else if (e instanceof SQLiteException) {
- code = 9;
- } else {
- reply.writeException(e);
- Log.e(TAG, "Writing exception to parcel", e);
- return;
- }
- reply.writeInt(code);
- reply.writeString(e.getMessage());
-
- if (logException) {
- Log.e(TAG, "Writing exception to parcel", e);
- }
- }
-
- /**
- * Special function for reading an exception result from the header of
- * a parcel, to be used after receiving the result of a transaction. This
- * will throw the exception for you if it had been written to the Parcel,
- * otherwise return and let you read the normal result data from the Parcel.
- * @param reply Parcel to read from
- * @see Parcel#writeNoException
- * @see Parcel#readException
- */
- public static final void readExceptionFromParcel(Parcel reply) {
- int code = reply.readInt();
- if (code == 0) return;
- String msg = reply.readString();
- DatabaseUtils.readExceptionFromParcel(reply, msg, code);
- }
-
- public static void readExceptionWithFileNotFoundExceptionFromParcel(
- Parcel reply) throws FileNotFoundException {
- int code = reply.readInt();
- if (code == 0) return;
- String msg = reply.readString();
- if (code == 1) {
- throw new FileNotFoundException(msg);
- } else {
- DatabaseUtils.readExceptionFromParcel(reply, msg, code);
- }
- }
-
- private static final void readExceptionFromParcel(Parcel reply, String msg, int code) {
- switch (code) {
- case 2:
- throw new IllegalArgumentException(msg);
- case 3:
- throw new UnsupportedOperationException(msg);
- case 4:
- throw new SQLiteAbortException(msg);
- case 5:
- throw new SQLiteConstraintException(msg);
- case 6:
- throw new SQLiteDatabaseCorruptException(msg);
- case 7:
- throw new SQLiteFullException(msg);
- case 8:
- throw new SQLiteDiskIOException(msg);
- case 9:
- throw new SQLiteException(msg);
- default:
- reply.readException(code, msg);
- }
- }
-
- /**
- * Binds the given Object to the given SQLiteProgram using the proper
- * typing. For example, bind numbers as longs/doubles, and everything else
- * as a string by call toString() on it.
- *
- * @param prog the program to bind the object to
- * @param index the 1-based index to bind at
- * @param value the value to bind
- */
- public static void bindObjectToProgram(SQLiteProgram prog, int index,
- Object value) {
- if (value == null) {
- prog.bindNull(index);
- } else if (value instanceof Double || value instanceof Float) {
- prog.bindDouble(index, ((Number)value).doubleValue());
- } else if (value instanceof Number) {
- prog.bindLong(index, ((Number)value).longValue());
- } else if (value instanceof Boolean) {
- Boolean bool = (Boolean)value;
- if (bool) {
- prog.bindLong(index, 1);
- } else {
- prog.bindLong(index, 0);
- }
- } else if (value instanceof byte[]){
- prog.bindBlob(index, (byte[]) value);
- } else {
- prog.bindString(index, value.toString());
- }
- }
-
- /**
- * Appends an SQL string to the given StringBuilder, including the opening
- * and closing single quotes. Any single quotes internal to sqlString will
- * be escaped.
- *
- * This method is deprecated because we want to encourage everyone
- * to use the "?" binding form. However, when implementing a
- * ContentProvider, one may want to add WHERE clauses that were
- * not provided by the caller. Since "?" is a positional form,
- * using it in this case could break the caller because the
- * indexes would be shifted to accomodate the ContentProvider's
- * internal bindings. In that case, it may be necessary to
- * construct a WHERE clause manually. This method is useful for
- * those cases.
- *
- * @param sb the StringBuilder that the SQL string will be appended to
- * @param sqlString the raw string to be appended, which may contain single
- * quotes
- */
- public static void appendEscapedSQLString(StringBuilder sb, String sqlString) {
- sb.append('\'');
- if (sqlString.indexOf('\'') != -1) {
- int length = sqlString.length();
- for (int i = 0; i < length; i++) {
- char c = sqlString.charAt(i);
- if (c == '\'') {
- sb.append('\'');
- }
- sb.append(c);
- }
- } else
- sb.append(sqlString);
- sb.append('\'');
- }
-
- /**
- * SQL-escape a string.
- */
- public static String sqlEscapeString(String value) {
- StringBuilder escaper = new StringBuilder();
-
- DatabaseUtils.appendEscapedSQLString(escaper, value);
-
- return escaper.toString();
- }
-
- /**
- * Appends an Object to an SQL string with the proper escaping, etc.
- */
- public static final void appendValueToSql(StringBuilder sql, Object value) {
- if (value == null) {
- sql.append("NULL");
- } else if (value instanceof Boolean) {
- Boolean bool = (Boolean)value;
- if (bool) {
- sql.append('1');
- } else {
- sql.append('0');
- }
- } else {
- appendEscapedSQLString(sql, value.toString());
- }
- }
-
- /**
- * Concatenates two SQL WHERE clauses, handling empty or null values.
- * @hide
- */
- public static String concatenateWhere(String a, String b) {
- if (TextUtils.isEmpty(a)) {
- return b;
- }
- if (TextUtils.isEmpty(b)) {
- return a;
- }
-
- return "(" + a + ") AND (" + b + ")";
- }
-
- /**
- * return the collation key
- * @param name
- * @return the collation key
- */
- public static String getCollationKey(String name) {
- byte [] arr = getCollationKeyInBytes(name);
- try {
- return new String(arr, 0, getKeyLen(arr), "ISO8859_1");
- } catch (Exception ex) {
- return "";
- }
- }
-
- /**
- * return the collation key in hex format
- * @param name
- * @return the collation key in hex format
- */
- public static String getHexCollationKey(String name) {
- byte [] arr = getCollationKeyInBytes(name);
- char[] keys = Hex.encodeHex(arr);
- return new String(keys, 0, getKeyLen(arr) * 2);
- }
-
- private static int getKeyLen(byte[] arr) {
- if (arr[arr.length - 1] != 0) {
- return arr.length;
- } else {
- // remove zero "termination"
- return arr.length-1;
- }
- }
-
- private static byte[] getCollationKeyInBytes(String name) {
- if (mColl == null) {
- mColl = Collator.getInstance();
- mColl.setStrength(Collator.PRIMARY);
- }
- return mColl.getCollationKey(name).toByteArray();
- }
-
- private static Collator mColl = null;
- /**
- * Prints the contents of a Cursor to System.out. The position is restored
- * after printing.
- *
- * @param cursor the cursor to print
- */
- public static void dumpCursor(Cursor cursor) {
- dumpCursor(cursor, System.out);
- }
-
- /**
- * Prints the contents of a Cursor to a PrintSteam. The position is restored
- * after printing.
- *
- * @param cursor the cursor to print
- * @param stream the stream to print to
- */
- public static void dumpCursor(Cursor cursor, PrintStream stream) {
- stream.println(">>>>> Dumping cursor " + cursor);
- if (cursor != null) {
- int startPos = cursor.getPosition();
-
- cursor.moveToPosition(-1);
- while (cursor.moveToNext()) {
- dumpCurrentRow(cursor, stream);
- }
- cursor.moveToPosition(startPos);
- }
- stream.println("<<<<<");
- }
-
- /**
- * Prints the contents of a Cursor to a StringBuilder. The position
- * is restored after printing.
- *
- * @param cursor the cursor to print
- * @param sb the StringBuilder to print to
- */
- public static void dumpCursor(Cursor cursor, StringBuilder sb) {
- sb.append(">>>>> Dumping cursor " + cursor + "\n");
- if (cursor != null) {
- int startPos = cursor.getPosition();
-
- cursor.moveToPosition(-1);
- while (cursor.moveToNext()) {
- dumpCurrentRow(cursor, sb);
- }
- cursor.moveToPosition(startPos);
- }
- sb.append("<<<<<\n");
- }
-
- /**
- * Prints the contents of a Cursor to a String. The position is restored
- * after printing.
- *
- * @param cursor the cursor to print
- * @return a String that contains the dumped cursor
- */
- public static String dumpCursorToString(Cursor cursor) {
- StringBuilder sb = new StringBuilder();
- dumpCursor(cursor, sb);
- return sb.toString();
- }
-
- /**
- * Prints the contents of a Cursor's current row to System.out.
- *
- * @param cursor the cursor to print from
- */
- public static void dumpCurrentRow(Cursor cursor) {
- dumpCurrentRow(cursor, System.out);
- }
-
- /**
- * Prints the contents of a Cursor's current row to a PrintSteam.
- *
- * @param cursor the cursor to print
- * @param stream the stream to print to
- */
- public static void dumpCurrentRow(Cursor cursor, PrintStream stream) {
- String[] cols = cursor.getColumnNames();
- stream.println("" + cursor.getPosition() + " {");
- int length = cols.length;
- for (int i = 0; i< length; i++) {
- String value;
- try {
- value = cursor.getString(i);
- } catch (SQLiteException e) {
- // assume that if the getString threw this exception then the column is not
- // representable by a string, e.g. it is a BLOB.
- value = "<unprintable>";
- }
- stream.println(" " + cols[i] + '=' + value);
- }
- stream.println("}");
- }
-
- /**
- * Prints the contents of a Cursor's current row to a StringBuilder.
- *
- * @param cursor the cursor to print
- * @param sb the StringBuilder to print to
- */
- public static void dumpCurrentRow(Cursor cursor, StringBuilder sb) {
- String[] cols = cursor.getColumnNames();
- sb.append("" + cursor.getPosition() + " {\n");
- int length = cols.length;
- for (int i = 0; i < length; i++) {
- String value;
- try {
- value = cursor.getString(i);
- } catch (SQLiteException e) {
- // assume that if the getString threw this exception then the column is not
- // representable by a string, e.g. it is a BLOB.
- value = "<unprintable>";
- }
- sb.append(" " + cols[i] + '=' + value + "\n");
- }
- sb.append("}\n");
- }
-
- /**
- * Dump the contents of a Cursor's current row to a String.
- *
- * @param cursor the cursor to print
- * @return a String that contains the dumped cursor row
- */
- public static String dumpCurrentRowToString(Cursor cursor) {
- StringBuilder sb = new StringBuilder();
- dumpCurrentRow(cursor, sb);
- return sb.toString();
- }
-
- /**
- * Reads a String out of a field in a Cursor and writes it to a Map.
- *
- * @param cursor The cursor to read from
- * @param field The TEXT field to read
- * @param values The {@link ContentValues} to put the value into, with the field as the key
- */
- public static void cursorStringToContentValues(Cursor cursor, String field,
- ContentValues values) {
- cursorStringToContentValues(cursor, field, values, field);
- }
-
- /**
- * Reads a String out of a field in a Cursor and writes it to an InsertHelper.
- *
- * @param cursor The cursor to read from
- * @param field The TEXT field to read
- * @param inserter The InsertHelper to bind into
- * @param index the index of the bind entry in the InsertHelper
- */
- public static void cursorStringToInsertHelper(Cursor cursor, String field,
- InsertHelper inserter, int index) {
- inserter.bind(index, cursor.getString(cursor.getColumnIndexOrThrow(field)));
- }
-
- /**
- * Reads a String out of a field in a Cursor and writes it to a Map.
- *
- * @param cursor The cursor to read from
- * @param field The TEXT field to read
- * @param values The {@link ContentValues} to put the value into, with the field as the key
- * @param key The key to store the value with in the map
- */
- public static void cursorStringToContentValues(Cursor cursor, String field,
- ContentValues values, String key) {
- values.put(key, cursor.getString(cursor.getColumnIndexOrThrow(field)));
- }
-
- /**
- * Reads an Integer out of a field in a Cursor and writes it to a Map.
- *
- * @param cursor The cursor to read from
- * @param field The INTEGER field to read
- * @param values The {@link ContentValues} to put the value into, with the field as the key
- */
- public static void cursorIntToContentValues(Cursor cursor, String field, ContentValues values) {
- cursorIntToContentValues(cursor, field, values, field);
- }
-
- /**
- * Reads a Integer out of a field in a Cursor and writes it to a Map.
- *
- * @param cursor The cursor to read from
- * @param field The INTEGER field to read
- * @param values The {@link ContentValues} to put the value into, with the field as the key
- * @param key The key to store the value with in the map
- */
- public static void cursorIntToContentValues(Cursor cursor, String field, ContentValues values,
- String key) {
- int colIndex = cursor.getColumnIndex(field);
- if (!cursor.isNull(colIndex)) {
- values.put(key, cursor.getInt(colIndex));
- } else {
- values.put(key, (Integer) null);
- }
- }
-
- /**
- * Reads a Long out of a field in a Cursor and writes it to a Map.
- *
- * @param cursor The cursor to read from
- * @param field The INTEGER field to read
- * @param values The {@link ContentValues} to put the value into, with the field as the key
- */
- public static void cursorLongToContentValues(Cursor cursor, String field, ContentValues values)
- {
- cursorLongToContentValues(cursor, field, values, field);
- }
-
- /**
- * Reads a Long out of a field in a Cursor and writes it to a Map.
- *
- * @param cursor The cursor to read from
- * @param field The INTEGER field to read
- * @param values The {@link ContentValues} to put the value into
- * @param key The key to store the value with in the map
- */
- public static void cursorLongToContentValues(Cursor cursor, String field, ContentValues values,
- String key) {
- int colIndex = cursor.getColumnIndex(field);
- if (!cursor.isNull(colIndex)) {
- Long value = Long.valueOf(cursor.getLong(colIndex));
- values.put(key, value);
- } else {
- values.put(key, (Long) null);
- }
- }
-
- /**
- * Reads a Double out of a field in a Cursor and writes it to a Map.
- *
- * @param cursor The cursor to read from
- * @param field The REAL field to read
- * @param values The {@link ContentValues} to put the value into
- */
- public static void cursorDoubleToCursorValues(Cursor cursor, String field, ContentValues values)
- {
- cursorDoubleToContentValues(cursor, field, values, field);
- }
-
- /**
- * Reads a Double out of a field in a Cursor and writes it to a Map.
- *
- * @param cursor The cursor to read from
- * @param field The REAL field to read
- * @param values The {@link ContentValues} to put the value into
- * @param key The key to store the value with in the map
- */
- public static void cursorDoubleToContentValues(Cursor cursor, String field,
- ContentValues values, String key) {
- int colIndex = cursor.getColumnIndex(field);
- if (!cursor.isNull(colIndex)) {
- values.put(key, cursor.getDouble(colIndex));
- } else {
- values.put(key, (Double) null);
- }
- }
-
- /**
- * Read the entire contents of a cursor row and store them in a ContentValues.
- *
- * @param cursor the cursor to read from.
- * @param values the {@link ContentValues} to put the row into.
- */
- public static void cursorRowToContentValues(Cursor cursor, ContentValues values) {
- AbstractWindowedCursor awc =
- (cursor instanceof AbstractWindowedCursor) ? (AbstractWindowedCursor) cursor : null;
-
- String[] columns = cursor.getColumnNames();
- int length = columns.length;
- for (int i = 0; i < length; i++) {
- if (awc != null && awc.isBlob(i)) {
- values.put(columns[i], cursor.getBlob(i));
- } else {
- values.put(columns[i], cursor.getString(i));
- }
- }
- }
-
- /**
- * Query the table for the number of rows in the table.
- * @param db the database the table is in
- * @param table the name of the table to query
- * @return the number of rows in the table
- */
- public static long queryNumEntries(SQLiteDatabase db, String table) {
- Cursor cursor = db.query(table, countProjection,
- null, null, null, null, null);
- cursor.moveToFirst();
- long count = cursor.getLong(0);
- cursor.deactivate();
- return count;
- }
-
- /**
- * Utility method to run the query on the db and return the value in the
- * first column of the first row.
- */
- public static long longForQuery(SQLiteDatabase db, String query, String[] selectionArgs) {
- SQLiteStatement prog = db.compileStatement(query);
- try {
- return longForQuery(prog, selectionArgs);
- } finally {
- prog.close();
- }
- }
-
- /**
- * Utility method to run the pre-compiled query and return the value in the
- * first column of the first row.
- */
- public static long longForQuery(SQLiteStatement prog, String[] selectionArgs) {
- if (selectionArgs != null) {
- int size = selectionArgs.length;
- for (int i = 0; i < size; i++) {
- bindObjectToProgram(prog, i + 1, selectionArgs[i]);
- }
- }
- long value = prog.simpleQueryForLong();
- return value;
- }
-
- /**
- * Utility method to run the query on the db and return the value in the
- * first column of the first row.
- */
- public static String stringForQuery(SQLiteDatabase db, String query, String[] selectionArgs) {
- SQLiteStatement prog = db.compileStatement(query);
- try {
- return stringForQuery(prog, selectionArgs);
- } finally {
- prog.close();
- }
- }
-
- /**
- * Utility method to run the pre-compiled query and return the value in the
- * first column of the first row.
- */
- public static String stringForQuery(SQLiteStatement prog, String[] selectionArgs) {
- if (selectionArgs != null) {
- int size = selectionArgs.length;
- for (int i = 0; i < size; i++) {
- bindObjectToProgram(prog, i + 1, selectionArgs[i]);
- }
- }
- String value = prog.simpleQueryForString();
- return value;
- }
-
- /**
- * This class allows users to do multiple inserts into a table but
- * compile the SQL insert statement only once, which may increase
- * performance.
- */
- public static class InsertHelper {
- private final SQLiteDatabase mDb;
- private final String mTableName;
- private HashMap<String, Integer> mColumns;
- private String mInsertSQL = null;
- private SQLiteStatement mInsertStatement = null;
- private SQLiteStatement mReplaceStatement = null;
- private SQLiteStatement mPreparedStatement = null;
-
- /**
- * {@hide}
- *
- * These are the columns returned by sqlite's "PRAGMA
- * table_info(...)" command that we depend on.
- */
- public static final int TABLE_INFO_PRAGMA_COLUMNNAME_INDEX = 1;
- public static final int TABLE_INFO_PRAGMA_DEFAULT_INDEX = 4;
-
- /**
- * @param db the SQLiteDatabase to insert into
- * @param tableName the name of the table to insert into
- */
- public InsertHelper(SQLiteDatabase db, String tableName) {
- mDb = db;
- mTableName = tableName;
- }
-
- private void buildSQL() throws SQLException {
- StringBuilder sb = new StringBuilder(128);
- sb.append("INSERT INTO ");
- sb.append(mTableName);
- sb.append(" (");
-
- StringBuilder sbv = new StringBuilder(128);
- sbv.append("VALUES (");
-
- int i = 1;
- Cursor cur = null;
- try {
- cur = mDb.rawQuery("PRAGMA table_info(" + mTableName + ")", null);
- mColumns = new HashMap<String, Integer>(cur.getCount());
- while (cur.moveToNext()) {
- String columnName = cur.getString(TABLE_INFO_PRAGMA_COLUMNNAME_INDEX);
- String defaultValue = cur.getString(TABLE_INFO_PRAGMA_DEFAULT_INDEX);
-
- mColumns.put(columnName, i);
- sb.append("'");
- sb.append(columnName);
- sb.append("'");
-
- if (defaultValue == null) {
- sbv.append("?");
- } else {
- sbv.append("COALESCE(?, ");
- sbv.append(defaultValue);
- sbv.append(")");
- }
-
- sb.append(i == cur.getCount() ? ") " : ", ");
- sbv.append(i == cur.getCount() ? ");" : ", ");
- ++i;
- }
- } finally {
- if (cur != null) cur.close();
- }
-
- sb.append(sbv);
-
- mInsertSQL = sb.toString();
- if (LOCAL_LOGV) Log.v(TAG, "insert statement is " + mInsertSQL);
- }
-
- private SQLiteStatement getStatement(boolean allowReplace) throws SQLException {
- if (allowReplace) {
- if (mReplaceStatement == null) {
- if (mInsertSQL == null) buildSQL();
- // chop "INSERT" off the front and prepend "INSERT OR REPLACE" instead.
- String replaceSQL = "INSERT OR REPLACE" + mInsertSQL.substring(6);
- mReplaceStatement = mDb.compileStatement(replaceSQL);
- }
- return mReplaceStatement;
- } else {
- if (mInsertStatement == null) {
- if (mInsertSQL == null) buildSQL();
- mInsertStatement = mDb.compileStatement(mInsertSQL);
- }
- return mInsertStatement;
- }
- }
-
- /**
- * Performs an insert, adding a new row with the given values.
- *
- * @param values the set of values with which to populate the
- * new row
- * @param allowReplace if true, the statement does "INSERT OR
- * REPLACE" instead of "INSERT", silently deleting any
- * previously existing rows that would cause a conflict
- *
- * @return the row ID of the newly inserted row, or -1 if an
- * error occurred
- */
- private synchronized long insertInternal(ContentValues values, boolean allowReplace) {
- try {
- SQLiteStatement stmt = getStatement(allowReplace);
- stmt.clearBindings();
- if (LOCAL_LOGV) Log.v(TAG, "--- inserting in table " + mTableName);
- for (Map.Entry<String, Object> e: values.valueSet()) {
- final String key = e.getKey();
- int i = getColumnIndex(key);
- DatabaseUtils.bindObjectToProgram(stmt, i, e.getValue());
- if (LOCAL_LOGV) {
- Log.v(TAG, "binding " + e.getValue() + " to column " +
- i + " (" + key + ")");
- }
- }
- return stmt.executeInsert();
- } catch (SQLException e) {
- Log.e(TAG, "Error inserting " + values + " into table " + mTableName, e);
- return -1;
- }
- }
-
- /**
- * Returns the index of the specified column. This is index is suitagble for use
- * in calls to bind().
- * @param key the column name
- * @return the index of the column
- */
- public int getColumnIndex(String key) {
- getStatement(false);
- final Integer index = mColumns.get(key);
- if (index == null) {
- throw new IllegalArgumentException("column '" + key + "' is invalid");
- }
- return index;
- }
-
- /**
- * Bind the value to an index. A prepareForInsert() or prepareForReplace()
- * without a matching execute() must have already have been called.
- * @param index the index of the slot to which to bind
- * @param value the value to bind
- */
- public void bind(int index, double value) {
- mPreparedStatement.bindDouble(index, value);
- }
-
- /**
- * Bind the value to an index. A prepareForInsert() or prepareForReplace()
- * without a matching execute() must have already have been called.
- * @param index the index of the slot to which to bind
- * @param value the value to bind
- */
- public void bind(int index, float value) {
- mPreparedStatement.bindDouble(index, value);
- }
-
- /**
- * Bind the value to an index. A prepareForInsert() or prepareForReplace()
- * without a matching execute() must have already have been called.
- * @param index the index of the slot to which to bind
- * @param value the value to bind
- */
- public void bind(int index, long value) {
- mPreparedStatement.bindLong(index, value);
- }
-
- /**
- * Bind the value to an index. A prepareForInsert() or prepareForReplace()
- * without a matching execute() must have already have been called.
- * @param index the index of the slot to which to bind
- * @param value the value to bind
- */
- public void bind(int index, int value) {
- mPreparedStatement.bindLong(index, value);
- }
-
- /**
- * Bind the value to an index. A prepareForInsert() or prepareForReplace()
- * without a matching execute() must have already have been called.
- * @param index the index of the slot to which to bind
- * @param value the value to bind
- */
- public void bind(int index, boolean value) {
- mPreparedStatement.bindLong(index, value ? 1 : 0);
- }
-
- /**
- * Bind null to an index. A prepareForInsert() or prepareForReplace()
- * without a matching execute() must have already have been called.
- * @param index the index of the slot to which to bind
- */
- public void bindNull(int index) {
- mPreparedStatement.bindNull(index);
- }
-
- /**
- * Bind the value to an index. A prepareForInsert() or prepareForReplace()
- * without a matching execute() must have already have been called.
- * @param index the index of the slot to which to bind
- * @param value the value to bind
- */
- public void bind(int index, byte[] value) {
- if (value == null) {
- mPreparedStatement.bindNull(index);
- } else {
- mPreparedStatement.bindBlob(index, value);
- }
- }
-
- /**
- * Bind the value to an index. A prepareForInsert() or prepareForReplace()
- * without a matching execute() must have already have been called.
- * @param index the index of the slot to which to bind
- * @param value the value to bind
- */
- public void bind(int index, String value) {
- if (value == null) {
- mPreparedStatement.bindNull(index);
- } else {
- mPreparedStatement.bindString(index, value);
- }
- }
-
- /**
- * Performs an insert, adding a new row with the given values.
- * If the table contains conflicting rows, an error is
- * returned.
- *
- * @param values the set of values with which to populate the
- * new row
- *
- * @return the row ID of the newly inserted row, or -1 if an
- * error occurred
- */
- public long insert(ContentValues values) {
- return insertInternal(values, false);
- }
-
- /**
- * Execute the previously prepared insert or replace using the bound values
- * since the last call to prepareForInsert or prepareForReplace.
- *
- * <p>Note that calling bind() and then execute() is not thread-safe. The only thread-safe
- * way to use this class is to call insert() or replace().
- *
- * @return the row ID of the newly inserted row, or -1 if an
- * error occurred
- */
- public long execute() {
- if (mPreparedStatement == null) {
- throw new IllegalStateException("you must prepare this inserter before calling "
- + "execute");
- }
- try {
- if (LOCAL_LOGV) Log.v(TAG, "--- doing insert or replace in table " + mTableName);
- return mPreparedStatement.executeInsert();
- } catch (SQLException e) {
- Log.e(TAG, "Error executing InsertHelper with table " + mTableName, e);
- return -1;
- } finally {
- // you can only call this once per prepare
- mPreparedStatement = null;
- }
- }
-
- /**
- * Prepare the InsertHelper for an insert. The pattern for this is:
- * <ul>
- * <li>prepareForInsert()
- * <li>bind(index, value);
- * <li>bind(index, value);
- * <li>...
- * <li>bind(index, value);
- * <li>execute();
- * </ul>
- */
- public void prepareForInsert() {
- mPreparedStatement = getStatement(false);
- mPreparedStatement.clearBindings();
- }
-
- /**
- * Prepare the InsertHelper for a replace. The pattern for this is:
- * <ul>
- * <li>prepareForReplace()
- * <li>bind(index, value);
- * <li>bind(index, value);
- * <li>...
- * <li>bind(index, value);
- * <li>execute();
- * </ul>
- */
- public void prepareForReplace() {
- mPreparedStatement = getStatement(true);
- mPreparedStatement.clearBindings();
- }
-
- /**
- * Performs an insert, adding a new row with the given values.
- * If the table contains conflicting rows, they are deleted
- * and replaced with the new row.
- *
- * @param values the set of values with which to populate the
- * new row
- *
- * @return the row ID of the newly inserted row, or -1 if an
- * error occurred
- */
- public long replace(ContentValues values) {
- return insertInternal(values, true);
- }
-
- /**
- * Close this object and release any resources associated with
- * it. The behavior of calling <code>insert()</code> after
- * calling this method is undefined.
- */
- public void close() {
- if (mInsertStatement != null) {
- mInsertStatement.close();
- mInsertStatement = null;
- }
- if (mReplaceStatement != null) {
- mReplaceStatement.close();
- mReplaceStatement = null;
- }
- mInsertSQL = null;
- mColumns = null;
- }
- }
-
- /**
- * Creates a db and populates it with the sql statements in sqlStatements.
- *
- * @param context the context to use to create the db
- * @param dbName the name of the db to create
- * @param dbVersion the version to set on the db
- * @param sqlStatements the statements to use to populate the db. This should be a single string
- * of the form returned by sqlite3's <tt>.dump</tt> command (statements separated by
- * semicolons)
- */
- static public void createDbFromSqlStatements(
- Context context, String dbName, int dbVersion, String sqlStatements) {
- SQLiteDatabase db = context.openOrCreateDatabase(dbName, 0, null);
- // TODO: this is not quite safe since it assumes that all semicolons at the end of a line
- // terminate statements. It is possible that a text field contains ;\n. We will have to fix
- // this if that turns out to be a problem.
- String[] statements = TextUtils.split(sqlStatements, ";\n");
- for (String statement : statements) {
- if (TextUtils.isEmpty(statement)) continue;
- db.execSQL(statement);
- }
- db.setVersion(dbVersion);
- db.close();
- }
-}
diff --git a/core/java/android/database/IBulkCursor.java b/core/java/android/database/IBulkCursor.java
deleted file mode 100644
index 24354fd..0000000
--- a/core/java/android/database/IBulkCursor.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database;
-
-import android.os.RemoteException;
-import android.os.IBinder;
-import android.os.IInterface;
-import android.os.Bundle;
-
-import java.util.Map;
-
-/**
- * This interface provides a low-level way to pass bulk cursor data across
- * both process and language boundries. Application code should use the Cursor
- * interface directly.
- *
- * {@hide}
- */
-public interface IBulkCursor extends IInterface
-{
- /**
- * Returns a BulkCursorWindow, which either has a reference to a shared
- * memory segment with the rows, or an array of JSON strings.
- */
- public CursorWindow getWindow(int startPos) throws RemoteException;
-
- public void onMove(int position) throws RemoteException;
-
- /**
- * Returns the number of rows in the cursor.
- *
- * @return the number of rows in the cursor.
- */
- public int count() throws RemoteException;
-
- /**
- * Returns a string array holding the names of all of the columns in the
- * cursor in the order in which they were listed in the result.
- *
- * @return the names of the columns returned in this query.
- */
- public String[] getColumnNames() throws RemoteException;
-
- public boolean updateRows(Map<? extends Long, ? extends Map<String, Object>> values) throws RemoteException;
-
- public boolean deleteRow(int position) throws RemoteException;
-
- public void deactivate() throws RemoteException;
-
- public void close() throws RemoteException;
-
- public int requery(IContentObserver observer, CursorWindow window) throws RemoteException;
-
- boolean getWantsAllOnMoveCalls() throws RemoteException;
-
- Bundle getExtras() throws RemoteException;
-
- Bundle respond(Bundle extras) throws RemoteException;
-
- /* IPC constants */
- static final String descriptor = "android.content.IBulkCursor";
-
- static final int GET_CURSOR_WINDOW_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION;
- static final int COUNT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 1;
- static final int GET_COLUMN_NAMES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 2;
- static final int UPDATE_ROWS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 3;
- static final int DELETE_ROW_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 4;
- static final int DEACTIVATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 5;
- static final int REQUERY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 6;
- static final int ON_MOVE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 7;
- static final int WANTS_ON_MOVE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 8;
- static final int GET_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 9;
- static final int RESPOND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 10;
- static final int CLOSE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 11;
-}
-
diff --git a/core/java/android/database/IContentObserver.aidl b/core/java/android/database/IContentObserver.aidl
deleted file mode 100755
index ac2f975..0000000
--- a/core/java/android/database/IContentObserver.aidl
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
-**
-** Copyright 2007, 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
-**
-** 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
-** limitations under the License.
-*/
-
-package android.database;
-
-/**
- * @hide
- */
-interface IContentObserver
-{
- /**
- * This method is called when an update occurs to the cursor that is being
- * observed. selfUpdate is true if the update was caused by a call to
- * commit on the cursor that is being observed.
- */
- oneway void onChange(boolean selfUpdate);
-}
diff --git a/core/java/android/database/MatrixCursor.java b/core/java/android/database/MatrixCursor.java
deleted file mode 100644
index cf5a573..0000000
--- a/core/java/android/database/MatrixCursor.java
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (C) 2007 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database;
-
-import java.util.ArrayList;
-
-/**
- * A mutable cursor implementation backed by an array of {@code Object}s. Use
- * {@link #newRow()} to add rows. Automatically expands internal capacity
- * as needed.
- */
-public class MatrixCursor extends AbstractCursor {
-
- private final String[] columnNames;
- private Object[] data;
- private int rowCount = 0;
- private final int columnCount;
-
- /**
- * Constructs a new cursor with the given initial capacity.
- *
- * @param columnNames names of the columns, the ordering of which
- * determines column ordering elsewhere in this cursor
- * @param initialCapacity in rows
- */
- public MatrixCursor(String[] columnNames, int initialCapacity) {
- this.columnNames = columnNames;
- this.columnCount = columnNames.length;
-
- if (initialCapacity < 1) {
- initialCapacity = 1;
- }
-
- this.data = new Object[columnCount * initialCapacity];
- }
-
- /**
- * Constructs a new cursor.
- *
- * @param columnNames names of the columns, the ordering of which
- * determines column ordering elsewhere in this cursor
- */
- public MatrixCursor(String[] columnNames) {
- this(columnNames, 16);
- }
-
- /**
- * Gets value at the given column for the current row.
- */
- private Object get(int column) {
- if (column < 0 || column >= columnCount) {
- throw new CursorIndexOutOfBoundsException("Requested column: "
- + column + ", # of columns: " + columnCount);
- }
- if (mPos < 0) {
- throw new CursorIndexOutOfBoundsException("Before first row.");
- }
- if (mPos >= rowCount) {
- throw new CursorIndexOutOfBoundsException("After last row.");
- }
- return data[mPos * columnCount + column];
- }
-
- /**
- * Adds a new row to the end and returns a builder for that row. Not safe
- * for concurrent use.
- *
- * @return builder which can be used to set the column values for the new
- * row
- */
- public RowBuilder newRow() {
- rowCount++;
- int endIndex = rowCount * columnCount;
- ensureCapacity(endIndex);
- int start = endIndex - columnCount;
- return new RowBuilder(start, endIndex);
- }
-
- /**
- * Adds a new row to the end with the given column values. Not safe
- * for concurrent use.
- *
- * @throws IllegalArgumentException if {@code columnValues.length !=
- * columnNames.length}
- * @param columnValues in the same order as the the column names specified
- * at cursor construction time
- */
- public void addRow(Object[] columnValues) {
- if (columnValues.length != columnCount) {
- throw new IllegalArgumentException("columnNames.length = "
- + columnCount + ", columnValues.length = "
- + columnValues.length);
- }
-
- int start = rowCount++ * columnCount;
- ensureCapacity(start + columnCount);
- System.arraycopy(columnValues, 0, data, start, columnCount);
- }
-
- /**
- * Adds a new row to the end with the given column values. Not safe
- * for concurrent use.
- *
- * @throws IllegalArgumentException if {@code columnValues.size() !=
- * columnNames.length}
- * @param columnValues in the same order as the the column names specified
- * at cursor construction time
- */
- public void addRow(Iterable<?> columnValues) {
- int start = rowCount * columnCount;
- int end = start + columnCount;
- ensureCapacity(end);
-
- if (columnValues instanceof ArrayList<?>) {
- addRow((ArrayList<?>) columnValues, start);
- return;
- }
-
- int current = start;
- Object[] localData = data;
- for (Object columnValue : columnValues) {
- if (current == end) {
- // TODO: null out row?
- throw new IllegalArgumentException(
- "columnValues.size() > columnNames.length");
- }
- localData[current++] = columnValue;
- }
-
- if (current != end) {
- // TODO: null out row?
- throw new IllegalArgumentException(
- "columnValues.size() < columnNames.length");
- }
-
- // Increase row count here in case we encounter an exception.
- rowCount++;
- }
-
- /** Optimization for {@link ArrayList}. */
- private void addRow(ArrayList<?> columnValues, int start) {
- int size = columnValues.size();
- if (size != columnCount) {
- throw new IllegalArgumentException("columnNames.length = "
- + columnCount + ", columnValues.size() = " + size);
- }
-
- rowCount++;
- Object[] localData = data;
- for (int i = 0; i < size; i++) {
- localData[start + i] = columnValues.get(i);
- }
- }
-
- /** Ensures that this cursor has enough capacity. */
- private void ensureCapacity(int size) {
- if (size > data.length) {
- Object[] oldData = this.data;
- int newSize = data.length * 2;
- if (newSize < size) {
- newSize = size;
- }
- this.data = new Object[newSize];
- System.arraycopy(oldData, 0, this.data, 0, oldData.length);
- }
- }
-
- /**
- * Builds a row, starting from the left-most column and adding one column
- * value at a time. Follows the same ordering as the column names specified
- * at cursor construction time.
- */
- public class RowBuilder {
-
- private int index;
- private final int endIndex;
-
- RowBuilder(int index, int endIndex) {
- this.index = index;
- this.endIndex = endIndex;
- }
-
- /**
- * Sets the next column value in this row.
- *
- * @throws CursorIndexOutOfBoundsException if you try to add too many
- * values
- * @return this builder to support chaining
- */
- public RowBuilder add(Object columnValue) {
- if (index == endIndex) {
- throw new CursorIndexOutOfBoundsException(
- "No more columns left.");
- }
-
- data[index++] = columnValue;
- return this;
- }
- }
-
- // AbstractCursor implementation.
-
- public int getCount() {
- return rowCount;
- }
-
- public String[] getColumnNames() {
- return columnNames;
- }
-
- public String getString(int column) {
- return String.valueOf(get(column));
- }
-
- public short getShort(int column) {
- Object value = get(column);
- return (value instanceof String)
- ? Short.valueOf((String) value)
- : ((Number) value).shortValue();
- }
-
- public int getInt(int column) {
- Object value = get(column);
- return (value instanceof String)
- ? Integer.valueOf((String) value)
- : ((Number) value).intValue();
- }
-
- public long getLong(int column) {
- Object value = get(column);
- return (value instanceof String)
- ? Long.valueOf((String) value)
- : ((Number) value).longValue();
- }
-
- public float getFloat(int column) {
- Object value = get(column);
- return (value instanceof String)
- ? Float.valueOf((String) value)
- : ((Number) value).floatValue();
- }
-
- public double getDouble(int column) {
- Object value = get(column);
- return (value instanceof String)
- ? Double.valueOf((String) value)
- : ((Number) value).doubleValue();
- }
-
- 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
deleted file mode 100644
index 7e91159..0000000
--- a/core/java/android/database/MergeCursor.java
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database;
-
-/**
- * A convience class that lets you present an array of Cursors as a single linear Cursor.
- * The schema of the cursors presented is entirely up to the creator of the MergeCursor, and
- * may be different if that is desired. Calls to getColumns, getColumnIndex, etc will return the
- * value for the row that the MergeCursor is currently pointing at.
- */
-public class MergeCursor extends AbstractCursor
-{
- private DataSetObserver mObserver = new DataSetObserver() {
-
- @Override
- public void onChanged() {
- // Reset our position so the optimizations in move-related code
- // don't screw us over
- mPos = -1;
- }
-
- @Override
- public void onInvalidated() {
- mPos = -1;
- }
- };
-
- public MergeCursor(Cursor[] cursors)
- {
- mCursors = cursors;
- mCursor = cursors[0];
-
- for (int i = 0; i < mCursors.length; i++) {
- if (mCursors[i] == null) continue;
-
- mCursors[i].registerDataSetObserver(mObserver);
- }
- }
-
- @Override
- public int getCount()
- {
- int count = 0;
- int length = mCursors.length;
- for (int i = 0 ; i < length ; i++) {
- if (mCursors[i] != null) {
- count += mCursors[i].getCount();
- }
- }
- return count;
- }
-
- @Override
- public boolean onMove(int oldPosition, int newPosition)
- {
- /* Find the right cursor */
- mCursor = null;
- int cursorStartPos = 0;
- int length = mCursors.length;
- for (int i = 0 ; i < length; i++) {
- if (mCursors[i] == null) {
- continue;
- }
-
- if (newPosition < (cursorStartPos + mCursors[i].getCount())) {
- mCursor = mCursors[i];
- break;
- }
-
- cursorStartPos += mCursors[i].getCount();
- }
-
- /* Move it to the right position */
- if (mCursor != null) {
- boolean ret = mCursor.moveToPosition(newPosition - cursorStartPos);
- return ret;
- }
- return false;
- }
-
- /**
- * @hide
- * @deprecated
- */
- @Override
- public boolean deleteRow()
- {
- return mCursor.deleteRow();
- }
-
- /**
- * @hide
- * @deprecated
- */
- @Override
- public boolean commitUpdates() {
- int length = mCursors.length;
- for (int i = 0 ; i < length ; i++) {
- if (mCursors[i] != null) {
- mCursors[i].commitUpdates();
- }
- }
- onChange(true);
- return true;
- }
-
- @Override
- public String getString(int column)
- {
- return mCursor.getString(column);
- }
-
- @Override
- public short getShort(int column)
- {
- return mCursor.getShort(column);
- }
-
- @Override
- public int getInt(int column)
- {
- return mCursor.getInt(column);
- }
-
- @Override
- public long getLong(int column)
- {
- return mCursor.getLong(column);
- }
-
- @Override
- public float getFloat(int column)
- {
- return mCursor.getFloat(column);
- }
-
- @Override
- public double getDouble(int column)
- {
- return mCursor.getDouble(column);
- }
-
- @Override
- public boolean isNull(int column)
- {
- return mCursor.isNull(column);
- }
-
- @Override
- public byte[] getBlob(int column)
- {
- return mCursor.getBlob(column);
- }
-
- @Override
- public String[] getColumnNames()
- {
- if (mCursor != null) {
- return mCursor.getColumnNames();
- } else {
- return new String[0];
- }
- }
-
- @Override
- public void deactivate()
- {
- int length = mCursors.length;
- for (int i = 0 ; i < length ; i++) {
- if (mCursors[i] != null) {
- mCursors[i].deactivate();
- }
- }
- }
-
- @Override
- public void close() {
- int length = mCursors.length;
- for (int i = 0 ; i < length ; i++) {
- if (mCursors[i] == null) continue;
- mCursors[i].close();
- }
- }
-
- @Override
- public void registerContentObserver(ContentObserver observer) {
- int length = mCursors.length;
- for (int i = 0 ; i < length ; i++) {
- if (mCursors[i] != null) {
- mCursors[i].registerContentObserver(observer);
- }
- }
- }
- @Override
- public void unregisterContentObserver(ContentObserver observer) {
- int length = mCursors.length;
- for (int i = 0 ; i < length ; i++) {
- if (mCursors[i] != null) {
- mCursors[i].unregisterContentObserver(observer);
- }
- }
- }
-
- @Override
- public void registerDataSetObserver(DataSetObserver observer) {
- int length = mCursors.length;
- for (int i = 0 ; i < length ; i++) {
- if (mCursors[i] != null) {
- mCursors[i].registerDataSetObserver(observer);
- }
- }
- }
-
- @Override
- public void unregisterDataSetObserver(DataSetObserver observer) {
- int length = mCursors.length;
- for (int i = 0 ; i < length ; i++) {
- if (mCursors[i] != null) {
- mCursors[i].unregisterDataSetObserver(observer);
- }
- }
- }
-
- @Override
- public boolean requery()
- {
- int length = mCursors.length;
- for (int i = 0 ; i < length ; i++) {
- if (mCursors[i] == null) {
- continue;
- }
-
- if (mCursors[i].requery() == false) {
- return false;
- }
- }
-
- return true;
- }
-
- private Cursor mCursor; // updated in onMove
- private Cursor[] mCursors;
-}
diff --git a/core/java/android/database/Observable.java b/core/java/android/database/Observable.java
deleted file mode 100644
index b6fecab..0000000
--- a/core/java/android/database/Observable.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2007 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database;
-
-import java.util.ArrayList;
-
-/**
- * Provides methods for (un)registering arbitrary observers in an ArrayList.
- */
-public abstract class Observable<T> {
- /**
- * The list of observers. An observer can be in the list at most
- * once and will never be null.
- */
- protected final ArrayList<T> mObservers = new ArrayList<T>();
-
- /**
- * Adds an observer to the list. The observer cannot be null and it must not already
- * be registered.
- * @param observer the observer to register
- * @throws IllegalArgumentException the observer is null
- * @throws IllegalStateException the observer is already registered
- */
- public void registerObserver(T observer) {
- if (observer == null) {
- throw new IllegalArgumentException("The observer is null.");
- }
- synchronized(mObservers) {
- if (mObservers.contains(observer)) {
- throw new IllegalStateException("Observer " + observer + " is already registered.");
- }
- mObservers.add(observer);
- }
- }
-
- /**
- * Removes a previously registered observer. The observer must not be null and it
- * must already have been registered.
- * @param observer the observer to unregister
- * @throws IllegalArgumentException the observer is null
- * @throws IllegalStateException the observer is not yet registered
- */
- public void unregisterObserver(T observer) {
- if (observer == null) {
- throw new IllegalArgumentException("The observer is null.");
- }
- synchronized(mObservers) {
- int index = mObservers.indexOf(observer);
- if (index == -1) {
- throw new IllegalStateException("Observer " + observer + " was not registered.");
- }
- mObservers.remove(index);
- }
- }
-
- /**
- * Remove all registered observer
- */
- public void unregisterAll() {
- synchronized(mObservers) {
- mObservers.clear();
- }
- }
-}
diff --git a/core/java/android/database/SQLException.java b/core/java/android/database/SQLException.java
deleted file mode 100644
index 0386af0..0000000
--- a/core/java/android/database/SQLException.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database;
-
-/**
- * An exception that indicates there was an error with SQL parsing or execution.
- */
-public class SQLException extends RuntimeException
-{
- public SQLException() {}
-
- public SQLException(String error)
- {
- super(error);
- }
-}
diff --git a/core/java/android/database/StaleDataException.java b/core/java/android/database/StaleDataException.java
deleted file mode 100644
index ee70beb..0000000
--- a/core/java/android/database/StaleDataException.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database;
-
-/**
- * This exception is thrown when a Cursor contains stale data and must be
- * requeried before being used again.
- */
-public class StaleDataException extends java.lang.RuntimeException
-{
- public StaleDataException()
- {
- super();
- }
-
- public StaleDataException(String description)
- {
- super(description);
- }
-}
diff --git a/core/java/android/database/package.html b/core/java/android/database/package.html
deleted file mode 100644
index 1f76d9f..0000000
--- a/core/java/android/database/package.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<HTML>
-<BODY>
-Contains classes to explore data returned through a content provider.
-<p>
-If you need to manage data in a private database, use the {@link
-android.database.sqlite} classes. These classes are used to manage the {@link
-android.database.Cursor} object returned from a content provider query. Databases
-are usually created and opened with {@link android.content.Context#openOrCreateDatabase}
-To make requests through
-content providers, you can use the {@link android.content.ContentResolver
-content.ContentResolver} class.
-<p>All databases are stored on the device in <code>/data/data/&lt;package_name&gt;/databases</code>
-</BODY>
-</HTML>
diff --git a/core/java/android/database/sqlite/SQLiteAbortException.java b/core/java/android/database/sqlite/SQLiteAbortException.java
deleted file mode 100644
index 64dc4b7..0000000
--- a/core/java/android/database/sqlite/SQLiteAbortException.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2008 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database.sqlite;
-
-/**
- * An exception that indicates that the SQLite program was aborted.
- * This can happen either through a call to ABORT in a trigger,
- * or as the result of using the ABORT conflict clause.
- */
-public class SQLiteAbortException extends SQLiteException {
- public SQLiteAbortException() {}
-
- public SQLiteAbortException(String error) {
- super(error);
- }
-}
diff --git a/core/java/android/database/sqlite/SQLiteClosable.java b/core/java/android/database/sqlite/SQLiteClosable.java
deleted file mode 100644
index f64261c..0000000
--- a/core/java/android/database/sqlite/SQLiteClosable.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2007 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database.sqlite;
-
-/**
- * An object create from a SQLiteDatabase that can be closed.
- */
-public abstract class SQLiteClosable {
- private int mReferenceCount = 1;
- private Object mLock = new Object();
- protected abstract void onAllReferencesReleased();
- protected void onAllReferencesReleasedFromContainer(){}
-
- public void acquireReference() {
- synchronized(mLock) {
- if (mReferenceCount <= 0) {
- throw new IllegalStateException(
- "attempt to acquire a reference on a close SQLiteClosable");
- }
- mReferenceCount++;
- }
- }
-
- public void releaseReference() {
- synchronized(mLock) {
- mReferenceCount--;
- if (mReferenceCount == 0) {
- onAllReferencesReleased();
- }
- }
- }
-
- public void releaseReferenceFromContainer() {
- synchronized(mLock) {
- mReferenceCount--;
- if (mReferenceCount == 0) {
- onAllReferencesReleasedFromContainer();
- }
- }
- }
-}
diff --git a/core/java/android/database/sqlite/SQLiteConstraintException.java b/core/java/android/database/sqlite/SQLiteConstraintException.java
deleted file mode 100644
index e3119eb..0000000
--- a/core/java/android/database/sqlite/SQLiteConstraintException.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2008 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database.sqlite;
-
-/**
- * An exception that indicates that an integrity constraint was violated.
- */
-public class SQLiteConstraintException extends SQLiteException {
- public SQLiteConstraintException() {}
-
- public SQLiteConstraintException(String error) {
- super(error);
- }
-}
diff --git a/core/java/android/database/sqlite/SQLiteCursor.java b/core/java/android/database/sqlite/SQLiteCursor.java
deleted file mode 100644
index 70b9b83..0000000
--- a/core/java/android/database/sqlite/SQLiteCursor.java
+++ /dev/null
@@ -1,606 +0,0 @@
-/*
- * 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database.sqlite;
-
-import android.database.AbstractWindowedCursor;
-import android.database.CursorWindow;
-import android.database.DataSetObserver;
-import android.database.SQLException;
-
-import android.os.Handler;
-import android.os.Message;
-import android.os.Process;
-import android.text.TextUtils;
-import android.util.Config;
-import android.util.Log;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.concurrent.locks.ReentrantLock;
-
-/**
- * A Cursor implementation that exposes results from a query on a
- * {@link SQLiteDatabase}.
- */
-public class SQLiteCursor extends AbstractWindowedCursor {
- static final String TAG = "Cursor";
- static final int NO_COUNT = -1;
-
- /** The name of the table to edit */
- private String mEditTable;
-
- /** The names of the columns in the rows */
- private String[] mColumns;
-
- /** The query object for the cursor */
- private SQLiteQuery mQuery;
-
- /** The database the cursor was created from */
- private SQLiteDatabase mDatabase;
-
- /** The compiled query this cursor came from */
- private SQLiteCursorDriver mDriver;
-
- /** The number of rows in the cursor */
- private int mCount = NO_COUNT;
-
- /** A mapping of column names to column indices, to speed up lookups */
- private Map<String, Integer> mColumnNameMap;
-
- /** Used to find out where a cursor was allocated in case it never got
- * released. */
- private StackTraceElement[] mStackTraceElements;
-
- /**
- * mMaxRead is the max items that each cursor window reads
- * default to a very high value
- */
- private int mMaxRead = Integer.MAX_VALUE;
- private int mInitialRead = Integer.MAX_VALUE;
- private int mCursorState = 0;
- private ReentrantLock mLock = null;
- private boolean mPendingData = false;
-
- /**
- * support for a cursor variant that doesn't always read all results
- * initialRead is the initial number of items that cursor window reads
- * if query contains more than this number of items, a thread will be
- * created and handle the left over items so that caller can show
- * results as soon as possible
- * @param initialRead initial number of items that cursor read
- * @param maxRead leftover items read at maxRead items per time
- * @hide
- */
- public void setLoadStyle(int initialRead, int maxRead) {
- mMaxRead = maxRead;
- mInitialRead = initialRead;
- mLock = new ReentrantLock(true);
- }
-
- private void queryThreadLock() {
- if (mLock != null) {
- mLock.lock();
- }
- }
-
- private void queryThreadUnlock() {
- if (mLock != null) {
- mLock.unlock();
- }
- }
-
-
- /**
- * @hide
- */
- final private class QueryThread implements Runnable {
- private final int mThreadState;
- QueryThread(int version) {
- mThreadState = version;
- }
- private void sendMessage() {
- if (mNotificationHandler != null) {
- mNotificationHandler.sendEmptyMessage(1);
- mPendingData = false;
- } else {
- mPendingData = true;
- }
-
- }
- public void run() {
- // use cached mWindow, to avoid get null mWindow
- CursorWindow cw = mWindow;
- Process.setThreadPriority(Process.myTid(), Process.THREAD_PRIORITY_BACKGROUND);
- // the cursor's state doesn't change
- while (true) {
- mLock.lock();
- if (mCursorState != mThreadState) {
- mLock.unlock();
- break;
- }
- try {
- int count = mQuery.fillWindow(cw, mMaxRead, mCount);
- // return -1 means not finished
- if (count != 0) {
- if (count == NO_COUNT){
- mCount += mMaxRead;
- sendMessage();
- } else {
- mCount = count;
- sendMessage();
- break;
- }
- } else {
- break;
- }
- } catch (Exception e) {
- // end the tread when the cursor is close
- break;
- } finally {
- mLock.unlock();
- }
- }
- }
- }
-
- /**
- * @hide
- */
- protected class MainThreadNotificationHandler extends Handler {
- public void handleMessage(Message msg) {
- notifyDataSetChange();
- }
- }
-
- /**
- * @hide
- */
- protected MainThreadNotificationHandler mNotificationHandler;
-
- public void registerDataSetObserver(DataSetObserver observer) {
- super.registerDataSetObserver(observer);
- if ((Integer.MAX_VALUE != mMaxRead || Integer.MAX_VALUE != mInitialRead) &&
- mNotificationHandler == null) {
- queryThreadLock();
- try {
- mNotificationHandler = new MainThreadNotificationHandler();
- if (mPendingData) {
- notifyDataSetChange();
- mPendingData = false;
- }
- } finally {
- queryThreadUnlock();
- }
- }
-
- }
-
- /**
- * Execute a query and provide access to its result set through a Cursor
- * interface. For a query such as: {@code SELECT name, birth, phone FROM
- * myTable WHERE ... LIMIT 1,20 ORDER BY...} the column names (name, birth,
- * phone) would be in the projection argument and everything from
- * {@code FROM} onward would be in the params argument. This constructor
- * has package scope.
- *
- * @param db a reference to a Database object that is already constructed
- * and opened
- * @param editTable the name of the table used for this query
- * @param query the rest of the query terms
- * cursor is finalized
- */
- public SQLiteCursor(SQLiteDatabase db, SQLiteCursorDriver driver,
- String editTable, SQLiteQuery query) {
- // The AbstractCursor constructor needs to do some setup.
- super();
-
- if (SQLiteDebug.DEBUG_ACTIVE_CURSOR_FINALIZATION) {
- mStackTraceElements = new Exception().getStackTrace();
- }
-
- mDatabase = db;
- mDriver = driver;
- mEditTable = editTable;
- mColumnNameMap = null;
- mQuery = query;
-
- try {
- db.lock();
-
- // Setup the list of columns
- int columnCount = mQuery.columnCountLocked();
- mColumns = new String[columnCount];
-
- // Read in all column names
- for (int i = 0; i < columnCount; i++) {
- String columnName = mQuery.columnNameLocked(i);
- mColumns[i] = columnName;
- if (Config.LOGV) {
- Log.v("DatabaseWindow", "mColumns[" + i + "] is "
- + mColumns[i]);
- }
-
- // Make note of the row ID column index for quick access to it
- if ("_id".equals(columnName)) {
- mRowIdColumnIndex = i;
- }
- }
- } finally {
- db.unlock();
- }
- }
-
- /**
- * @return the SQLiteDatabase that this cursor is associated with.
- */
- public SQLiteDatabase getDatabase() {
- return mDatabase;
- }
-
- @Override
- public boolean onMove(int oldPosition, int newPosition) {
- // Make sure the row at newPosition is present in the window
- if (mWindow == null || newPosition < mWindow.getStartPosition() ||
- newPosition >= (mWindow.getStartPosition() + mWindow.getNumRows())) {
- fillWindow(newPosition);
- }
-
- return true;
- }
-
- @Override
- public int getCount() {
- if (mCount == NO_COUNT) {
- fillWindow(0);
- }
- return mCount;
- }
-
- private void fillWindow (int startPos) {
- if (mWindow == null) {
- // If there isn't a window set already it will only be accessed locally
- mWindow = new CursorWindow(true /* the window is local only */);
- } else {
- mCursorState++;
- queryThreadLock();
- try {
- mWindow.clear();
- } finally {
- queryThreadUnlock();
- }
- }
- mWindow.setStartPosition(startPos);
- mCount = mQuery.fillWindow(mWindow, mInitialRead, 0);
- // return -1 means not finished
- if (mCount == NO_COUNT){
- mCount = startPos + mInitialRead;
- Thread t = new Thread(new QueryThread(mCursorState), "query thread");
- t.start();
- }
- }
-
- @Override
- public int getColumnIndex(String columnName) {
- // Create mColumnNameMap on demand
- if (mColumnNameMap == null) {
- String[] columns = mColumns;
- int columnCount = columns.length;
- HashMap<String, Integer> map = new HashMap<String, Integer>(columnCount, 1);
- for (int i = 0; i < columnCount; i++) {
- map.put(columns[i], i);
- }
- mColumnNameMap = map;
- }
-
- // Hack according to bug 903852
- final int periodIndex = columnName.lastIndexOf('.');
- if (periodIndex != -1) {
- Exception e = new Exception();
- Log.e(TAG, "requesting column name with table name -- " + columnName, e);
- columnName = columnName.substring(periodIndex + 1);
- }
-
- Integer i = mColumnNameMap.get(columnName);
- if (i != null) {
- return i.intValue();
- } else {
- return -1;
- }
- }
-
- /**
- * @hide
- * @deprecated
- */
- @Override
- public boolean deleteRow() {
- checkPosition();
-
- // Only allow deletes if there is an ID column, and the ID has been read from it
- if (mRowIdColumnIndex == -1 || mCurrentRowID == null) {
- Log.e(TAG,
- "Could not delete row because either the row ID column is not available or it" +
- "has not been read.");
- return false;
- }
-
- boolean success;
-
- /*
- * Ensure we don't change the state of the database when another
- * thread is holding the database lock. requery() and moveTo() are also
- * synchronized here to make sure they get the state of the database
- * immediately following the DELETE.
- */
- mDatabase.lock();
- try {
- try {
- mDatabase.delete(mEditTable, mColumns[mRowIdColumnIndex] + "=?",
- new String[] {mCurrentRowID.toString()});
- success = true;
- } catch (SQLException e) {
- success = false;
- }
-
- int pos = mPos;
- requery();
-
- /*
- * Ensure proper cursor state. Note that mCurrentRowID changes
- * in this call.
- */
- moveToPosition(pos);
- } finally {
- mDatabase.unlock();
- }
-
- if (success) {
- onChange(true);
- return true;
- } else {
- return false;
- }
- }
-
- @Override
- public String[] getColumnNames() {
- return mColumns;
- }
-
- /**
- * @hide
- * @deprecated
- */
- @Override
- public boolean supportsUpdates() {
- return super.supportsUpdates() && !TextUtils.isEmpty(mEditTable);
- }
-
- /**
- * @hide
- * @deprecated
- */
- @Override
- public boolean commitUpdates(Map<? extends Long,
- ? extends Map<String, Object>> additionalValues) {
- if (!supportsUpdates()) {
- Log.e(TAG, "commitUpdates not supported on this cursor, did you "
- + "include the _id column?");
- return false;
- }
-
- /*
- * Prevent other threads from changing the updated rows while they're
- * being processed here.
- */
- synchronized (mUpdatedRows) {
- if (additionalValues != null) {
- mUpdatedRows.putAll(additionalValues);
- }
-
- if (mUpdatedRows.size() == 0) {
- return true;
- }
-
- /*
- * Prevent other threads from changing the database state while
- * we process the updated rows, and prevents us from changing the
- * database behind the back of another thread.
- */
- mDatabase.beginTransaction();
- try {
- StringBuilder sql = new StringBuilder(128);
-
- // For each row that has been updated
- for (Map.Entry<Long, Map<String, Object>> rowEntry :
- mUpdatedRows.entrySet()) {
- Map<String, Object> values = rowEntry.getValue();
- Long rowIdObj = rowEntry.getKey();
-
- if (rowIdObj == null || values == null) {
- throw new IllegalStateException("null rowId or values found! rowId = "
- + rowIdObj + ", values = " + values);
- }
-
- if (values.size() == 0) {
- continue;
- }
-
- long rowId = rowIdObj.longValue();
-
- Iterator<Map.Entry<String, Object>> valuesIter =
- values.entrySet().iterator();
-
- sql.setLength(0);
- sql.append("UPDATE " + mEditTable + " SET ");
-
- // For each column value that has been updated
- Object[] bindings = new Object[values.size()];
- int i = 0;
- while (valuesIter.hasNext()) {
- Map.Entry<String, Object> entry = valuesIter.next();
- sql.append(entry.getKey());
- sql.append("=?");
- bindings[i] = entry.getValue();
- if (valuesIter.hasNext()) {
- sql.append(", ");
- }
- i++;
- }
-
- sql.append(" WHERE " + mColumns[mRowIdColumnIndex]
- + '=' + rowId);
- sql.append(';');
- mDatabase.execSQL(sql.toString(), bindings);
- mDatabase.rowUpdated(mEditTable, rowId);
- }
- mDatabase.setTransactionSuccessful();
- } finally {
- mDatabase.endTransaction();
- }
-
- mUpdatedRows.clear();
- }
-
- // Let any change observers know about the update
- onChange(true);
-
- return true;
- }
-
- private void deactivateCommon() {
- if (Config.LOGV) Log.v(TAG, "<<< Releasing cursor " + this);
- mCursorState = 0;
- if (mWindow != null) {
- mWindow.close();
- mWindow = null;
- }
- if (Config.LOGV) Log.v("DatabaseWindow", "closing window in release()");
- }
-
- @Override
- public void deactivate() {
- super.deactivate();
- deactivateCommon();
- mDriver.cursorDeactivated();
- }
-
- @Override
- public void close() {
- super.close();
- deactivateCommon();
- mQuery.close();
- mDriver.cursorClosed();
- }
-
- @Override
- public boolean requery() {
- if (isClosed()) {
- return false;
- }
- long timeStart = 0;
- if (Config.LOGV) {
- timeStart = System.currentTimeMillis();
- }
- /*
- * Synchronize on the database lock to ensure that mCount matches the
- * results of mQuery.requery().
- */
- mDatabase.lock();
- try {
- if (mWindow != null) {
- mWindow.clear();
- }
- mPos = -1;
- // This one will recreate the temp table, and get its count
- mDriver.cursorRequeried(this);
- mCount = NO_COUNT;
- mCursorState++;
- queryThreadLock();
- try {
- mQuery.requery();
- } finally {
- queryThreadUnlock();
- }
- } finally {
- mDatabase.unlock();
- }
-
- if (Config.LOGV) {
- Log.v("DatabaseWindow", "closing window in requery()");
- Log.v(TAG, "--- Requery()ed cursor " + this + ": " + mQuery);
- }
-
- boolean result = super.requery();
- if (Config.LOGV) {
- long timeEnd = System.currentTimeMillis();
- Log.v(TAG, "requery (" + (timeEnd - timeStart) + " ms): " + mDriver.toString());
- }
- return result;
- }
-
- @Override
- public void setWindow(CursorWindow window) {
- if (mWindow != null) {
- mCursorState++;
- queryThreadLock();
- try {
- mWindow.close();
- } finally {
- queryThreadUnlock();
- }
- mCount = NO_COUNT;
- }
- mWindow = window;
- }
-
- /**
- * Changes the selection arguments. The new values take effect after a call to requery().
- */
- public void setSelectionArguments(String[] selectionArgs) {
- mDriver.setBindArguments(selectionArgs);
- }
-
- /**
- * Release the native resources, if they haven't been released yet.
- */
- @Override
- protected void finalize() {
- try {
- if (mWindow != null) {
- close();
- String message = "Finalizing cursor " + this + " on " + mEditTable
- + " that has not been deactivated or closed";
- if (SQLiteDebug.DEBUG_ACTIVE_CURSOR_FINALIZATION) {
- Log.d(TAG, message + "\nThis cursor was created in:");
- for (StackTraceElement ste : mStackTraceElements) {
- Log.d(TAG, " " + ste);
- }
- }
- SQLiteDebug.notifyActiveCursorFinalized();
- throw new IllegalStateException(message);
- } else {
- if (Config.LOGV) {
- Log.v(TAG, "Finalizing cursor " + this + " on " + mEditTable);
- }
- }
- } finally {
- super.finalize();
- }
- }
-}
diff --git a/core/java/android/database/sqlite/SQLiteCursorDriver.java b/core/java/android/database/sqlite/SQLiteCursorDriver.java
deleted file mode 100644
index eda1b78..0000000
--- a/core/java/android/database/sqlite/SQLiteCursorDriver.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2007 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database.sqlite;
-
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase.CursorFactory;
-
-/**
- * A driver for SQLiteCursors that is used to create them and gets notified
- * by the cursors it creates on significant events in their lifetimes.
- */
-public interface SQLiteCursorDriver {
- /**
- * Executes the query returning a Cursor over the result set.
- *
- * @param factory The CursorFactory to use when creating the Cursors, or
- * null if standard SQLiteCursors should be returned.
- * @return a Cursor over the result set
- */
- Cursor query(CursorFactory factory, String[] bindArgs);
-
- /**
- * Called by a SQLiteCursor when it is released.
- */
- void cursorDeactivated();
-
- /**
- * Called by a SQLiteCursor when it is requeryed.
- *
- * @return The new count value.
- */
- void cursorRequeried(Cursor cursor);
-
- /**
- * Called by a SQLiteCursor when it it closed to destroy this object as well.
- */
- void cursorClosed();
-
- /**
- * Set new bind arguments. These will take effect in cursorRequeried().
- * @param bindArgs the new arguments
- */
- public void setBindArguments(String[] bindArgs);
-}
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
deleted file mode 100644
index 87bb277..0000000
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ /dev/null
@@ -1,1675 +0,0 @@
-/*
- * 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database.sqlite;
-
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.database.SQLException;
-import android.os.Debug;
-import android.os.SystemClock;
-import android.text.TextUtils;
-import android.util.Config;
-import android.util.Log;
-import android.util.EventLog;
-
-import java.io.File;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-import java.util.WeakHashMap;
-import java.util.concurrent.locks.ReentrantLock;
-
-/**
- * Exposes methods to manage a SQLite database.
- * <p>SQLiteDatabase has methods to create, delete, execute SQL commands, and
- * perform other common database management tasks.
- * <p>See the Notepad sample application in the SDK for an example of creating
- * and managing a database.
- * <p> Database names must be unique within an application, not across all
- * applications.
- *
- * <h3>Localized Collation - ORDER BY</h3>
- * <p>In addition to SQLite's default <code>BINARY</code> collator, Android supplies
- * two more, <code>LOCALIZED</code>, which changes with the system's current locale
- * if you wire it up correctly (XXX a link needed!), and <code>UNICODE</code>, which
- * is the Unicode Collation Algorithm and not tailored to the current locale.
- */
-public class SQLiteDatabase extends SQLiteClosable {
- private static final String TAG = "Database";
- private static final int DB_OPERATION_EVENT = 52000;
-
- /**
- * Algorithms used in ON CONFLICT clause
- * http://www.sqlite.org/lang_conflict.html
- * @hide
- */
- public enum ConflictAlgorithm {
- /**
- * When a constraint violation occurs, an immediate ROLLBACK occurs,
- * thus ending the current transaction, and the command aborts with a
- * return code of SQLITE_CONSTRAINT. If no transaction is active
- * (other than the implied transaction that is created on every command)
- * then this algorithm works the same as ABORT.
- */
- ROLLBACK("ROLLBACK"),
-
- /**
- * When a constraint violation occurs,no ROLLBACK is executed
- * so changes from prior commands within the same transaction
- * are preserved. This is the default behavior.
- */
- ABORT("ABORT"),
-
- /**
- * When a constraint violation occurs, the command aborts with a return
- * code SQLITE_CONSTRAINT. But any changes to the database that
- * the command made prior to encountering the constraint violation
- * are preserved and are not backed out.
- */
- FAIL("FAIL"),
-
- /**
- * When a constraint violation occurs, the one row that contains
- * the constraint violation is not inserted or changed.
- * But the command continues executing normally. Other rows before and
- * after the row that contained the constraint violation continue to be
- * inserted or updated normally. No error is returned.
- */
- IGNORE("IGNORE"),
-
- /**
- * When a UNIQUE constraint violation occurs, the pre-existing rows that
- * are causing the constraint violation are removed prior to inserting
- * or updating the current row. Thus the insert or update always occurs.
- * The command continues executing normally. No error is returned.
- * If a NOT NULL constraint violation occurs, the NULL value is replaced
- * by the default value for that column. If the column has no default
- * value, then the ABORT algorithm is used. If a CHECK constraint
- * violation occurs then the IGNORE algorithm is used. When this conflict
- * resolution strategy deletes rows in order to satisfy a constraint,
- * it does not invoke delete triggers on those rows.
- * This behavior might change in a future release.
- */
- REPLACE("REPLACE");
-
- private final String mValue;
- ConflictAlgorithm(String value) {
- mValue = value;
- }
- public String value() {
- return mValue;
- }
- }
-
- /**
- * Maximum Length Of A LIKE Or GLOB Pattern
- * The pattern matching algorithm used in the default LIKE and GLOB implementation
- * of SQLite can exhibit O(N^2) performance (where N is the number of characters in
- * the pattern) for certain pathological cases. To avoid denial-of-service attacks
- * the length of the LIKE or GLOB pattern is limited to SQLITE_MAX_LIKE_PATTERN_LENGTH bytes.
- * The default value of this limit is 50000. A modern workstation can evaluate
- * even a pathological LIKE or GLOB pattern of 50000 bytes relatively quickly.
- * The denial of service problem only comes into play when the pattern length gets
- * into millions of bytes. Nevertheless, since most useful LIKE or GLOB patterns
- * are at most a few dozen bytes in length, paranoid application developers may
- * want to reduce this parameter to something in the range of a few hundred
- * if they know that external users are able to generate arbitrary patterns.
- */
- public static final int SQLITE_MAX_LIKE_PATTERN_LENGTH = 50000;
-
- /**
- * Flag for {@link #openDatabase} to open the database for reading and writing.
- * If the disk is full, this may fail even before you actually write anything.
- *
- * {@more} Note that the value of this flag is 0, so it is the default.
- */
- public static final int OPEN_READWRITE = 0x00000000; // update native code if changing
-
- /**
- * Flag for {@link #openDatabase} to open the database for reading only.
- * This is the only reliable way to open a database if the disk may be full.
- */
- public static final int OPEN_READONLY = 0x00000001; // update native code if changing
-
- private static final int OPEN_READ_MASK = 0x00000001; // update native code if changing
-
- /**
- * Flag for {@link #openDatabase} to open the database without support for localized collators.
- *
- * {@more} This causes the collator <code>LOCALIZED</code> not to be created.
- * You must be consistent when using this flag to use the setting the database was
- * created with. If this is set, {@link #setLocale} will do nothing.
- */
- public static final int NO_LOCALIZED_COLLATORS = 0x00000010; // update native code if changing
-
- /**
- * Flag for {@link #openDatabase} to create the database file if it does not already exist.
- */
- public static final int CREATE_IF_NECESSARY = 0x10000000; // update native code if changing
-
- /**
- * Indicates whether the most-recently started transaction has been marked as successful.
- */
- private boolean mInnerTransactionIsSuccessful;
-
- /**
- * Valid during the life of a transaction, and indicates whether the entire transaction (the
- * outer one and all of the inner ones) so far has been successful.
- */
- private boolean mTransactionIsSuccessful;
-
- /** Synchronize on this when accessing the database */
- private final ReentrantLock mLock = new ReentrantLock(true);
-
- private long mLockAcquiredWallTime = 0L;
- private long mLockAcquiredThreadTime = 0L;
-
- // limit the frequency of complaints about each database to one within 20 sec
- // unless run command adb shell setprop log.tag.Database VERBOSE
- private static final int LOCK_WARNING_WINDOW_IN_MS = 20000;
- /** If the lock is held this long then a warning will be printed when it is released. */
- private static final int LOCK_ACQUIRED_WARNING_TIME_IN_MS = 300;
- private static final int LOCK_ACQUIRED_WARNING_THREAD_TIME_IN_MS = 100;
- private static final int LOCK_ACQUIRED_WARNING_TIME_IN_MS_ALWAYS_PRINT = 2000;
-
- private long mLastLockMessageTime = 0L;
-
- /** Used by native code, do not rename */
- /* package */ int mNativeHandle = 0;
-
- /** Used to make temp table names unique */
- /* package */ int mTempTableSequence = 0;
-
- /** The path for the database file */
- private String mPath;
-
- /** The flags passed to open/create */
- private int mFlags;
-
- /** The optional factory to use when creating new Cursors */
- private CursorFactory mFactory;
-
- private WeakHashMap<SQLiteClosable, Object> mPrograms;
-
- private final RuntimeException mLeakedException;
-
- // package visible, since callers will access directly to minimize overhead in the case
- // that logging is not enabled.
- /* package */ final boolean mLogStats;
-
- /**
- * @param closable
- */
- void addSQLiteClosable(SQLiteClosable closable) {
- lock();
- try {
- mPrograms.put(closable, null);
- } finally {
- unlock();
- }
- }
-
- void removeSQLiteClosable(SQLiteClosable closable) {
- lock();
- try {
- mPrograms.remove(closable);
- } finally {
- unlock();
- }
- }
-
- @Override
- protected void onAllReferencesReleased() {
- if (isOpen()) {
- dbclose();
- }
- }
-
- /**
- * Attempts to release memory that SQLite holds but does not require to
- * operate properly. Typically this memory will come from the page cache.
- *
- * @return the number of bytes actually released
- */
- static public native int releaseMemory();
-
- /**
- * Control whether or not the SQLiteDatabase is made thread-safe by using locks
- * around critical sections. This is pretty expensive, so if you know that your
- * DB will only be used by a single thread then you should set this to false.
- * The default is true.
- * @param lockingEnabled set to true to enable locks, false otherwise
- */
- public void setLockingEnabled(boolean lockingEnabled) {
- mLockingEnabled = lockingEnabled;
- }
-
- /**
- * If set then the SQLiteDatabase is made thread-safe by using locks
- * around critical sections
- */
- private boolean mLockingEnabled = true;
-
- /* package */ void onCorruption() {
- try {
- // Close the database (if we can), which will cause subsequent operations to fail.
- close();
- } finally {
- Log.e(TAG, "Removing corrupt database: " + mPath);
- // Delete the corrupt file. Don't re-create it now -- that would just confuse people
- // -- but the next time someone tries to open it, they can set it up from scratch.
- new File(mPath).delete();
- }
- }
-
- /**
- * Locks the database for exclusive access. The database lock must be held when
- * touch the native sqlite3* object since it is single threaded and uses
- * a polling lock contention algorithm. The lock is recursive, and may be acquired
- * multiple times by the same thread. This is a no-op if mLockingEnabled is false.
- *
- * @see #unlock()
- */
- /* package */ void lock() {
- if (!mLockingEnabled) return;
- mLock.lock();
- if (SQLiteDebug.DEBUG_LOCK_TIME_TRACKING) {
- if (mLock.getHoldCount() == 1) {
- // Use elapsed real-time since the CPU may sleep when waiting for IO
- mLockAcquiredWallTime = SystemClock.elapsedRealtime();
- mLockAcquiredThreadTime = Debug.threadCpuTimeNanos();
- }
- }
- }
-
- /**
- * Locks the database for exclusive access. The database lock must be held when
- * touch the native sqlite3* object since it is single threaded and uses
- * a polling lock contention algorithm. The lock is recursive, and may be acquired
- * multiple times by the same thread.
- *
- * @see #unlockForced()
- */
- private void lockForced() {
- mLock.lock();
- if (SQLiteDebug.DEBUG_LOCK_TIME_TRACKING) {
- if (mLock.getHoldCount() == 1) {
- // Use elapsed real-time since the CPU may sleep when waiting for IO
- mLockAcquiredWallTime = SystemClock.elapsedRealtime();
- mLockAcquiredThreadTime = Debug.threadCpuTimeNanos();
- }
- }
- }
-
- /**
- * Releases the database lock. This is a no-op if mLockingEnabled is false.
- *
- * @see #unlock()
- */
- /* package */ void unlock() {
- if (!mLockingEnabled) return;
- if (SQLiteDebug.DEBUG_LOCK_TIME_TRACKING) {
- if (mLock.getHoldCount() == 1) {
- checkLockHoldTime();
- }
- }
- mLock.unlock();
- }
-
- /**
- * Releases the database lock.
- *
- * @see #unlockForced()
- */
- private void unlockForced() {
- if (SQLiteDebug.DEBUG_LOCK_TIME_TRACKING) {
- if (mLock.getHoldCount() == 1) {
- checkLockHoldTime();
- }
- }
- mLock.unlock();
- }
-
- private void checkLockHoldTime() {
- // Use elapsed real-time since the CPU may sleep when waiting for IO
- long elapsedTime = SystemClock.elapsedRealtime();
- long lockedTime = elapsedTime - mLockAcquiredWallTime;
- if (lockedTime < LOCK_ACQUIRED_WARNING_TIME_IN_MS_ALWAYS_PRINT &&
- !Log.isLoggable(TAG, Log.VERBOSE) &&
- (elapsedTime - mLastLockMessageTime) < LOCK_WARNING_WINDOW_IN_MS) {
- return;
- }
- if (lockedTime > LOCK_ACQUIRED_WARNING_TIME_IN_MS) {
- int threadTime = (int)
- ((Debug.threadCpuTimeNanos() - mLockAcquiredThreadTime) / 1000000);
- if (threadTime > LOCK_ACQUIRED_WARNING_THREAD_TIME_IN_MS ||
- lockedTime > LOCK_ACQUIRED_WARNING_TIME_IN_MS_ALWAYS_PRINT) {
- mLastLockMessageTime = elapsedTime;
- String msg = "lock held on " + mPath + " for " + lockedTime + "ms. Thread time was "
- + threadTime + "ms";
- if (SQLiteDebug.DEBUG_LOCK_TIME_TRACKING_STACK_TRACE) {
- Log.d(TAG, msg, new Exception());
- } else {
- Log.d(TAG, msg);
- }
- }
- }
- }
-
- /**
- * Begins a transaction. Transactions can be nested. When the outer transaction is ended all of
- * the work done in that transaction and all of the nested transactions will be committed or
- * rolled back. The changes will be rolled back if any transaction is ended without being
- * marked as clean (by calling setTransactionSuccessful). Otherwise they will be committed.
- *
- * <p>Here is the standard idiom for transactions:
- *
- * <pre>
- * db.beginTransaction();
- * try {
- * ...
- * db.setTransactionSuccessful();
- * } finally {
- * db.endTransaction();
- * }
- * </pre>
- */
- public void beginTransaction() {
- lockForced();
- boolean ok = false;
- try {
- // If this thread already had the lock then get out
- if (mLock.getHoldCount() > 1) {
- if (mInnerTransactionIsSuccessful) {
- String msg = "Cannot call beginTransaction between "
- + "calling setTransactionSuccessful and endTransaction";
- IllegalStateException e = new IllegalStateException(msg);
- Log.e(TAG, "beginTransaction() failed", e);
- throw e;
- }
- ok = true;
- return;
- }
-
- // This thread didn't already have the lock, so begin a database
- // transaction now.
- execSQL("BEGIN EXCLUSIVE;");
- mTransactionIsSuccessful = true;
- mInnerTransactionIsSuccessful = false;
- ok = true;
- } finally {
- if (!ok) {
- // beginTransaction is called before the try block so we must release the lock in
- // the case of failure.
- unlockForced();
- }
- }
- }
-
- /**
- * End a transaction. See beginTransaction for notes about how to use this and when transactions
- * are committed and rolled back.
- */
- public void endTransaction() {
- if (!mLock.isHeldByCurrentThread()) {
- throw new IllegalStateException("no transaction pending");
- }
- try {
- if (mInnerTransactionIsSuccessful) {
- mInnerTransactionIsSuccessful = false;
- } else {
- mTransactionIsSuccessful = false;
- }
- if (mLock.getHoldCount() != 1) {
- return;
- }
- if (mTransactionIsSuccessful) {
- execSQL("COMMIT;");
- } else {
- try {
- execSQL("ROLLBACK;");
- } catch (SQLException e) {
- if (Config.LOGD) {
- Log.d(TAG, "exception during rollback, maybe the DB previously "
- + "performed an auto-rollback");
- }
- }
- }
- } finally {
- unlockForced();
- if (Config.LOGV) {
- Log.v(TAG, "unlocked " + Thread.currentThread()
- + ", holdCount is " + mLock.getHoldCount());
- }
- }
- }
-
- /**
- * Marks the current transaction as successful. Do not do any more database work between
- * calling this and calling endTransaction. Do as little non-database work as possible in that
- * situation too. If any errors are encountered between this and endTransaction the transaction
- * will still be committed.
- *
- * @throws IllegalStateException if the current thread is not in a transaction or the
- * transaction is already marked as successful.
- */
- public void setTransactionSuccessful() {
- if (!mLock.isHeldByCurrentThread()) {
- throw new IllegalStateException("no transaction pending");
- }
- if (mInnerTransactionIsSuccessful) {
- throw new IllegalStateException(
- "setTransactionSuccessful may only be called once per call to beginTransaction");
- }
- mInnerTransactionIsSuccessful = true;
- }
-
- /**
- * return true if there is a transaction pending
- */
- public boolean inTransaction() {
- return mLock.getHoldCount() > 0;
- }
-
- /**
- * Checks if the database lock is held by this thread.
- *
- * @return true, if this thread is holding the database lock.
- */
- public boolean isDbLockedByCurrentThread() {
- return mLock.isHeldByCurrentThread();
- }
-
- /**
- * Checks if the database is locked by another thread. This is
- * just an estimate, since this status can change at any time,
- * including after the call is made but before the result has
- * been acted upon.
- *
- * @return true, if the database is locked by another thread
- */
- public boolean isDbLockedByOtherThreads() {
- return !mLock.isHeldByCurrentThread() && mLock.isLocked();
- }
-
- /**
- * Temporarily end the transaction to let other threads run. The transaction is assumed to be
- * successful so far. Do not call setTransactionSuccessful before calling this. When this
- * returns a new transaction will have been created but not marked as successful.
- * @return true if the transaction was yielded
- * @deprecated if the db is locked more than once (becuase of nested transactions) then the lock
- * will not be yielded. Use yieldIfContendedSafely instead.
- */
- public boolean yieldIfContended() {
- return yieldIfContendedHelper(false /* do not check yielding */);
- }
-
- /**
- * Temporarily end the transaction to let other threads run. The transaction is assumed to be
- * successful so far. Do not call setTransactionSuccessful before calling this. When this
- * returns a new transaction will have been created but not marked as successful. This assumes
- * that there are no nested transactions (beginTransaction has only been called once) and will
- * through an exception if that is not the case.
- * @return true if the transaction was yielded
- */
- public boolean yieldIfContendedSafely() {
- return yieldIfContendedHelper(true /* check yielding */);
- }
-
- private boolean yieldIfContendedHelper(boolean checkFullyYielded) {
- if (mLock.getQueueLength() == 0) {
- // Reset the lock acquire time since we know that the thread was willing to yield
- // the lock at this time.
- mLockAcquiredWallTime = SystemClock.elapsedRealtime();
- mLockAcquiredThreadTime = Debug.threadCpuTimeNanos();
- return false;
- }
- setTransactionSuccessful();
- endTransaction();
- if (checkFullyYielded) {
- if (this.isDbLockedByCurrentThread()) {
- throw new IllegalStateException(
- "Db locked more than once. yielfIfContended cannot yield");
- }
- }
- beginTransaction();
- return true;
- }
-
- /** Maps table names to info about what to which _sync_time column to set
- * to NULL on an update. This is used to support syncing. */
- private final Map<String, SyncUpdateInfo> mSyncUpdateInfo =
- new HashMap<String, SyncUpdateInfo>();
-
- public Map<String, String> getSyncedTables() {
- synchronized(mSyncUpdateInfo) {
- HashMap<String, String> tables = new HashMap<String, String>();
- for (String table : mSyncUpdateInfo.keySet()) {
- SyncUpdateInfo info = mSyncUpdateInfo.get(table);
- if (info.deletedTable != null) {
- tables.put(table, info.deletedTable);
- }
- }
- return tables;
- }
- }
-
- /**
- * Internal class used to keep track what needs to be marked as changed
- * when an update occurs. This is used for syncing, so the sync engine
- * knows what data has been updated locally.
- */
- static private class SyncUpdateInfo {
- /**
- * Creates the SyncUpdateInfo class.
- *
- * @param masterTable The table to set _sync_time to NULL in
- * @param deletedTable The deleted table that corresponds to the
- * master table
- * @param foreignKey The key that refers to the primary key in table
- */
- SyncUpdateInfo(String masterTable, String deletedTable,
- String foreignKey) {
- this.masterTable = masterTable;
- this.deletedTable = deletedTable;
- this.foreignKey = foreignKey;
- }
-
- /** The table containing the _sync_time column */
- String masterTable;
-
- /** The deleted table that corresponds to the master table */
- String deletedTable;
-
- /** The key in the local table the row in table. It may be _id, if table
- * is the local table. */
- String foreignKey;
- }
-
- /**
- * Used to allow returning sub-classes of {@link Cursor} when calling query.
- */
- public interface CursorFactory {
- /**
- * See
- * {@link SQLiteCursor#SQLiteCursor(SQLiteDatabase, SQLiteCursorDriver,
- * String, SQLiteQuery)}.
- */
- public Cursor newCursor(SQLiteDatabase db,
- SQLiteCursorDriver masterQuery, String editTable,
- SQLiteQuery query);
- }
-
- /**
- * Open the database according to the flags {@link #OPEN_READWRITE}
- * {@link #OPEN_READONLY} {@link #CREATE_IF_NECESSARY} and/or {@link #NO_LOCALIZED_COLLATORS}.
- *
- * <p>Sets the locale of the database to the the system's current locale.
- * Call {@link #setLocale} if you would like something else.</p>
- *
- * @param path to database file to open and/or create
- * @param factory an optional factory class that is called to instantiate a
- * cursor when query is called, or null for default
- * @param flags to control database access mode
- * @return the newly opened database
- * @throws SQLiteException if the database cannot be opened
- */
- public static SQLiteDatabase openDatabase(String path, CursorFactory factory, int flags) {
- SQLiteDatabase db = null;
- try {
- // Open the database.
- return new SQLiteDatabase(path, factory, flags);
- } catch (SQLiteDatabaseCorruptException e) {
- // Try to recover from this, if we can.
- // TODO: should we do this for other open failures?
- Log.e(TAG, "Deleting and re-creating corrupt database " + path, e);
- new File(path).delete();
- return new SQLiteDatabase(path, factory, flags);
- }
- }
-
- /**
- * Equivalent to openDatabase(file.getPath(), factory, CREATE_IF_NECESSARY).
- */
- public static SQLiteDatabase openOrCreateDatabase(File file, CursorFactory factory) {
- return openOrCreateDatabase(file.getPath(), factory);
- }
-
- /**
- * Equivalent to openDatabase(path, factory, CREATE_IF_NECESSARY).
- */
- public static SQLiteDatabase openOrCreateDatabase(String path, CursorFactory factory) {
- return openDatabase(path, factory, CREATE_IF_NECESSARY);
- }
-
- /**
- * Create a memory backed SQLite database. Its contents will be destroyed
- * when the database is closed.
- *
- * <p>Sets the locale of the database to the the system's current locale.
- * Call {@link #setLocale} if you would like something else.</p>
- *
- * @param factory an optional factory class that is called to instantiate a
- * cursor when query is called
- * @return a SQLiteDatabase object, or null if the database can't be created
- */
- public static SQLiteDatabase create(CursorFactory factory) {
- // This is a magic string with special meaning for SQLite.
- return openDatabase(":memory:", factory, CREATE_IF_NECESSARY);
- }
-
- /**
- * Close the database.
- */
- public void close() {
- lock();
- try {
- closeClosable();
- releaseReference();
- } finally {
- unlock();
- }
- }
-
- private void closeClosable() {
- Iterator<Map.Entry<SQLiteClosable, Object>> iter = mPrograms.entrySet().iterator();
- while (iter.hasNext()) {
- Map.Entry<SQLiteClosable, Object> entry = iter.next();
- SQLiteClosable program = entry.getKey();
- if (program != null) {
- program.onAllReferencesReleasedFromContainer();
- }
- }
- }
-
- /**
- * Native call to close the database.
- */
- private native void dbclose();
-
- /**
- * Gets the database version.
- *
- * @return the database version
- */
- public int getVersion() {
- SQLiteStatement prog = null;
- lock();
- try {
- prog = new SQLiteStatement(this, "PRAGMA user_version;");
- long version = prog.simpleQueryForLong();
- return (int) version;
- } finally {
- if (prog != null) prog.close();
- unlock();
- }
- }
-
- /**
- * Sets the database version.
- *
- * @param version the new database version
- */
- public void setVersion(int version) {
- execSQL("PRAGMA user_version = " + version);
- }
-
- /**
- * Returns the maximum size the database may grow to.
- *
- * @return the new maximum database size
- */
- public long getMaximumSize() {
- SQLiteStatement prog = null;
- lock();
- try {
- prog = new SQLiteStatement(this,
- "PRAGMA max_page_count;");
- long pageCount = prog.simpleQueryForLong();
- return pageCount * getPageSize();
- } finally {
- if (prog != null) prog.close();
- unlock();
- }
- }
-
- /**
- * Sets the maximum size the database will grow to. The maximum size cannot
- * be set below the current size.
- *
- * @param numBytes the maximum database size, in bytes
- * @return the new maximum database size
- */
- public long setMaximumSize(long numBytes) {
- SQLiteStatement prog = null;
- lock();
- try {
- long pageSize = getPageSize();
- long numPages = numBytes / pageSize;
- // If numBytes isn't a multiple of pageSize, bump up a page
- if ((numBytes % pageSize) != 0) {
- numPages++;
- }
- prog = new SQLiteStatement(this,
- "PRAGMA max_page_count = " + numPages);
- long newPageCount = prog.simpleQueryForLong();
- return newPageCount * pageSize;
- } finally {
- if (prog != null) prog.close();
- unlock();
- }
- }
-
- /**
- * Returns the maximum size the database may grow to.
- *
- * @return the new maximum database size
- */
- public long getPageSize() {
- SQLiteStatement prog = null;
- lock();
- try {
- prog = new SQLiteStatement(this,
- "PRAGMA page_size;");
- long size = prog.simpleQueryForLong();
- return size;
- } finally {
- if (prog != null) prog.close();
- unlock();
- }
- }
-
- /**
- * Sets the database page size. The page size must be a power of two. This
- * method does not work if any data has been written to the database file,
- * and must be called right after the database has been created.
- *
- * @param numBytes the database page size, in bytes
- */
- public void setPageSize(long numBytes) {
- execSQL("PRAGMA page_size = " + numBytes);
- }
-
- /**
- * Mark this table as syncable. When an update occurs in this table the
- * _sync_dirty field will be set to ensure proper syncing operation.
- *
- * @param table the table to mark as syncable
- * @param deletedTable The deleted table that corresponds to the
- * syncable table
- */
- public void markTableSyncable(String table, String deletedTable) {
- markTableSyncable(table, "_id", table, deletedTable);
- }
-
- /**
- * Mark this table as syncable, with the _sync_dirty residing in another
- * table. When an update occurs in this table the _sync_dirty field of the
- * row in updateTable with the _id in foreignKey will be set to
- * ensure proper syncing operation.
- *
- * @param table an update on this table will trigger a sync time removal
- * @param foreignKey this is the column in table whose value is an _id in
- * updateTable
- * @param updateTable this is the table that will have its _sync_dirty
- */
- public void markTableSyncable(String table, String foreignKey,
- String updateTable) {
- markTableSyncable(table, foreignKey, updateTable, null);
- }
-
- /**
- * Mark this table as syncable, with the _sync_dirty residing in another
- * table. When an update occurs in this table the _sync_dirty field of the
- * row in updateTable with the _id in foreignKey will be set to
- * ensure proper syncing operation.
- *
- * @param table an update on this table will trigger a sync time removal
- * @param foreignKey this is the column in table whose value is an _id in
- * updateTable
- * @param updateTable this is the table that will have its _sync_dirty
- * @param deletedTable The deleted table that corresponds to the
- * updateTable
- */
- private void markTableSyncable(String table, String foreignKey,
- String updateTable, String deletedTable) {
- lock();
- try {
- native_execSQL("SELECT _sync_dirty FROM " + updateTable
- + " LIMIT 0");
- native_execSQL("SELECT " + foreignKey + " FROM " + table
- + " LIMIT 0");
- } finally {
- unlock();
- }
-
- SyncUpdateInfo info = new SyncUpdateInfo(updateTable, deletedTable,
- foreignKey);
- synchronized (mSyncUpdateInfo) {
- mSyncUpdateInfo.put(table, info);
- }
- }
-
- /**
- * Call for each row that is updated in a cursor.
- *
- * @param table the table the row is in
- * @param rowId the row ID of the updated row
- */
- /* package */ void rowUpdated(String table, long rowId) {
- SyncUpdateInfo info;
- synchronized (mSyncUpdateInfo) {
- info = mSyncUpdateInfo.get(table);
- }
- if (info != null) {
- execSQL("UPDATE " + info.masterTable
- + " SET _sync_dirty=1 WHERE _id=(SELECT " + info.foreignKey
- + " FROM " + table + " WHERE _id=" + rowId + ")");
- }
- }
-
- /**
- * Finds the name of the first table, which is editable.
- *
- * @param tables a list of tables
- * @return the first table listed
- */
- public static String findEditTable(String tables) {
- if (!TextUtils.isEmpty(tables)) {
- // find the first word terminated by either a space or a comma
- int spacepos = tables.indexOf(' ');
- int commapos = tables.indexOf(',');
-
- if (spacepos > 0 && (spacepos < commapos || commapos < 0)) {
- return tables.substring(0, spacepos);
- } else if (commapos > 0 && (commapos < spacepos || spacepos < 0) ) {
- return tables.substring(0, commapos);
- }
- return tables;
- } else {
- throw new IllegalStateException("Invalid tables");
- }
- }
-
- /**
- * Compiles an SQL statement into a reusable pre-compiled statement object.
- * The parameters are identical to {@link #execSQL(String)}. You may put ?s in the
- * statement and fill in those values with {@link SQLiteProgram#bindString}
- * and {@link SQLiteProgram#bindLong} each time you want to run the
- * statement. Statements may not return result sets larger than 1x1.
- *
- * @param sql The raw SQL statement, may contain ? for unknown values to be
- * bound later.
- * @return a pre-compiled statement object.
- */
- public SQLiteStatement compileStatement(String sql) throws SQLException {
- lock();
- try {
- return new SQLiteStatement(this, sql);
- } finally {
- unlock();
- }
- }
-
- /**
- * Query the given URL, returning a {@link Cursor} over the result set.
- *
- * @param distinct true if you want each row to be unique, false otherwise.
- * @param table The table name to compile the query against.
- * @param columns A list of which columns to return. Passing null will
- * return all columns, which is discouraged to prevent reading
- * data from storage that isn't going to be used.
- * @param selection A filter declaring which rows to return, formatted as an
- * SQL WHERE clause (excluding the WHERE itself). Passing null
- * will return all rows for the given table.
- * @param selectionArgs You may include ?s in selection, which will be
- * replaced by the values from selectionArgs, in order that they
- * appear in the selection. The values will be bound as Strings.
- * @param groupBy A filter declaring how to group rows, formatted as an SQL
- * GROUP BY clause (excluding the GROUP BY itself). Passing null
- * will cause the rows to not be grouped.
- * @param having A filter declare which row groups to include in the cursor,
- * if row grouping is being used, formatted as an SQL HAVING
- * clause (excluding the HAVING itself). Passing null will cause
- * all row groups to be included, and is required when row
- * grouping is not being used.
- * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
- * (excluding the ORDER BY itself). Passing null will use the
- * default sort order, which may be unordered.
- * @param limit Limits the number of rows returned by the query,
- * formatted as LIMIT clause. Passing null denotes no LIMIT clause.
- * @return A Cursor object, which is positioned before the first entry
- * @see Cursor
- */
- public Cursor query(boolean distinct, String table, String[] columns,
- String selection, String[] selectionArgs, String groupBy,
- String having, String orderBy, String limit) {
- return queryWithFactory(null, distinct, table, columns, selection, selectionArgs,
- groupBy, having, orderBy, limit);
- }
-
- /**
- * Query the given URL, returning a {@link Cursor} over the result set.
- *
- * @param cursorFactory the cursor factory to use, or null for the default factory
- * @param distinct true if you want each row to be unique, false otherwise.
- * @param table The table name to compile the query against.
- * @param columns A list of which columns to return. Passing null will
- * return all columns, which is discouraged to prevent reading
- * data from storage that isn't going to be used.
- * @param selection A filter declaring which rows to return, formatted as an
- * SQL WHERE clause (excluding the WHERE itself). Passing null
- * will return all rows for the given table.
- * @param selectionArgs You may include ?s in selection, which will be
- * replaced by the values from selectionArgs, in order that they
- * appear in the selection. The values will be bound as Strings.
- * @param groupBy A filter declaring how to group rows, formatted as an SQL
- * GROUP BY clause (excluding the GROUP BY itself). Passing null
- * will cause the rows to not be grouped.
- * @param having A filter declare which row groups to include in the cursor,
- * if row grouping is being used, formatted as an SQL HAVING
- * clause (excluding the HAVING itself). Passing null will cause
- * all row groups to be included, and is required when row
- * grouping is not being used.
- * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
- * (excluding the ORDER BY itself). Passing null will use the
- * default sort order, which may be unordered.
- * @param limit Limits the number of rows returned by the query,
- * formatted as LIMIT clause. Passing null denotes no LIMIT clause.
- * @return A Cursor object, which is positioned before the first entry
- * @see Cursor
- */
- public Cursor queryWithFactory(CursorFactory cursorFactory,
- boolean distinct, String table, String[] columns,
- String selection, String[] selectionArgs, String groupBy,
- String having, String orderBy, String limit) {
- String sql = SQLiteQueryBuilder.buildQueryString(
- distinct, table, columns, selection, groupBy, having, orderBy, limit);
-
- return rawQueryWithFactory(
- cursorFactory, sql, selectionArgs, findEditTable(table));
- }
-
- /**
- * Query the given table, returning a {@link Cursor} over the result set.
- *
- * @param table The table name to compile the query against.
- * @param columns A list of which columns to return. Passing null will
- * return all columns, which is discouraged to prevent reading
- * data from storage that isn't going to be used.
- * @param selection A filter declaring which rows to return, formatted as an
- * SQL WHERE clause (excluding the WHERE itself). Passing null
- * will return all rows for the given table.
- * @param selectionArgs You may include ?s in selection, which will be
- * replaced by the values from selectionArgs, in order that they
- * appear in the selection. The values will be bound as Strings.
- * @param groupBy A filter declaring how to group rows, formatted as an SQL
- * GROUP BY clause (excluding the GROUP BY itself). Passing null
- * will cause the rows to not be grouped.
- * @param having A filter declare which row groups to include in the cursor,
- * if row grouping is being used, formatted as an SQL HAVING
- * clause (excluding the HAVING itself). Passing null will cause
- * all row groups to be included, and is required when row
- * grouping is not being used.
- * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
- * (excluding the ORDER BY itself). Passing null will use the
- * default sort order, which may be unordered.
- * @return A {@link Cursor} object, which is positioned before the first entry
- * @see Cursor
- */
- public Cursor query(String table, String[] columns, String selection,
- String[] selectionArgs, String groupBy, String having,
- String orderBy) {
-
- return query(false, table, columns, selection, selectionArgs, groupBy,
- having, orderBy, null /* limit */);
- }
-
- /**
- * Query the given table, returning a {@link Cursor} over the result set.
- *
- * @param table The table name to compile the query against.
- * @param columns A list of which columns to return. Passing null will
- * return all columns, which is discouraged to prevent reading
- * data from storage that isn't going to be used.
- * @param selection A filter declaring which rows to return, formatted as an
- * SQL WHERE clause (excluding the WHERE itself). Passing null
- * will return all rows for the given table.
- * @param selectionArgs You may include ?s in selection, which will be
- * replaced by the values from selectionArgs, in order that they
- * appear in the selection. The values will be bound as Strings.
- * @param groupBy A filter declaring how to group rows, formatted as an SQL
- * GROUP BY clause (excluding the GROUP BY itself). Passing null
- * will cause the rows to not be grouped.
- * @param having A filter declare which row groups to include in the cursor,
- * if row grouping is being used, formatted as an SQL HAVING
- * clause (excluding the HAVING itself). Passing null will cause
- * all row groups to be included, and is required when row
- * grouping is not being used.
- * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
- * (excluding the ORDER BY itself). Passing null will use the
- * default sort order, which may be unordered.
- * @param limit Limits the number of rows returned by the query,
- * formatted as LIMIT clause. Passing null denotes no LIMIT clause.
- * @return A {@link Cursor} object, which is positioned before the first entry
- * @see Cursor
- */
- public Cursor query(String table, String[] columns, String selection,
- String[] selectionArgs, String groupBy, String having,
- String orderBy, String limit) {
-
- return query(false, table, columns, selection, selectionArgs, groupBy,
- having, orderBy, limit);
- }
-
- /**
- * Runs the provided SQL and returns a {@link Cursor} over the result set.
- *
- * @param sql the SQL query. The SQL string must not be ; terminated
- * @param selectionArgs You may include ?s in where clause in the query,
- * which will be replaced by the values from selectionArgs. The
- * values will be bound as Strings.
- * @return A {@link Cursor} object, which is positioned before the first entry
- */
- public Cursor rawQuery(String sql, String[] selectionArgs) {
- return rawQueryWithFactory(null, sql, selectionArgs, null);
- }
-
- /**
- * Runs the provided SQL and returns a cursor over the result set.
- *
- * @param cursorFactory the cursor factory to use, or null for the default factory
- * @param sql the SQL query. The SQL string must not be ; terminated
- * @param selectionArgs You may include ?s in where clause in the query,
- * which will be replaced by the values from selectionArgs. The
- * values will be bound as Strings.
- * @param editTable the name of the first table, which is editable
- * @return A {@link Cursor} object, which is positioned before the first entry
- */
- public Cursor rawQueryWithFactory(
- CursorFactory cursorFactory, String sql, String[] selectionArgs,
- String editTable) {
- long timeStart = 0;
-
- if (Config.LOGV) {
- timeStart = System.currentTimeMillis();
- }
-
- SQLiteCursorDriver driver = new SQLiteDirectCursorDriver(this, sql, editTable);
-
- try {
- return driver.query(
- cursorFactory != null ? cursorFactory : mFactory,
- selectionArgs);
- } finally {
- if (Config.LOGV) {
- long duration = System.currentTimeMillis() - timeStart;
-
- Log.v(SQLiteCursor.TAG,
- "query (" + duration + " ms): " + driver.toString() + ", args are "
- + (selectionArgs != null
- ? TextUtils.join(",", selectionArgs)
- : "<null>"));
- }
- }
- }
-
- /**
- * Runs the provided SQL and returns a cursor over the result set.
- * The cursor will read an initial set of rows and the return to the caller.
- * It will continue to read in batches and send data changed notifications
- * when the later batches are ready.
- * @param sql the SQL query. The SQL string must not be ; terminated
- * @param selectionArgs You may include ?s in where clause in the query,
- * which will be replaced by the values from selectionArgs. The
- * values will be bound as Strings.
- * @param initialRead set the initial count of items to read from the cursor
- * @param maxRead set the count of items to read on each iteration after the first
- * @return A {@link Cursor} object, which is positioned before the first entry
- * @hide pending API council approval
- */
- public Cursor rawQuery(String sql, String[] selectionArgs,
- int initialRead, int maxRead) {
- SQLiteCursor c = (SQLiteCursor)rawQueryWithFactory(
- null, sql, selectionArgs, null);
- c.setLoadStyle(initialRead, maxRead);
- return c;
- }
-
- /**
- * Convenience method for inserting a row into the database.
- *
- * @param table the table to insert the row into
- * @param nullColumnHack SQL doesn't allow inserting a completely empty row,
- * so if initialValues is empty this column will explicitly be
- * assigned a NULL value
- * @param values this map contains the initial column values for the
- * row. The keys should be the column names and the values the
- * column values
- * @return the row ID of the newly inserted row, or -1 if an error occurred
- */
- public long insert(String table, String nullColumnHack, ContentValues values) {
- try {
- return insertWithOnConflict(table, nullColumnHack, values, null);
- } catch (SQLException e) {
- Log.e(TAG, "Error inserting " + values, e);
- return -1;
- }
- }
-
- /**
- * Convenience method for inserting a row into the database.
- *
- * @param table the table to insert the row into
- * @param nullColumnHack SQL doesn't allow inserting a completely empty row,
- * so if initialValues is empty this column will explicitly be
- * assigned a NULL value
- * @param values this map contains the initial column values for the
- * row. The keys should be the column names and the values the
- * column values
- * @throws SQLException
- * @return the row ID of the newly inserted row, or -1 if an error occurred
- */
- public long insertOrThrow(String table, String nullColumnHack, ContentValues values)
- throws SQLException {
- return insertWithOnConflict(table, nullColumnHack, values, null);
- }
-
- /**
- * Convenience method for replacing a row in the database.
- *
- * @param table the table in which to replace the row
- * @param nullColumnHack SQL doesn't allow inserting a completely empty row,
- * so if initialValues is empty this row will explicitly be
- * assigned a NULL value
- * @param initialValues this map contains the initial column values for
- * the row. The key
- * @return the row ID of the newly inserted row, or -1 if an error occurred
- */
- public long replace(String table, String nullColumnHack, ContentValues initialValues) {
- try {
- return insertWithOnConflict(table, nullColumnHack, initialValues,
- ConflictAlgorithm.REPLACE);
- } catch (SQLException e) {
- Log.e(TAG, "Error inserting " + initialValues, e);
- return -1;
- }
- }
-
- /**
- * Convenience method for replacing a row in the database.
- *
- * @param table the table in which to replace the row
- * @param nullColumnHack SQL doesn't allow inserting a completely empty row,
- * so if initialValues is empty this row will explicitly be
- * assigned a NULL value
- * @param initialValues this map contains the initial column values for
- * the row. The key
- * @throws SQLException
- * @return the row ID of the newly inserted row, or -1 if an error occurred
- */
- public long replaceOrThrow(String table, String nullColumnHack,
- ContentValues initialValues) throws SQLException {
- return insertWithOnConflict(table, nullColumnHack, initialValues,
- ConflictAlgorithm.REPLACE);
- }
-
- /**
- * General method for inserting a row into the database.
- *
- * @param table the table to insert the row into
- * @param nullColumnHack SQL doesn't allow inserting a completely empty row,
- * so if initialValues is empty this column will explicitly be
- * assigned a NULL value
- * @param initialValues this map contains the initial column values for the
- * row. The keys should be the column names and the values the
- * column values
- * @param algorithm {@link ConflictAlgorithm} for insert conflict resolver
- * @return the row ID of the newly inserted row, or -1 if an error occurred
- * @hide
- */
- public long insertWithOnConflict(String table, String nullColumnHack,
- ContentValues initialValues, ConflictAlgorithm algorithm) {
- if (!isOpen()) {
- throw new IllegalStateException("database not open");
- }
-
- // Measurements show most sql lengths <= 152
- StringBuilder sql = new StringBuilder(152);
- sql.append("INSERT");
- if (algorithm != null) {
- sql.append(" OR ");
- sql.append(algorithm.value());
- }
- sql.append(" INTO ");
- sql.append(table);
- // Measurements show most values lengths < 40
- StringBuilder values = new StringBuilder(40);
-
- Set<Map.Entry<String, Object>> entrySet = null;
- if (initialValues != null && initialValues.size() > 0) {
- entrySet = initialValues.valueSet();
- Iterator<Map.Entry<String, Object>> entriesIter = entrySet.iterator();
- sql.append('(');
-
- boolean needSeparator = false;
- while (entriesIter.hasNext()) {
- if (needSeparator) {
- sql.append(", ");
- values.append(", ");
- }
- needSeparator = true;
- Map.Entry<String, Object> entry = entriesIter.next();
- sql.append(entry.getKey());
- values.append('?');
- }
-
- sql.append(')');
- } else {
- sql.append("(" + nullColumnHack + ") ");
- values.append("NULL");
- }
-
- sql.append(" VALUES(");
- sql.append(values);
- sql.append(");");
-
- lock();
- SQLiteStatement statement = null;
- try {
- statement = compileStatement(sql.toString());
-
- // Bind the values
- if (entrySet != null) {
- int size = entrySet.size();
- Iterator<Map.Entry<String, Object>> entriesIter = entrySet.iterator();
- for (int i = 0; i < size; i++) {
- Map.Entry<String, Object> entry = entriesIter.next();
- DatabaseUtils.bindObjectToProgram(statement, i + 1, entry.getValue());
- }
- }
-
- // Run the program and then cleanup
- statement.execute();
-
- long insertedRowId = lastInsertRow();
- if (insertedRowId == -1) {
- Log.e(TAG, "Error inserting " + initialValues + " using " + sql);
- } else {
- if (Config.LOGD && Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "Inserting row " + insertedRowId + " from "
- + initialValues + " using " + sql);
- }
- }
- return insertedRowId;
- } catch (SQLiteDatabaseCorruptException e) {
- onCorruption();
- throw e;
- } finally {
- if (statement != null) {
- statement.close();
- }
- unlock();
- }
- }
-
- /**
- * Convenience method for deleting rows in the database.
- *
- * @param table the table to delete from
- * @param whereClause the optional WHERE clause to apply when deleting.
- * Passing null will delete all rows.
- * @return the number of rows affected if a whereClause is passed in, 0
- * otherwise. To remove all rows and get a count pass "1" as the
- * whereClause.
- */
- public int delete(String table, String whereClause, String[] whereArgs) {
- if (!isOpen()) {
- throw new IllegalStateException("database not open");
- }
- lock();
- SQLiteStatement statement = null;
- try {
- statement = compileStatement("DELETE FROM " + table
- + (!TextUtils.isEmpty(whereClause)
- ? " WHERE " + whereClause : ""));
- if (whereArgs != null) {
- int numArgs = whereArgs.length;
- for (int i = 0; i < numArgs; i++) {
- DatabaseUtils.bindObjectToProgram(statement, i + 1, whereArgs[i]);
- }
- }
- statement.execute();
- statement.close();
- return lastChangeCount();
- } catch (SQLiteDatabaseCorruptException e) {
- onCorruption();
- throw e;
- } finally {
- if (statement != null) {
- statement.close();
- }
- unlock();
- }
- }
-
- /**
- * Convenience method for updating rows in the database.
- *
- * @param table the table to update in
- * @param values a map from column names to new column values. null is a
- * valid value that will be translated to NULL.
- * @param whereClause the optional WHERE clause to apply when updating.
- * Passing null will update all rows.
- * @return the number of rows affected
- */
- public int update(String table, ContentValues values, String whereClause, String[] whereArgs) {
- return updateWithOnConflict(table, values, whereClause, whereArgs, null);
- }
-
- /**
- * Convenience method for updating rows in the database.
- *
- * @param table the table to update in
- * @param values a map from column names to new column values. null is a
- * valid value that will be translated to NULL.
- * @param whereClause the optional WHERE clause to apply when updating.
- * Passing null will update all rows.
- * @param algorithm {@link ConflictAlgorithm} for update conflict resolver
- * @return the number of rows affected
- * @hide
- */
- public int updateWithOnConflict(String table, ContentValues values,
- String whereClause, String[] whereArgs, ConflictAlgorithm algorithm) {
- if (!isOpen()) {
- throw new IllegalStateException("database not open");
- }
-
- if (values == null || values.size() == 0) {
- throw new IllegalArgumentException("Empty values");
- }
-
- StringBuilder sql = new StringBuilder(120);
- sql.append("UPDATE ");
- if (algorithm != null) {
- sql.append(" OR ");
- sql.append(algorithm.value());
- }
-
- sql.append(table);
- sql.append(" SET ");
-
- Set<Map.Entry<String, Object>> entrySet = values.valueSet();
- Iterator<Map.Entry<String, Object>> entriesIter = entrySet.iterator();
-
- while (entriesIter.hasNext()) {
- Map.Entry<String, Object> entry = entriesIter.next();
- sql.append(entry.getKey());
- sql.append("=?");
- if (entriesIter.hasNext()) {
- sql.append(", ");
- }
- }
-
- if (!TextUtils.isEmpty(whereClause)) {
- sql.append(" WHERE ");
- sql.append(whereClause);
- }
-
- lock();
- SQLiteStatement statement = null;
- try {
- statement = compileStatement(sql.toString());
-
- // Bind the values
- int size = entrySet.size();
- entriesIter = entrySet.iterator();
- int bindArg = 1;
- for (int i = 0; i < size; i++) {
- Map.Entry<String, Object> entry = entriesIter.next();
- DatabaseUtils.bindObjectToProgram(statement, bindArg, entry.getValue());
- bindArg++;
- }
-
- if (whereArgs != null) {
- size = whereArgs.length;
- for (int i = 0; i < size; i++) {
- statement.bindString(bindArg, whereArgs[i]);
- bindArg++;
- }
- }
-
- // Run the program and then cleanup
- statement.execute();
- statement.close();
- int numChangedRows = lastChangeCount();
- if (Config.LOGD && Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "Updated " + numChangedRows + " using " + values + " and " + sql);
- }
- return numChangedRows;
- } catch (SQLiteDatabaseCorruptException e) {
- onCorruption();
- throw e;
- } catch (SQLException e) {
- Log.e(TAG, "Error updating " + values + " using " + sql);
- throw e;
- } finally {
- if (statement != null) {
- statement.close();
- }
- unlock();
- }
- }
-
- /**
- * Execute a single SQL statement that is not a query. For example, CREATE
- * TABLE, DELETE, INSERT, etc. Multiple statements separated by ;s are not
- * supported. it takes a write lock
- *
- * @throws SQLException If the SQL string is invalid for some reason
- */
- public void execSQL(String sql) throws SQLException {
- boolean logStats = mLogStats;
- long timeStart = logStats ? SystemClock.elapsedRealtime() : 0;
- lock();
- try {
- native_execSQL(sql);
- } catch (SQLiteDatabaseCorruptException e) {
- onCorruption();
- throw e;
- } finally {
- unlock();
- }
- if (logStats) {
- logTimeStat(false /* not a read */, timeStart, SystemClock.elapsedRealtime());
- }
- }
-
- /**
- * Execute a single SQL statement that is not a query. For example, CREATE
- * TABLE, DELETE, INSERT, etc. Multiple statements separated by ;s are not
- * supported. it takes a write lock,
- *
- * @param sql
- * @param bindArgs only byte[], String, Long and Double are supported in bindArgs.
- * @throws SQLException If the SQL string is invalid for some reason
- */
- public void execSQL(String sql, Object[] bindArgs) throws SQLException {
- if (bindArgs == null) {
- throw new IllegalArgumentException("Empty bindArgs");
- }
-
- boolean logStats = mLogStats;
- long timeStart = logStats ? SystemClock.elapsedRealtime() : 0;
- lock();
- SQLiteStatement statement = null;
- try {
- statement = compileStatement(sql);
- if (bindArgs != null) {
- int numArgs = bindArgs.length;
- for (int i = 0; i < numArgs; i++) {
- DatabaseUtils.bindObjectToProgram(statement, i + 1, bindArgs[i]);
- }
- }
- statement.execute();
- } catch (SQLiteDatabaseCorruptException e) {
- onCorruption();
- throw e;
- } finally {
- if (statement != null) {
- statement.close();
- }
- unlock();
- }
- if (logStats) {
- logTimeStat(false /* not a read */, timeStart, SystemClock.elapsedRealtime());
- }
- }
-
- @Override
- protected void finalize() {
- if (isOpen()) {
- if (mPrograms.isEmpty()) {
- Log.e(TAG, "Leak found", mLeakedException);
- } else {
- IllegalStateException leakProgram = new IllegalStateException(
- "mPrograms size " + mPrograms.size(), mLeakedException);
- Log.e(TAG, "Leak found", leakProgram);
- }
- closeClosable();
- onAllReferencesReleased();
- }
- }
-
- /**
- * Private constructor. See {@link #create} and {@link #openDatabase}.
- *
- * @param path The full path to the database
- * @param factory The factory to use when creating cursors, may be NULL.
- * @param flags 0 or {@link #NO_LOCALIZED_COLLATORS}. If the database file already
- * exists, mFlags will be updated appropriately.
- */
- private SQLiteDatabase(String path, CursorFactory factory, int flags) {
- if (path == null) {
- throw new IllegalArgumentException("path should not be null");
- }
- mFlags = flags;
- mPath = path;
- mLogStats = "1".equals(android.os.SystemProperties.get("db.logstats"));
-
- mLeakedException = new IllegalStateException(path +
- " SQLiteDatabase created and never closed");
- mFactory = factory;
- dbopen(mPath, mFlags);
- mPrograms = new WeakHashMap<SQLiteClosable,Object>();
- try {
- setLocale(Locale.getDefault());
- } catch (RuntimeException e) {
- Log.e(TAG, "Failed to setLocale() when constructing, closing the database", e);
- dbclose();
- throw e;
- }
- }
-
- /**
- * return whether the DB is opened as read only.
- * @return true if DB is opened as read only
- */
- public boolean isReadOnly() {
- return (mFlags & OPEN_READ_MASK) == OPEN_READONLY;
- }
-
- /**
- * @return true if the DB is currently open (has not been closed)
- */
- public boolean isOpen() {
- return mNativeHandle != 0;
- }
-
- public boolean needUpgrade(int newVersion) {
- return newVersion > getVersion();
- }
-
- /**
- * Getter for the path to the database file.
- *
- * @return the path to our database file.
- */
- public final String getPath() {
- return mPath;
- }
-
- /* package */ void logTimeStat(boolean read, long begin, long end) {
- EventLog.writeEvent(DB_OPERATION_EVENT, mPath, read ? 0 : 1, end - begin);
- }
-
- /**
- * Sets the locale for this database. Does nothing if this database has
- * the NO_LOCALIZED_COLLATORS flag set or was opened read only.
- * @throws SQLException if the locale could not be set. The most common reason
- * for this is that there is no collator available for the locale you requested.
- * In this case the database remains unchanged.
- */
- public void setLocale(Locale locale) {
- lock();
- try {
- native_setLocale(locale.toString(), mFlags);
- } finally {
- unlock();
- }
- }
-
- /**
- * Native call to open the database.
- *
- * @param path The full path to the database
- */
- private native void dbopen(String path, int flags);
-
- /**
- * Native call to execute a raw SQL statement. {@link #lock} must be held
- * when calling this method.
- *
- * @param sql The raw SQL string
- * @throws SQLException
- */
- /* package */ native void native_execSQL(String sql) throws SQLException;
-
- /**
- * Native call to set the locale. {@link #lock} must be held when calling
- * this method.
- * @throws SQLException
- */
- /* package */ native void native_setLocale(String loc, int flags);
-
- /**
- * Returns the row ID of the last row inserted into the database.
- *
- * @return the row ID of the last row inserted into the database.
- */
- /* package */ native long lastInsertRow();
-
- /**
- * Returns the number of changes made in the last statement executed.
- *
- * @return the number of changes made in the last statement executed.
- */
- /* package */ native int lastChangeCount();
-}
diff --git a/core/java/android/database/sqlite/SQLiteDatabaseCorruptException.java b/core/java/android/database/sqlite/SQLiteDatabaseCorruptException.java
deleted file mode 100644
index 73b6c0c..0000000
--- a/core/java/android/database/sqlite/SQLiteDatabaseCorruptException.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database.sqlite;
-
-/**
- * An exception that indicates that the SQLite database file is corrupt.
- */
-public class SQLiteDatabaseCorruptException extends SQLiteException {
- public SQLiteDatabaseCorruptException() {}
-
- public SQLiteDatabaseCorruptException(String error) {
- super(error);
- }
-}
diff --git a/core/java/android/database/sqlite/SQLiteDebug.java b/core/java/android/database/sqlite/SQLiteDebug.java
deleted file mode 100644
index d04afb0..0000000
--- a/core/java/android/database/sqlite/SQLiteDebug.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2007 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database.sqlite;
-
-import android.util.Config;
-
-/**
- * Provides debugging info about all SQLite databases running in the current process.
- *
- * {@hide}
- */
-public final class SQLiteDebug {
- /**
- * Controls the printing of SQL statements as they are executed.
- */
- public static final boolean DEBUG_SQL_STATEMENTS = Config.LOGV;
-
- /**
- * Controls the stack trace reporting of active cursors being
- * finalized.
- */
- public static final boolean DEBUG_ACTIVE_CURSOR_FINALIZATION = Config.LOGV;
-
- /**
- * Controls the tracking of time spent holding the database lock.
- */
- public static final boolean DEBUG_LOCK_TIME_TRACKING = false;
-
- /**
- * Controls the printing of stack traces when tracking the time spent holding the database lock.
- */
- public static final boolean DEBUG_LOCK_TIME_TRACKING_STACK_TRACE = false;
-
- /**
- * Contains statistics about the active pagers in the current process.
- *
- * @see #getPagerStats(PagerStats)
- */
- public static class PagerStats {
- /** The total number of bytes in all pagers in the current process */
- public long totalBytes;
- /** The number of bytes in referenced pages in all pagers in the current process */
- public long referencedBytes;
- /** The number of bytes in all database files opened in the current process */
- public long databaseBytes;
- /** The number of pagers opened in the current process */
- public int numPagers;
- }
-
- /**
- * Gathers statistics about all pagers in the current process.
- */
- public static native void getPagerStats(PagerStats stats);
-
- /**
- * Returns the size of the SQLite heap.
- * @return The size of the SQLite heap in bytes.
- */
- public static native long getHeapSize();
-
- /**
- * Returns the amount of allocated memory in the SQLite heap.
- * @return The allocated size in bytes.
- */
- public static native long getHeapAllocatedSize();
-
- /**
- * Returns the amount of free memory in the SQLite heap.
- * @return The freed size in bytes.
- */
- public static native long getHeapFreeSize();
-
- /**
- * Determines the number of dirty belonging to the SQLite
- * heap segments of this process. pages[0] returns the number of
- * shared pages, pages[1] returns the number of private pages
- */
- public static native void getHeapDirtyPages(int[] pages);
-
- private static int sNumActiveCursorsFinalized = 0;
-
- /**
- * Returns the number of active cursors that have been finalized. This depends on the GC having
- * run but is still useful for tests.
- */
- public static int getNumActiveCursorsFinalized() {
- return sNumActiveCursorsFinalized;
- }
-
- static synchronized void notifyActiveCursorFinalized() {
- sNumActiveCursorsFinalized++;
- }
-}
diff --git a/core/java/android/database/sqlite/SQLiteDirectCursorDriver.java b/core/java/android/database/sqlite/SQLiteDirectCursorDriver.java
deleted file mode 100644
index ca64aca..0000000
--- a/core/java/android/database/sqlite/SQLiteDirectCursorDriver.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2007 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database.sqlite;
-
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase.CursorFactory;
-import android.util.Log;
-
-/**
- * A cursor driver that uses the given query directly.
- *
- * @hide
- */
-public class SQLiteDirectCursorDriver implements SQLiteCursorDriver {
- private static String TAG = "SQLiteDirectCursorDriver";
- private String mEditTable;
- private SQLiteDatabase mDatabase;
- private Cursor mCursor;
- private String mSql;
- private SQLiteQuery mQuery;
-
- public SQLiteDirectCursorDriver(SQLiteDatabase db, String sql, String editTable) {
- mDatabase = db;
- mEditTable = editTable;
- //TODO remove all callers that end in ; and remove this check
- if (sql.charAt(sql.length() - 1) == ';') {
- Log.w(TAG, "Found SQL string that ends in ; -- " + sql);
- sql = sql.substring(0, sql.length() - 1);
- }
- mSql = sql;
- }
-
- public Cursor query(CursorFactory factory, String[] selectionArgs) {
- // Compile the query
- SQLiteQuery query = new SQLiteQuery(mDatabase, mSql, 0, selectionArgs);
-
- try {
- // Arg binding
- int numArgs = selectionArgs == null ? 0 : selectionArgs.length;
- for (int i = 0; i < numArgs; i++) {
- query.bindString(i + 1, selectionArgs[i]);
- }
-
- // Create the cursor
- if (factory == null) {
- mCursor = new SQLiteCursor(mDatabase, this, mEditTable, query);
- } else {
- mCursor = factory.newCursor(mDatabase, this, mEditTable, query);
- }
-
- mQuery = query;
- query = null;
- return mCursor;
- } finally {
- // Make sure this object is cleaned up if something happens
- if (query != null) query.close();
- }
- }
-
- public void cursorClosed() {
- mCursor = null;
- }
-
- public void setBindArguments(String[] bindArgs) {
- final int numArgs = bindArgs.length;
- for (int i = 0; i < numArgs; i++) {
- mQuery.bindString(i + 1, bindArgs[i]);
- }
- }
-
- public void cursorDeactivated() {
- // Do nothing
- }
-
- public void cursorRequeried(Cursor cursor) {
- // Do nothing
- }
-
- @Override
- public String toString() {
- return "SQLiteDirectCursorDriver: " + mSql;
- }
-}
diff --git a/core/java/android/database/sqlite/SQLiteDiskIOException.java b/core/java/android/database/sqlite/SQLiteDiskIOException.java
deleted file mode 100644
index 01b2069..0000000
--- a/core/java/android/database/sqlite/SQLiteDiskIOException.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database.sqlite;
-
-/**
- * An exception that indicates that an IO error occured while accessing the
- * SQLite database file.
- */
-public class SQLiteDiskIOException extends SQLiteException {
- public SQLiteDiskIOException() {}
-
- public SQLiteDiskIOException(String error) {
- super(error);
- }
-}
diff --git a/core/java/android/database/sqlite/SQLiteDoneException.java b/core/java/android/database/sqlite/SQLiteDoneException.java
deleted file mode 100644
index d6d3f66..0000000
--- a/core/java/android/database/sqlite/SQLiteDoneException.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2008 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database.sqlite;
-
-/**
- * An exception that indicates that the SQLite program is done.
- * Thrown when an operation that expects a row (such as {@link
- * SQLiteStatement#simpleQueryForString} or {@link
- * SQLiteStatement#simpleQueryForLong}) does not get one.
- */
-public class SQLiteDoneException extends SQLiteException {
- public SQLiteDoneException() {}
-
- public SQLiteDoneException(String error) {
- super(error);
- }
-}
diff --git a/core/java/android/database/sqlite/SQLiteException.java b/core/java/android/database/sqlite/SQLiteException.java
deleted file mode 100644
index 3a97bfb..0000000
--- a/core/java/android/database/sqlite/SQLiteException.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database.sqlite;
-
-import android.database.SQLException;
-
-/**
- * A SQLite exception that indicates there was an error with SQL parsing or execution.
- */
-public class SQLiteException extends SQLException {
- public SQLiteException() {}
-
- public SQLiteException(String error) {
- super(error);
- }
-}
diff --git a/core/java/android/database/sqlite/SQLiteFullException.java b/core/java/android/database/sqlite/SQLiteFullException.java
deleted file mode 100644
index 582d930..0000000
--- a/core/java/android/database/sqlite/SQLiteFullException.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2008 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database.sqlite;
-
-/**
- * An exception that indicates that the SQLite database is full.
- */
-public class SQLiteFullException extends SQLiteException {
- public SQLiteFullException() {}
-
- public SQLiteFullException(String error) {
- super(error);
- }
-}
diff --git a/core/java/android/database/sqlite/SQLiteMisuseException.java b/core/java/android/database/sqlite/SQLiteMisuseException.java
deleted file mode 100644
index 685f3ea..0000000
--- a/core/java/android/database/sqlite/SQLiteMisuseException.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2008 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database.sqlite;
-
-public class SQLiteMisuseException extends SQLiteException {
- public SQLiteMisuseException() {}
-
- public SQLiteMisuseException(String error) {
- super(error);
- }
-}
diff --git a/core/java/android/database/sqlite/SQLiteOpenHelper.java b/core/java/android/database/sqlite/SQLiteOpenHelper.java
deleted file mode 100644
index 52aac3a..0000000
--- a/core/java/android/database/sqlite/SQLiteOpenHelper.java
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Copyright (C) 2007 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database.sqlite;
-
-import android.content.Context;
-import android.database.sqlite.SQLiteDatabase.CursorFactory;
-import android.util.Log;
-
-/**
- * A helper class to manage database creation and version management.
- * You create a subclass implementing {@link #onCreate}, {@link #onUpgrade} and
- * optionally {@link #onOpen}, and this class takes care of opening the database
- * if it exists, creating it if it does not, and upgrading it as necessary.
- * Transactions are used to make sure the database is always in a sensible state.
- * <p>For an example, see the NotePadProvider class in the NotePad sample application,
- * in the <em>samples/</em> directory of the SDK.</p>
- */
-public abstract class SQLiteOpenHelper {
- private static final String TAG = SQLiteOpenHelper.class.getSimpleName();
-
- private final Context mContext;
- private final String mName;
- private final CursorFactory mFactory;
- private final int mNewVersion;
-
- private SQLiteDatabase mDatabase = null;
- private boolean mIsInitializing = false;
-
- /**
- * Create a helper object to create, open, and/or manage a database.
- * The database is not actually created or opened until one of
- * {@link #getWritableDatabase} or {@link #getReadableDatabase} is called.
- *
- * @param context to use to open or create the database
- * @param name of the database file, or null for an in-memory database
- * @param factory to use for creating cursor objects, or null for the default
- * @param version number of the database (starting at 1); if the database is older,
- * {@link #onUpgrade} will be used to upgrade the database
- */
- public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version) {
- if (version < 1) throw new IllegalArgumentException("Version must be >= 1, was " + version);
-
- mContext = context;
- mName = name;
- mFactory = factory;
- mNewVersion = version;
- }
-
- /**
- * Create and/or open a database that will be used for reading and writing.
- * Once opened successfully, the database is cached, so you can call this
- * method every time you need to write to the database. Make sure to call
- * {@link #close} when you no longer need it.
- *
- * <p>Errors such as bad permissions or a full disk may cause this operation
- * to fail, but future attempts may succeed if the problem is fixed.</p>
- *
- * @throws SQLiteException if the database cannot be opened for writing
- * @return a read/write database object valid until {@link #close} is called
- */
- public synchronized SQLiteDatabase getWritableDatabase() {
- if (mDatabase != null && mDatabase.isOpen() && !mDatabase.isReadOnly()) {
- return mDatabase; // The database is already open for business
- }
-
- if (mIsInitializing) {
- throw new IllegalStateException("getWritableDatabase called recursively");
- }
-
- // If we have a read-only database open, someone could be using it
- // (though they shouldn't), which would cause a lock to be held on
- // the file, and our attempts to open the database read-write would
- // fail waiting for the file lock. To prevent that, we acquire the
- // lock on the read-only database, which shuts out other users.
-
- boolean success = false;
- SQLiteDatabase db = null;
- if (mDatabase != null) mDatabase.lock();
- try {
- mIsInitializing = true;
- if (mName == null) {
- db = SQLiteDatabase.create(null);
- } else {
- db = mContext.openOrCreateDatabase(mName, 0, mFactory);
- }
-
- int version = db.getVersion();
- if (version != mNewVersion) {
- db.beginTransaction();
- try {
- if (version == 0) {
- onCreate(db);
- } else {
- onUpgrade(db, version, mNewVersion);
- }
- db.setVersion(mNewVersion);
- db.setTransactionSuccessful();
- } finally {
- db.endTransaction();
- }
- }
-
- onOpen(db);
- success = true;
- return db;
- } finally {
- mIsInitializing = false;
- if (success) {
- if (mDatabase != null) {
- try { mDatabase.close(); } catch (Exception e) { }
- mDatabase.unlock();
- }
- mDatabase = db;
- } else {
- if (mDatabase != null) mDatabase.unlock();
- if (db != null) db.close();
- }
- }
- }
-
- /**
- * Create and/or open a database. This will be the same object returned by
- * {@link #getWritableDatabase} unless some problem, such as a full disk,
- * requires the database to be opened read-only. In that case, a read-only
- * database object will be returned. If the problem is fixed, a future call
- * to {@link #getWritableDatabase} may succeed, in which case the read-only
- * database object will be closed and the read/write object will be returned
- * in the future.
- *
- * @throws SQLiteException if the database cannot be opened
- * @return a database object valid until {@link #getWritableDatabase}
- * or {@link #close} is called.
- */
- public synchronized SQLiteDatabase getReadableDatabase() {
- if (mDatabase != null && mDatabase.isOpen()) {
- return mDatabase; // The database is already open for business
- }
-
- if (mIsInitializing) {
- throw new IllegalStateException("getReadableDatabase called recursively");
- }
-
- try {
- return getWritableDatabase();
- } catch (SQLiteException e) {
- if (mName == null) throw e; // Can't open a temp database read-only!
- Log.e(TAG, "Couldn't open " + mName + " for writing (will try read-only):", e);
- }
-
- SQLiteDatabase db = null;
- try {
- mIsInitializing = true;
- String path = mContext.getDatabasePath(mName).getPath();
- db = SQLiteDatabase.openDatabase(path, mFactory, SQLiteDatabase.OPEN_READONLY);
- if (db.getVersion() != mNewVersion) {
- throw new SQLiteException("Can't upgrade read-only database from version " +
- db.getVersion() + " to " + mNewVersion + ": " + path);
- }
-
- onOpen(db);
- Log.w(TAG, "Opened " + mName + " in read-only mode");
- mDatabase = db;
- return mDatabase;
- } finally {
- mIsInitializing = false;
- if (db != null && db != mDatabase) db.close();
- }
- }
-
- /**
- * Close any open database object.
- */
- public synchronized void close() {
- if (mIsInitializing) throw new IllegalStateException("Closed during initialization");
-
- if (mDatabase != null && mDatabase.isOpen()) {
- mDatabase.close();
- mDatabase = null;
- }
- }
-
- /**
- * Called when the database is created for the first time. This is where the
- * creation of tables and the initial population of the tables should happen.
- *
- * @param db The database.
- */
- public abstract void onCreate(SQLiteDatabase db);
-
- /**
- * Called when the database needs to be upgraded. The implementation
- * should use this method to drop tables, add tables, or do anything else it
- * needs to upgrade to the new schema version.
- *
- * <p>The SQLite ALTER TABLE documentation can be found
- * <a href="http://sqlite.org/lang_altertable.html">here</a>. If you add new columns
- * you can use ALTER TABLE to insert them into a live table. If you rename or remove columns
- * you can use ALTER TABLE to rename the old table, then create the new table and then
- * populate the new table with the contents of the old table.
- *
- * @param db The database.
- * @param oldVersion The old database version.
- * @param newVersion The new database version.
- */
- public abstract void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion);
-
- /**
- * Called when the database has been opened.
- * Override method should check {@link SQLiteDatabase#isReadOnly} before
- * updating the database.
- *
- * @param db The database.
- */
- public void onOpen(SQLiteDatabase db) {}
-}
diff --git a/core/java/android/database/sqlite/SQLiteProgram.java b/core/java/android/database/sqlite/SQLiteProgram.java
deleted file mode 100644
index f89c87d..0000000
--- a/core/java/android/database/sqlite/SQLiteProgram.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database.sqlite;
-
-import android.util.Log;
-
-/**
- * A base class for compiled SQLite programs.
- */
-public abstract class SQLiteProgram extends SQLiteClosable {
- static final String TAG = "SQLiteProgram";
-
- /** The database this program is compiled against. */
- protected SQLiteDatabase mDatabase;
-
- /**
- * Native linkage, do not modify. This comes from the database and should not be modified
- * in here or in the native code.
- */
- protected int nHandle = 0;
-
- /**
- * Native linkage, do not modify. When non-0 this holds a reference to a valid
- * sqlite3_statement object. It is only updated by the native code, but may be
- * checked in this class when the database lock is held to determine if there
- * is a valid native-side program or not.
- */
- protected int nStatement = 0;
-
- /**
- * Used to find out where a cursor was allocated in case it never got
- * released.
- */
- private StackTraceElement[] mStackTraceElements;
-
- /* package */ SQLiteProgram(SQLiteDatabase db, String sql) {
- if (SQLiteDebug.DEBUG_SQL_STATEMENTS) {
- mStackTraceElements = new Exception().getStackTrace();
- }
-
- mDatabase = db;
- db.acquireReference();
- db.addSQLiteClosable(this);
- this.nHandle = db.mNativeHandle;
- compile(sql, false);
- }
-
- @Override
- protected void onAllReferencesReleased() {
- // Note that native_finalize() checks to make sure that nStatement is
- // non-null before destroying it.
- native_finalize();
- mDatabase.releaseReference();
- mDatabase.removeSQLiteClosable(this);
- }
-
- @Override
- protected void onAllReferencesReleasedFromContainer(){
- // Note that native_finalize() checks to make sure that nStatement is
- // non-null before destroying it.
- native_finalize();
- mDatabase.releaseReference();
- }
-
- /**
- * Returns a unique identifier for this program.
- *
- * @return a unique identifier for this program
- */
- public final int getUniqueId() {
- return nStatement;
- }
-
- /**
- * Compiles the given SQL into a SQLite byte code program using sqlite3_prepare_v2(). If
- * this method has been called previously without a call to close and forCompilation is set
- * to false the previous compilation will be used. Setting forceCompilation to true will
- * always re-compile the program and should be done if you pass differing SQL strings to this
- * method.
- *
- * <P>Note: this method acquires the database lock.</P>
- *
- * @param sql the SQL string to compile
- * @param forceCompilation forces the SQL to be recompiled in the event that there is an
- * existing compiled SQL program already around
- */
- protected void compile(String sql, boolean forceCompilation) {
- // Only compile if we don't have a valid statement already or the caller has
- // explicitly requested a recompile.
- if (nStatement == 0 || forceCompilation) {
- mDatabase.lock();
- try {
- // Note that the native_compile() takes care of destroying any previously
- // existing programs before it compiles.
- acquireReference();
- native_compile(sql);
- } finally {
- releaseReference();
- mDatabase.unlock();
- }
- }
- }
-
- /**
- * Bind a NULL value to this statement. The value remains bound until
- * {@link #clearBindings} is called.
- *
- * @param index The 1-based index to the parameter to bind null to
- */
- public void bindNull(int index) {
- acquireReference();
- try {
- native_bind_null(index);
- } finally {
- releaseReference();
- }
- }
-
- /**
- * Bind a long value to this statement. The value remains bound until
- * {@link #clearBindings} is called.
- *
- * @param index The 1-based index to the parameter to bind
- * @param value The value to bind
- */
- public void bindLong(int index, long value) {
- acquireReference();
- try {
- native_bind_long(index, value);
- } finally {
- releaseReference();
- }
- }
-
- /**
- * Bind a double value to this statement. The value remains bound until
- * {@link #clearBindings} is called.
- *
- * @param index The 1-based index to the parameter to bind
- * @param value The value to bind
- */
- public void bindDouble(int index, double value) {
- acquireReference();
- try {
- native_bind_double(index, value);
- } finally {
- releaseReference();
- }
- }
-
- /**
- * Bind a String value to this statement. The value remains bound until
- * {@link #clearBindings} is called.
- *
- * @param index The 1-based index to the parameter to bind
- * @param value The value to bind
- */
- public void bindString(int index, String value) {
- if (value == null) {
- throw new IllegalArgumentException("the bind value at index " + index + " is null");
- }
- acquireReference();
- try {
- native_bind_string(index, value);
- } finally {
- releaseReference();
- }
- }
-
- /**
- * Bind a byte array value to this statement. The value remains bound until
- * {@link #clearBindings} is called.
- *
- * @param index The 1-based index to the parameter to bind
- * @param value The value to bind
- */
- public void bindBlob(int index, byte[] value) {
- if (value == null) {
- throw new IllegalArgumentException("the bind value at index " + index + " is null");
- }
- acquireReference();
- try {
- native_bind_blob(index, value);
- } finally {
- releaseReference();
- }
- }
-
- /**
- * Clears all existing bindings. Unset bindings are treated as NULL.
- */
- public void clearBindings() {
- acquireReference();
- try {
- native_clear_bindings();
- } finally {
- releaseReference();
- }
- }
-
- /**
- * Release this program's resources, making it invalid.
- */
- public void close() {
- mDatabase.lock();
- try {
- releaseReference();
- } finally {
- mDatabase.unlock();
- }
- }
-
- /**
- * Make sure that the native resource is cleaned up.
- */
- @Override
- protected void finalize() {
- if (nStatement != 0) {
- if (SQLiteDebug.DEBUG_SQL_STATEMENTS) {
- String message = "Finalizing " + this +
- " that has not been closed";
-
- Log.d(TAG, message + "\nThis cursor was created in:");
- for (StackTraceElement ste : mStackTraceElements) {
- Log.d(TAG, " " + ste);
- }
- }
- // when in finalize() it is already removed from weakhashmap
- // so it is safe to not removed itself from db
- onAllReferencesReleasedFromContainer();
- }
- }
-
- /**
- * Compiles SQL into a SQLite program.
- *
- * <P>The database lock must be held when calling this method.
- * @param sql The SQL to compile.
- */
- protected final native void native_compile(String sql);
- protected final native void native_finalize();
-
- protected final native void native_bind_null(int index);
- protected final native void native_bind_long(int index, long value);
- protected final native void native_bind_double(int index, double value);
- protected final native void native_bind_string(int index, String value);
- protected final native void native_bind_blob(int index, byte[] value);
- private final native void native_clear_bindings();
-}
-
diff --git a/core/java/android/database/sqlite/SQLiteQuery.java b/core/java/android/database/sqlite/SQLiteQuery.java
deleted file mode 100644
index 5bfa0e8..0000000
--- a/core/java/android/database/sqlite/SQLiteQuery.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database.sqlite;
-
-import android.database.CursorWindow;
-import android.os.SystemClock;
-
-/**
- * A SQLite program that represents a query that reads the resulting rows into a CursorWindow.
- * This class is used by SQLiteCursor and isn't useful itself.
- */
-public class SQLiteQuery extends SQLiteProgram {
- //private static final String TAG = "Cursor";
-
- /** The index of the unbound OFFSET parameter */
- private int mOffsetIndex;
-
- /** The SQL used to create this query */
- private String mQuery;
-
- /** Args to bind on requery */
- private String[] mBindArgs;
-
- private boolean mClosed = false;
-
- /**
- * Create a persistent query object.
- *
- * @param db The database that this query object is associated with
- * @param query The SQL string for this query.
- * @param offsetIndex The 1-based index to the OFFSET parameter,
- */
- /* package */ SQLiteQuery(SQLiteDatabase db, String query, int offsetIndex, String[] bindArgs) {
- super(db, query);
-
- mOffsetIndex = offsetIndex;
- mQuery = query;
- mBindArgs = bindArgs;
- }
-
- /**
- * Reads rows into a buffer. This method acquires the database lock.
- *
- * @param window The window to fill into
- * @return number of total rows in the query
- */
- /* package */ int fillWindow(CursorWindow window,
- int maxRead, int lastPos) {
- mDatabase.lock();
-
- boolean logStats = mDatabase.mLogStats;
- long startTime = logStats ? SystemClock.elapsedRealtime() : 0;
- try {
- acquireReference();
- try {
- window.acquireReference();
- // if the start pos is not equal to 0, then most likely window is
- // too small for the data set, loading by another thread
- // is not safe in this situation. the native code will ignore maxRead
- int numRows = native_fill_window(window, window.getStartPosition(), mOffsetIndex,
- maxRead, lastPos);
- if (logStats) {
- mDatabase.logTimeStat(true /* read */, startTime,
- SystemClock.elapsedRealtime());
- }
- return numRows;
- } catch (IllegalStateException e){
- // simply ignore it
- return 0;
- } catch (SQLiteDatabaseCorruptException e) {
- mDatabase.onCorruption();
- throw e;
- } finally {
- window.releaseReference();
- }
- } finally {
- releaseReference();
- mDatabase.unlock();
- }
- }
-
- /**
- * Get the column count for the statement. Only valid on query based
- * statements. The database must be locked
- * when calling this method.
- *
- * @return The number of column in the statement's result set.
- */
- /* package */ int columnCountLocked() {
- acquireReference();
- try {
- return native_column_count();
- } finally {
- releaseReference();
- }
- }
-
- /**
- * Retrieves the column name for the given column index. The database must be locked
- * when calling this method.
- *
- * @param columnIndex the index of the column to get the name for
- * @return The requested column's name
- */
- /* package */ String columnNameLocked(int columnIndex) {
- acquireReference();
- try {
- return native_column_name(columnIndex);
- } finally {
- releaseReference();
- }
- }
-
- /** {@hide pending API Council approval} */
- @Override
- public String toString() {
- return "SQLiteQuery: " + mQuery;
- }
-
- @Override
- public void close() {
- super.close();
- mClosed = true;
- }
-
- /**
- * Called by SQLiteCursor when it is requeried.
- */
- /* package */ void requery() {
- if (mBindArgs != null) {
- int len = mBindArgs.length;
- try {
- for (int i = 0; i < len; i++) {
- super.bindString(i + 1, mBindArgs[i]);
- }
- } catch (SQLiteMisuseException e) {
- StringBuilder errMsg = new StringBuilder("mQuery " + mQuery);
- for (int i = 0; i < len; i++) {
- errMsg.append(" ");
- errMsg.append(mBindArgs[i]);
- }
- errMsg.append(" ");
- IllegalStateException leakProgram = new IllegalStateException(
- errMsg.toString(), e);
- throw leakProgram;
- }
- }
- }
-
- @Override
- public void bindNull(int index) {
- mBindArgs[index - 1] = null;
- if (!mClosed) super.bindNull(index);
- }
-
- @Override
- public void bindLong(int index, long value) {
- mBindArgs[index - 1] = Long.toString(value);
- if (!mClosed) super.bindLong(index, value);
- }
-
- @Override
- public void bindDouble(int index, double value) {
- mBindArgs[index - 1] = Double.toString(value);
- if (!mClosed) super.bindDouble(index, value);
- }
-
- @Override
- public void bindString(int index, String value) {
- mBindArgs[index - 1] = value;
- if (!mClosed) super.bindString(index, value);
- }
-
- private final native int native_fill_window(CursorWindow window,
- int startPos, int offsetParam, int maxRead, int lastPos);
-
- private final native int native_column_count();
-
- private final native String native_column_name(int columnIndex);
-}
diff --git a/core/java/android/database/sqlite/SQLiteQueryBuilder.java b/core/java/android/database/sqlite/SQLiteQueryBuilder.java
deleted file mode 100644
index 519a81c..0000000
--- a/core/java/android/database/sqlite/SQLiteQueryBuilder.java
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
- * 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database.sqlite;
-
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.database.sqlite.SQLiteDatabase;
-import android.provider.BaseColumns;
-import android.text.TextUtils;
-import android.util.Config;
-import android.util.Log;
-
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.Map.Entry;
-
-/**
- * This is a convience class that helps build SQL queries to be sent to
- * {@link SQLiteDatabase} objects.
- */
-public class SQLiteQueryBuilder
-{
- private static final String TAG = "SQLiteQueryBuilder";
-
- private Map<String, String> mProjectionMap = null;
- private String mTables = "";
- private StringBuilder mWhereClause = new StringBuilder(64);
- private boolean mDistinct;
- private SQLiteDatabase.CursorFactory mFactory;
-
- public SQLiteQueryBuilder() {
- mDistinct = false;
- mFactory = null;
- }
-
- /**
- * Mark the query as DISTINCT.
- *
- * @param distinct if true the query is DISTINCT, otherwise it isn't
- */
- public void setDistinct(boolean distinct) {
- mDistinct = distinct;
- }
-
- /**
- * Returns the list of tables being queried
- *
- * @return the list of tables being queried
- */
- public String getTables() {
- return mTables;
- }
-
- /**
- * Sets the list of tables to query. Multiple tables can be specified to perform a join.
- * For example:
- * setTables("foo, bar")
- * setTables("foo LEFT OUTER JOIN bar ON (foo.id = bar.foo_id)")
- *
- * @param inTables the list of tables to query on
- */
- public void setTables(String inTables) {
- mTables = inTables;
- }
-
- /**
- * Append a chunk to the WHERE clause of the query. All chunks appended are surrounded
- * by parenthesis and ANDed with the selection passed to {@link #query}. The final
- * WHERE clause looks like:
- *
- * WHERE (&lt;append chunk 1>&lt;append chunk2>) AND (&lt;query() selection parameter>)
- *
- * @param inWhere the chunk of text to append to the WHERE clause.
- */
- public void appendWhere(CharSequence inWhere) {
- if (mWhereClause.length() == 0) {
- mWhereClause.append('(');
- }
- mWhereClause.append(inWhere);
- }
-
- /**
- * Append a chunk to the WHERE clause of the query. All chunks appended are surrounded
- * by parenthesis and ANDed with the selection passed to {@link #query}. The final
- * WHERE clause looks like:
- *
- * WHERE (&lt;append chunk 1>&lt;append chunk2>) AND (&lt;query() selection parameter>)
- *
- * @param inWhere the chunk of text to append to the WHERE clause. it will be escaped
- * to avoid SQL injection attacks
- */
- public void appendWhereEscapeString(String inWhere) {
- if (mWhereClause.length() == 0) {
- mWhereClause.append('(');
- }
- DatabaseUtils.appendEscapedSQLString(mWhereClause, inWhere);
- }
-
- /**
- * Sets the projection map for the query. The projection map maps
- * from column names that the caller passes into query to database
- * column names. This is useful for renaming columns as well as
- * disambiguating column names when doing joins. For example you
- * could map "name" to "people.name". If a projection map is set
- * it must contain all column names the user may request, even if
- * the key and value are the same.
- *
- * @param columnMap maps from the user column names to the database column names
- */
- public void setProjectionMap(Map<String, String> columnMap) {
- mProjectionMap = columnMap;
- }
-
- /**
- * Sets the cursor factory to be used for the query. You can use
- * one factory for all queries on a database but it is normally
- * easier to specify the factory when doing this query. @param
- * factory the factor to use
- */
- public void setCursorFactory(SQLiteDatabase.CursorFactory factory) {
- mFactory = factory;
- }
-
- /**
- * Build an SQL query string from the given clauses.
- *
- * @param distinct true if you want each row to be unique, false otherwise.
- * @param tables The table names to compile the query against.
- * @param columns A list of which columns to return. Passing null will
- * return all columns, which is discouraged to prevent reading
- * data from storage that isn't going to be used.
- * @param where A filter declaring which rows to return, formatted as an SQL
- * WHERE clause (excluding the WHERE itself). Passing null will
- * return all rows for the given URL.
- * @param groupBy A filter declaring how to group rows, formatted as an SQL
- * GROUP BY clause (excluding the GROUP BY itself). Passing null
- * will cause the rows to not be grouped.
- * @param having A filter declare which row groups to include in the cursor,
- * if row grouping is being used, formatted as an SQL HAVING
- * clause (excluding the HAVING itself). Passing null will cause
- * all row groups to be included, and is required when row
- * grouping is not being used.
- * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
- * (excluding the ORDER BY itself). Passing null will use the
- * default sort order, which may be unordered.
- * @param limit Limits the number of rows returned by the query,
- * formatted as LIMIT clause. Passing null denotes no LIMIT clause.
- * @return the SQL query string
- */
- public static String buildQueryString(
- boolean distinct, String tables, String[] columns, String where,
- String groupBy, String having, String orderBy, String limit) {
- if (TextUtils.isEmpty(groupBy) && !TextUtils.isEmpty(having)) {
- throw new IllegalArgumentException(
- "HAVING clauses are only permitted when using a groupBy clause");
- }
-
- StringBuilder query = new StringBuilder(120);
-
- query.append("SELECT ");
- if (distinct) {
- query.append("DISTINCT ");
- }
- if (columns != null && columns.length != 0) {
- appendColumns(query, columns);
- } else {
- query.append("* ");
- }
- query.append("FROM ");
- query.append(tables);
- appendClause(query, " WHERE ", where);
- appendClause(query, " GROUP BY ", groupBy);
- appendClause(query, " HAVING ", having);
- appendClause(query, " ORDER BY ", orderBy);
- appendClauseEscapeClause(query, " LIMIT ", limit);
-
- return query.toString();
- }
-
- private static void appendClause(StringBuilder s, String name, String clause) {
- if (!TextUtils.isEmpty(clause)) {
- s.append(name);
- s.append(clause);
- }
- }
-
- private static void appendClauseEscapeClause(StringBuilder s, String name, String clause) {
- if (!TextUtils.isEmpty(clause)) {
- s.append(name);
- DatabaseUtils.appendEscapedSQLString(s, clause);
- }
- }
-
- /**
- * Add the names that are non-null in columns to s, separating
- * them with commas.
- */
- public static void appendColumns(StringBuilder s, String[] columns) {
- int n = columns.length;
-
- for (int i = 0; i < n; i++) {
- String column = columns[i];
-
- if (column != null) {
- if (i > 0) {
- s.append(", ");
- }
- s.append(column);
- }
- }
- s.append(' ');
- }
-
- /**
- * Perform a query by combining all current settings and the
- * information passed into this method.
- *
- * @param db the database to query on
- * @param projectionIn A list of which columns to return. Passing
- * null will return all columns, which is discouraged to prevent
- * reading data from storage that isn't going to be used.
- * @param selection A filter declaring which rows to return,
- * formatted as an SQL WHERE clause (excluding the WHERE
- * itself). Passing null will return all rows for the given URL.
- * @param selectionArgs You may include ?s in selection, which
- * will be replaced by the values from selectionArgs, in order
- * that they appear in the selection. The values will be bound
- * as Strings.
- * @param groupBy A filter declaring how to group rows, formatted
- * as an SQL GROUP BY clause (excluding the GROUP BY
- * itself). Passing null will cause the rows to not be grouped.
- * @param having A filter declare which row groups to include in
- * the cursor, if row grouping is being used, formatted as an
- * SQL HAVING clause (excluding the HAVING itself). Passing
- * null will cause all row groups to be included, and is
- * required when row grouping is not being used.
- * @param sortOrder How to order the rows, formatted as an SQL
- * ORDER BY clause (excluding the ORDER BY itself). Passing null
- * will use the default sort order, which may be unordered.
- * @return a cursor over the result set
- * @see android.content.ContentResolver#query(android.net.Uri, String[],
- * String, String[], String)
- */
- public Cursor query(SQLiteDatabase db, String[] projectionIn,
- String selection, String[] selectionArgs, String groupBy,
- String having, String sortOrder) {
- return query(db, projectionIn, selection, selectionArgs, groupBy, having, sortOrder,
- null /* limit */);
- }
-
- /**
- * Perform a query by combining all current settings and the
- * information passed into this method.
- *
- * @param db the database to query on
- * @param projectionIn A list of which columns to return. Passing
- * null will return all columns, which is discouraged to prevent
- * reading data from storage that isn't going to be used.
- * @param selection A filter declaring which rows to return,
- * formatted as an SQL WHERE clause (excluding the WHERE
- * itself). Passing null will return all rows for the given URL.
- * @param selectionArgs You may include ?s in selection, which
- * will be replaced by the values from selectionArgs, in order
- * that they appear in the selection. The values will be bound
- * as Strings.
- * @param groupBy A filter declaring how to group rows, formatted
- * as an SQL GROUP BY clause (excluding the GROUP BY
- * itself). Passing null will cause the rows to not be grouped.
- * @param having A filter declare which row groups to include in
- * the cursor, if row grouping is being used, formatted as an
- * SQL HAVING clause (excluding the HAVING itself). Passing
- * null will cause all row groups to be included, and is
- * required when row grouping is not being used.
- * @param sortOrder How to order the rows, formatted as an SQL
- * ORDER BY clause (excluding the ORDER BY itself). Passing null
- * will use the default sort order, which may be unordered.
- * @param limit Limits the number of rows returned by the query,
- * formatted as LIMIT clause. Passing null denotes no LIMIT clause.
- * @return a cursor over the result set
- * @see android.content.ContentResolver#query(android.net.Uri, String[],
- * String, String[], String)
- */
- public Cursor query(SQLiteDatabase db, String[] projectionIn,
- String selection, String[] selectionArgs, String groupBy,
- String having, String sortOrder, String limit) {
- if (mTables == null) {
- return null;
- }
-
- String sql = buildQuery(
- projectionIn, selection, selectionArgs, groupBy, having,
- sortOrder, limit);
-
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "Performing query: " + sql);
- }
- return db.rawQueryWithFactory(
- mFactory, sql, selectionArgs,
- SQLiteDatabase.findEditTable(mTables));
- }
-
- /**
- * Construct a SELECT statement suitable for use in a group of
- * SELECT statements that will be joined through UNION operators
- * in buildUnionQuery.
- *
- * @param projectionIn A list of which columns to return. Passing
- * null will return all columns, which is discouraged to
- * prevent reading data from storage that isn't going to be
- * used.
- * @param selection A filter declaring which rows to return,
- * formatted as an SQL WHERE clause (excluding the WHERE
- * itself). Passing null will return all rows for the given
- * URL.
- * @param selectionArgs You may include ?s in selection, which
- * will be replaced by the values from selectionArgs, in order
- * that they appear in the selection. The values will be bound
- * as Strings.
- * @param groupBy A filter declaring how to group rows, formatted
- * as an SQL GROUP BY clause (excluding the GROUP BY itself).
- * Passing null will cause the rows to not be grouped.
- * @param having A filter declare which row groups to include in
- * the cursor, if row grouping is being used, formatted as an
- * SQL HAVING clause (excluding the HAVING itself). Passing
- * null will cause all row groups to be included, and is
- * required when row grouping is not being used.
- * @param sortOrder How to order the rows, formatted as an SQL
- * ORDER BY clause (excluding the ORDER BY itself). Passing null
- * will use the default sort order, which may be unordered.
- * @param limit Limits the number of rows returned by the query,
- * formatted as LIMIT clause. Passing null denotes no LIMIT clause.
- * @return the resulting SQL SELECT statement
- */
- public String buildQuery(
- String[] projectionIn, String selection, String[] selectionArgs,
- String groupBy, String having, String sortOrder, String limit) {
- String[] projection = computeProjection(projectionIn);
-
- if (mWhereClause.length() > 0) {
- mWhereClause.append(')');
- }
-
- // Tack on the user's selection, if present.
- if (selection != null && selection.length() > 0) {
- if (mWhereClause.length() > 0) {
- mWhereClause.append(" AND ");
- }
-
- mWhereClause.append('(');
- mWhereClause.append(selection);
- mWhereClause.append(')');
- }
-
- return buildQueryString(
- mDistinct, mTables, projection, mWhereClause.toString(),
- groupBy, having, sortOrder, limit);
- }
-
- /**
- * Construct a SELECT statement suitable for use in a group of
- * SELECT statements that will be joined through UNION operators
- * in buildUnionQuery.
- *
- * @param typeDiscriminatorColumn the name of the result column
- * whose cells will contain the name of the table from which
- * each row was drawn.
- * @param unionColumns the names of the columns to appear in the
- * result. This may include columns that do not appear in the
- * table this SELECT is querying (i.e. mTables), but that do
- * appear in one of the other tables in the UNION query that we
- * are constructing.
- * @param columnsPresentInTable a Set of the names of the columns
- * that appear in this table (i.e. in the table whose name is
- * mTables). Since columns in unionColumns include columns that
- * appear only in other tables, we use this array to distinguish
- * which ones actually are present. Other columns will have
- * NULL values for results from this subquery.
- * @param computedColumnsOffset all columns in unionColumns before
- * this index are included under the assumption that they're
- * computed and therefore won't appear in columnsPresentInTable,
- * e.g. "date * 1000 as normalized_date"
- * @param typeDiscriminatorValue the value used for the
- * type-discriminator column in this subquery
- * @param selection A filter declaring which rows to return,
- * formatted as an SQL WHERE clause (excluding the WHERE
- * itself). Passing null will return all rows for the given
- * URL.
- * @param selectionArgs You may include ?s in selection, which
- * will be replaced by the values from selectionArgs, in order
- * that they appear in the selection. The values will be bound
- * as Strings.
- * @param groupBy A filter declaring how to group rows, formatted
- * as an SQL GROUP BY clause (excluding the GROUP BY itself).
- * Passing null will cause the rows to not be grouped.
- * @param having A filter declare which row groups to include in
- * the cursor, if row grouping is being used, formatted as an
- * SQL HAVING clause (excluding the HAVING itself). Passing
- * null will cause all row groups to be included, and is
- * required when row grouping is not being used.
- * @return the resulting SQL SELECT statement
- */
- public String buildUnionSubQuery(
- String typeDiscriminatorColumn,
- String[] unionColumns,
- Set<String> columnsPresentInTable,
- int computedColumnsOffset,
- String typeDiscriminatorValue,
- String selection,
- String[] selectionArgs,
- String groupBy,
- String having) {
- int unionColumnsCount = unionColumns.length;
- String[] projectionIn = new String[unionColumnsCount];
-
- for (int i = 0; i < unionColumnsCount; i++) {
- String unionColumn = unionColumns[i];
-
- if (unionColumn.equals(typeDiscriminatorColumn)) {
- projectionIn[i] = "'" + typeDiscriminatorValue + "' AS "
- + typeDiscriminatorColumn;
- } else if (i <= computedColumnsOffset
- || columnsPresentInTable.contains(unionColumn)) {
- projectionIn[i] = unionColumn;
- } else {
- projectionIn[i] = "NULL AS " + unionColumn;
- }
- }
- return buildQuery(
- projectionIn, selection, selectionArgs, groupBy, having,
- null /* sortOrder */,
- null /* limit */);
- }
-
- /**
- * Given a set of subqueries, all of which are SELECT statements,
- * construct a query that returns the union of what those
- * subqueries return.
- * @param subQueries an array of SQL SELECT statements, all of
- * which must have the same columns as the same positions in
- * their results
- * @param sortOrder How to order the rows, formatted as an SQL
- * ORDER BY clause (excluding the ORDER BY itself). Passing
- * null will use the default sort order, which may be unordered.
- * @param limit The limit clause, which applies to the entire union result set
- *
- * @return the resulting SQL SELECT statement
- */
- public String buildUnionQuery(String[] subQueries, String sortOrder, String limit) {
- StringBuilder query = new StringBuilder(128);
- int subQueryCount = subQueries.length;
- String unionOperator = mDistinct ? " UNION " : " UNION ALL ";
-
- for (int i = 0; i < subQueryCount; i++) {
- if (i > 0) {
- query.append(unionOperator);
- }
- query.append(subQueries[i]);
- }
- appendClause(query, " ORDER BY ", sortOrder);
- appendClause(query, " LIMIT ", limit);
- return query.toString();
- }
-
- private String[] computeProjection(String[] projectionIn) {
- if (projectionIn != null && projectionIn.length > 0) {
- if (mProjectionMap != null) {
- String[] projection = new String[projectionIn.length];
- int length = projectionIn.length;
-
- for (int i = 0; i < length; i++) {
- String userColumn = projectionIn[i];
- String column = mProjectionMap.get(userColumn);
-
- if (column == null) {
- throw new IllegalArgumentException(
- "Invalid column " + projectionIn[i]);
- } else {
- projection[i] = column;
- }
- }
- return projection;
- } else {
- return projectionIn;
- }
- } else if (mProjectionMap != null) {
- // Return all columns in projection map.
- Set<Entry<String, String>> entrySet = mProjectionMap.entrySet();
- String[] projection = new String[entrySet.size()];
- Iterator<Entry<String, String>> entryIter = entrySet.iterator();
- int i = 0;
-
- while (entryIter.hasNext()) {
- Entry<String, String> entry = entryIter.next();
-
- // Don't include the _count column when people ask for no projection.
- if (entry.getKey().equals(BaseColumns._COUNT)) {
- continue;
- }
- projection[i++] = entry.getValue();
- }
- return projection;
- }
- return null;
- }
-}
diff --git a/core/java/android/database/sqlite/SQLiteStatement.java b/core/java/android/database/sqlite/SQLiteStatement.java
deleted file mode 100644
index d169259..0000000
--- a/core/java/android/database/sqlite/SQLiteStatement.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * 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
- *
- * 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
- * limitations under the License.
- */
-
-package android.database.sqlite;
-
-import android.os.SystemClock;
-
-/**
- * A pre-compiled statement against a {@link SQLiteDatabase} that can be reused.
- * The statement cannot return multiple rows, but 1x1 result sets are allowed.
- * Don't use SQLiteStatement constructor directly, please use
- * {@link SQLiteDatabase#compileStatement(String)}
- */
-public class SQLiteStatement extends SQLiteProgram
-{
- /**
- * Don't use SQLiteStatement constructor directly, please use
- * {@link SQLiteDatabase#compileStatement(String)}
- * @param db
- * @param sql
- */
- /* package */ SQLiteStatement(SQLiteDatabase db, String sql) {
- super(db, sql);
- }
-
- /**
- * Execute this SQL statement, if it is not a query. For example,
- * CREATE TABLE, DELTE, INSERT, etc.
- *
- * @throws android.database.SQLException If the SQL string is invalid for
- * some reason
- */
- public void execute() {
- mDatabase.lock();
- boolean logStats = mDatabase.mLogStats;
- long startTime = logStats ? SystemClock.elapsedRealtime() : 0;
-
- acquireReference();
- try {
- native_execute();
- if (logStats) {
- mDatabase.logTimeStat(false /* write */, startTime, SystemClock.elapsedRealtime());
- }
- } finally {
- releaseReference();
- mDatabase.unlock();
- }
- }
-
- /**
- * Execute this SQL statement and return the ID of the most
- * recently inserted row. The SQL statement should probably be an
- * INSERT for this to be a useful call.
- *
- * @return the row ID of the last row inserted.
- *
- * @throws android.database.SQLException If the SQL string is invalid for
- * some reason
- */
- public long executeInsert() {
- mDatabase.lock();
- boolean logStats = mDatabase.mLogStats;
- long startTime = logStats ? SystemClock.elapsedRealtime() : 0;
-
- acquireReference();
- try {
- native_execute();
- if (logStats) {
- mDatabase.logTimeStat(false /* write */, startTime, SystemClock.elapsedRealtime());
- }
- return mDatabase.lastInsertRow();
- } finally {
- releaseReference();
- mDatabase.unlock();
- }
- }
-
- /**
- * Execute a statement that returns a 1 by 1 table with a numeric value.
- * For example, SELECT COUNT(*) FROM table;
- *
- * @return The result of the query.
- *
- * @throws android.database.sqlite.SQLiteDoneException if the query returns zero rows
- */
- public long simpleQueryForLong() {
- mDatabase.lock();
- boolean logStats = mDatabase.mLogStats;
- long startTime = logStats ? SystemClock.elapsedRealtime() : 0;
-
- acquireReference();
- try {
- long retValue = native_1x1_long();
- if (logStats) {
- mDatabase.logTimeStat(false /* write */, startTime, SystemClock.elapsedRealtime());
- }
- return retValue;
- } finally {
- releaseReference();
- mDatabase.unlock();
- }
- }
-
- /**
- * Execute a statement that returns a 1 by 1 table with a text value.
- * For example, SELECT COUNT(*) FROM table;
- *
- * @return The result of the query.
- *
- * @throws android.database.sqlite.SQLiteDoneException if the query returns zero rows
- */
- public String simpleQueryForString() {
- mDatabase.lock();
- boolean logStats = mDatabase.mLogStats;
- long startTime = logStats ? SystemClock.elapsedRealtime() : 0;
-
- acquireReference();
- try {
- String retValue = native_1x1_string();
- if (logStats) {
- mDatabase.logTimeStat(false /* write */, startTime, SystemClock.elapsedRealtime());
- }
- return retValue;
- } finally {
- releaseReference();
- mDatabase.unlock();
- }
- }
-
- private final native void native_execute();
- private final native long native_1x1_long();
- private final native String native_1x1_string();
-}
diff --git a/core/java/android/database/sqlite/package.html b/core/java/android/database/sqlite/package.html
deleted file mode 100644
index ff0f9f5..0000000
--- a/core/java/android/database/sqlite/package.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<HTML>
-<BODY>
-Contains the SQLite database management
-classes that an application would use to manage its own private database.
-<p>
-Applications use these classes to maange private databases. If creating a
-content provider, you will probably have to use these classes to create and
-manage your own database to store content. See <a
-href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a> to learn
-the conventions for implementing a content provider. See the
-NotePadProvider class in the NotePad sample application in the SDK for an
-example of a content provider. Android ships with SQLite version 3.4.0
-<p>If you are working with data sent to you by a provider, you will not use
-these SQLite classes, but instead use the generic {@link android.database}
-classes.
-<p>Android ships with the sqlite3 database tool in the <code>tools/</code>
-folder. You can use this tool to browse or run SQL commands on the device. Run by
-typing <code>sqlite3</code> in a shell window.
-</BODY>
-</HTML>