Remove the deprecated cursor methods.

Change-Id: Ie3571fea9f36996c31c327240b11086f8cc487f0
This commit is contained in:
Jeff Hamilton
2010-05-12 17:30:27 -05:00
parent 93f8547dcf
commit 7cd51efcbd
14 changed files with 10 additions and 986 deletions

View File

@@ -1579,40 +1579,6 @@ public class Activity extends ContextThemeWrapper
return c;
}
/**
* Wrapper around {@link Cursor#commitUpdates()} that takes care of noting
* that the Cursor needs to be requeried. You can call this method in
* {@link #onPause} or {@link #onStop} to have the system call
* {@link Cursor#requery} for you if the activity is later resumed. This
* allows you to avoid determing when to do the requery yourself (which is
* required for the Cursor to see any data changes that were committed with
* it).
*
* @param c The Cursor whose changes are to be committed.
*
* @see #managedQuery(android.net.Uri , String[], String, String[], String)
* @see #startManagingCursor
* @see Cursor#commitUpdates()
* @see Cursor#requery
* @hide
*/
@Deprecated
public void managedCommitUpdates(Cursor c) {
synchronized (mManagedCursors) {
final int N = mManagedCursors.size();
for (int i=0; i<N; i++) {
ManagedCursor mc = mManagedCursors.get(i);
if (mc.mCursor == c) {
c.commitUpdates();
mc.mUpdated = true;
return;
}
}
throw new RuntimeException(
"Cursor " + c + " is not currently managed");
}
}
/**
* This method allows the activity to take care of managing the given
* {@link Cursor}'s lifecycle for you based on the activity's lifecycle.

View File

@@ -103,22 +103,6 @@ public abstract class AbstractCursor implements CrossProcessCursor {
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
@@ -315,137 +299,6 @@ public abstract class AbstractCursor implements CrossProcessCursor {
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);
}

View File

@@ -17,13 +17,10 @@
package android.database;
import android.os.Binder;
import android.os.RemoteException;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Bundle;
import java.util.HashMap;
import java.util.Map;
import android.os.RemoteException;
/**
* Native implementation of the bulk cursor. This is only for use in implementing
@@ -120,26 +117,6 @@ public abstract class BulkCursorNative extends Binder implements IBulkCursor
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();
@@ -343,48 +320,6 @@ final class BulkCursorProxy implements IBulkCursor {
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();

View File

@@ -16,12 +16,10 @@
package android.database;
import android.os.RemoteException;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;
import java.util.Map;
/**
* Adapts an {@link IBulkCursor} to a {@link Cursor} for use in the local
* process.
@@ -174,38 +172,6 @@ public final class BulkCursorToCursorAdaptor extends AbstractWindowedCursor {
}
}
/**
* @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() {
if (mColumns == null) {
@@ -219,44 +185,6 @@ public final class BulkCursorToCursorAdaptor extends AbstractWindowedCursor {
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 {

View File

@@ -145,22 +145,6 @@ public interface Cursor {
*/
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
@@ -302,188 +286,6 @@ public interface Cursor {
*/
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.

View File

@@ -16,16 +16,12 @@
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.
@@ -38,7 +34,6 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative
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
@@ -98,7 +93,6 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative
"Only CrossProcessCursor cursors are supported across process for now", e);
}
mProviderName = providerName;
mReadOnly = !allowWrite;
createAndRegisterObserverProxy(observer);
}
@@ -197,31 +191,6 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative
}
}
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();
}

View File

@@ -32,14 +32,6 @@ public class CursorWrapper implements Cursor {
public CursorWrapper(Cursor cursor) {
mCursor = cursor;
}
/**
* @hide
* @deprecated
*/
public void abortUpdates() {
mCursor.abortUpdates();
}
public void close() {
mCursor.close();
@@ -49,23 +41,6 @@ public class CursorWrapper implements Cursor {
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();
}
@@ -74,14 +49,6 @@ public class CursorWrapper implements Cursor {
mCursor.deactivate();
}
/**
* @hide
* @deprecated
*/
public boolean deleteRow() {
return mCursor.deleteRow();
}
public boolean moveToFirst() {
return mCursor.moveToFirst();
}
@@ -147,14 +114,6 @@ public class CursorWrapper implements Cursor {
return mCursor.getWantsAllOnMoveCalls();
}
/**
* @hide
* @deprecated
*/
public boolean hasUpdates() {
return mCursor.hasUpdates();
}
public boolean isAfterLast() {
return mCursor.isAfterLast();
}
@@ -219,14 +178,6 @@ public class CursorWrapper implements Cursor {
mCursor.setNotificationUri(cr, uri);
}
/**
* @hide
* @deprecated
*/
public boolean supportsUpdates() {
return mCursor.supportsUpdates();
}
public void unregisterContentObserver(ContentObserver observer) {
mCursor.unregisterContentObserver(observer);
}
@@ -235,71 +186,6 @@ public class CursorWrapper implements Cursor {
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;
private Cursor mCursor;
}

View File

@@ -16,16 +16,14 @@
package android.database;
import android.os.RemoteException;
import android.os.Bundle;
import android.os.IBinder;
import android.os.IInterface;
import android.os.Bundle;
import java.util.Map;
import android.os.RemoteException;
/**
* This interface provides a low-level way to pass bulk cursor data across
* both process and language boundries. Application code should use the Cursor
* both process and language boundaries. Application code should use the Cursor
* interface directly.
*
* {@hide}
@@ -54,10 +52,6 @@ public interface IBulkCursor extends IInterface {
*/
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;
@@ -76,8 +70,6 @@ public interface IBulkCursor extends IInterface {
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;

View File

@@ -92,32 +92,6 @@ public class MergeCursor extends AbstractCursor
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)
{

View File

@@ -21,17 +21,14 @@ import android.database.AbstractWindowedCursor;
import android.database.CursorWindow;
import android.database.DataSetObserver;
import android.database.RequeryOnUiThreadException;
import android.database.SQLException;
import android.os.Handler;
import android.os.Looper;
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;
@@ -328,166 +325,11 @@ public class SQLiteCursor extends AbstractWindowedCursor {
}
}
/**
* @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;

View File

@@ -3532,20 +3532,8 @@ public final class Settings {
// If a shortcut is supplied, and it is already defined for
// another bookmark, then remove the old definition.
if (shortcut != 0) {
Cursor c = cr.query(CONTENT_URI,
sShortcutProjection, sShortcutSelection,
new String[] { String.valueOf((int) shortcut) }, null);
try {
if (c.moveToFirst()) {
while (c.getCount() > 0) {
if (!c.deleteRow()) {
Log.w(TAG, "Could not delete existing shortcut row");
}
}
}
} finally {
if (c != null) c.close();
}
cr.delete(CONTENT_URI, sShortcutSelection,
new String[] { String.valueOf((int) shortcut) });
}
ContentValues values = new ContentValues();

View File

@@ -181,24 +181,6 @@ public class SortCursor extends AbstractCursor
return true;
}
@Override
public boolean deleteRow()
{
return mCursor.deleteRow();
}
@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)
{

View File

@@ -91,43 +91,6 @@ public class DatabaseCursorTest extends AndroidTestCase implements PerformanceTe
mDatabase.execSQL("INSERT INTO test (data) VALUES ('" + sString3 + "');");
}
@MediumTest
public void testCursorUpdate() {
mDatabase.execSQL(
"CREATE TABLE test (_id INTEGER PRIMARY KEY, d INTEGER, s INTEGER);");
for(int i = 0; i < 20; i++) {
mDatabase.execSQL("INSERT INTO test (d, s) VALUES (" + i +
"," + i%2 + ");");
}
Cursor c = mDatabase.query("test", null, "s = 0", null, null, null, null);
int dCol = c.getColumnIndexOrThrow("d");
int sCol = c.getColumnIndexOrThrow("s");
int count = 0;
while (c.moveToNext()) {
assertTrue(c.updateInt(dCol, 3));
count++;
}
assertEquals(10, count);
assertTrue(c.commitUpdates());
assertTrue(c.requery());
count = 0;
while (c.moveToNext()) {
assertEquals(3, c.getInt(dCol));
count++;
}
assertEquals(10, count);
assertTrue(c.moveToFirst());
assertTrue(c.deleteRow());
assertEquals(9, c.getCount());
c.close();
}
@MediumTest
public void testBlob() throws Exception {
// create table
@@ -164,24 +127,7 @@ public class DatabaseCursorTest extends AndroidTestCase implements PerformanceTe
assertTrue(Arrays.equals(blob, cBlob));
assertEquals(s, c.getString(sCol));
assertEquals((double)d, c.getDouble(dCol));
assertEquals((long)l, c.getLong(lCol));
// new byte[]
byte[] newblob = new byte[1000];
value = 98;
Arrays.fill(blob, value);
c.updateBlob(bCol, newblob);
cBlob = c.getBlob(bCol);
assertTrue(Arrays.equals(newblob, cBlob));
// commit
assertTrue(c.commitUpdates());
assertTrue(c.requery());
c.moveToNext();
cBlob = c.getBlob(bCol);
assertTrue(Arrays.equals(newblob, cBlob));
c.close();
assertEquals((long)l, c.getLong(lCol));
}
@MediumTest

View File

@@ -467,45 +467,6 @@ public class DatabaseGeneralTest extends AndroidTestCase implements PerformanceT
boolean mCursor;
}
@MediumTest
public void testNotificationTest1() throws Exception {
/*
Cursor c = mContentResolver.query(Notes.CONTENT_URI,
new String[] {Notes._ID, Notes.NOTE},
null, null);
c.registerContentObserver(new MyContentObserver(true));
int count = c.count();
MyContentObserver observer = new MyContentObserver(false);
mContentResolver.registerContentObserver(Notes.CONTENT_URI, true, observer);
Uri uri;
HashMap<String, String> values = new HashMap<String, String>();
values.put(Notes.NOTE, "test note1");
uri = mContentResolver.insert(Notes.CONTENT_URI, values);
assertEquals(1, mCursorNotificationCount);
assertEquals(1, mNotificationCount);
c.requery();
assertEquals(count + 1, c.count());
c.first();
assertEquals("test note1", c.getString(c.getColumnIndex(Notes.NOTE)));
c.updateString(c.getColumnIndex(Notes.NOTE), "test note2");
c.commitUpdates();
assertEquals(2, mCursorNotificationCount);
assertEquals(2, mNotificationCount);
mContentResolver.delete(uri, null);
assertEquals(3, mCursorNotificationCount);
assertEquals(3, mNotificationCount);
mContentResolver.unregisterContentObserver(observer);
*/
}
@MediumTest
public void testSelectionArgs() throws Exception {
mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, data TEXT);");