FileDocCategorySizeDatePackage
ContentProviderOperation.javaAPI DocAndroid 5.1 API26474Thu Mar 12 22:22:10 GMT 2015android.content

ContentProviderOperation

public class ContentProviderOperation extends Object implements android.os.Parcelable

Fields Summary
public static final int
TYPE_INSERT
public static final int
TYPE_UPDATE
public static final int
TYPE_DELETE
public static final int
TYPE_ASSERT
private final int
mType
private final android.net.Uri
mUri
private final String
mSelection
private final String[]
mSelectionArgs
private final ContentValues
mValues
private final Integer
mExpectedCount
private final ContentValues
mValuesBackReferences
private final Map
mSelectionArgsBackReferences
private final boolean
mYieldAllowed
private static final String
TAG
public static final Creator
CREATOR
Constructors Summary
private ContentProviderOperation(Builder builder)
Creates a {@link ContentProviderOperation} by copying the contents of a {@link Builder}.


                     
       
        mType = builder.mType;
        mUri = builder.mUri;
        mValues = builder.mValues;
        mSelection = builder.mSelection;
        mSelectionArgs = builder.mSelectionArgs;
        mExpectedCount = builder.mExpectedCount;
        mSelectionArgsBackReferences = builder.mSelectionArgsBackReferences;
        mValuesBackReferences = builder.mValuesBackReferences;
        mYieldAllowed = builder.mYieldAllowed;
    
private ContentProviderOperation(android.os.Parcel source)

        mType = source.readInt();
        mUri = Uri.CREATOR.createFromParcel(source);
        mValues = source.readInt() != 0 ? ContentValues.CREATOR.createFromParcel(source) : null;
        mSelection = source.readInt() != 0 ? source.readString() : null;
        mSelectionArgs = source.readInt() != 0 ? source.readStringArray() : null;
        mExpectedCount = source.readInt() != 0 ? source.readInt() : null;
        mValuesBackReferences = source.readInt() != 0
                ? ContentValues.CREATOR.createFromParcel(source)
                : null;
        mSelectionArgsBackReferences = source.readInt() != 0
                ? new HashMap<Integer, Integer>()
                : null;
        if (mSelectionArgsBackReferences != null) {
            final int count = source.readInt();
            for (int i = 0; i < count; i++) {
                mSelectionArgsBackReferences.put(source.readInt(), source.readInt());
            }
        }
        mYieldAllowed = source.readInt() != 0;
    
public ContentProviderOperation(ContentProviderOperation cpo, boolean removeUserIdFromUri)

hide

        mType = cpo.mType;
        if (removeUserIdFromUri) {
            mUri = ContentProvider.getUriWithoutUserId(cpo.mUri);
        } else {
            mUri = cpo.mUri;
        }
        mValues = cpo.mValues;
        mSelection = cpo.mSelection;
        mSelectionArgs = cpo.mSelectionArgs;
        mExpectedCount = cpo.mExpectedCount;
        mSelectionArgsBackReferences = cpo.mSelectionArgsBackReferences;
        mValuesBackReferences = cpo.mValuesBackReferences;
        mYieldAllowed = cpo.mYieldAllowed;
    
Methods Summary
public ContentProviderResultapply(android.content.ContentProvider provider, ContentProviderResult[] backRefs, int numBackRefs)
Applies this operation using the given provider. The backRefs array is used to resolve any back references that were requested using {@link Builder#withValueBackReferences(ContentValues)} and {@link Builder#withSelectionBackReference}.

param
provider the {@link ContentProvider} on which this batch is applied
param
backRefs a {@link ContentProviderResult} array that will be consulted to resolve any requested back references.
param
numBackRefs the number of valid results on the backRefs array.
return
a {@link ContentProviderResult} that contains either the {@link Uri} of the inserted row if this was an insert otherwise the number of rows affected.
throws
OperationApplicationException thrown if either the insert fails or if the number of rows affected didn't match the expected count

        ContentValues values = resolveValueBackReferences(backRefs, numBackRefs);
        String[] selectionArgs =
                resolveSelectionArgsBackReferences(backRefs, numBackRefs);

        if (mType == TYPE_INSERT) {
            Uri newUri = provider.insert(mUri, values);
            if (newUri == null) {
                throw new OperationApplicationException("insert failed");
            }
            return new ContentProviderResult(newUri);
        }

        int numRows;
        if (mType == TYPE_DELETE) {
            numRows = provider.delete(mUri, mSelection, selectionArgs);
        } else if (mType == TYPE_UPDATE) {
            numRows = provider.update(mUri, values, mSelection, selectionArgs);
        } else if (mType == TYPE_ASSERT) {
            // Assert that all rows match expected values
            String[] projection =  null;
            if (values != null) {
                // Build projection map from expected values
                final ArrayList<String> projectionList = new ArrayList<String>();
                for (Map.Entry<String, Object> entry : values.valueSet()) {
                    projectionList.add(entry.getKey());
                }
                projection = projectionList.toArray(new String[projectionList.size()]);
            }
            final Cursor cursor = provider.query(mUri, projection, mSelection, selectionArgs, null);
            try {
                numRows = cursor.getCount();
                if (projection != null) {
                    while (cursor.moveToNext()) {
                        for (int i = 0; i < projection.length; i++) {
                            final String cursorValue = cursor.getString(i);
                            final String expectedValue = values.getAsString(projection[i]);
                            if (!TextUtils.equals(cursorValue, expectedValue)) {
                                // Throw exception when expected values don't match
                                Log.e(TAG, this.toString());
                                throw new OperationApplicationException("Found value " + cursorValue
                                        + " when expected " + expectedValue + " for column "
                                        + projection[i]);
                            }
                        }
                    }
                }
            } finally {
                cursor.close();
            }
        } else {
            Log.e(TAG, this.toString());
            throw new IllegalStateException("bad type, " + mType);
        }

        if (mExpectedCount != null && mExpectedCount != numRows) {
            Log.e(TAG, this.toString());
            throw new OperationApplicationException("wrong number of rows: " + numRows);
        }

        return new ContentProviderResult(numRows);
    
private longbackRefToValue(ContentProviderResult[] backRefs, int numBackRefs, java.lang.Integer backRefIndex)
Return the string representation of the requested back reference.

param
backRefs an array of results
param
numBackRefs the number of items in the backRefs array that are valid
param
backRefIndex which backRef to be used
throws
ArrayIndexOutOfBoundsException thrown if the backRefIndex is larger than the numBackRefs
return
the string representation of the requested back reference.

        if (backRefIndex >= numBackRefs) {
            Log.e(TAG, this.toString());
            throw new ArrayIndexOutOfBoundsException("asked for back ref " + backRefIndex
                    + " but there are only " + numBackRefs + " back refs");
        }
        ContentProviderResult backRef = backRefs[backRefIndex];
        long backRefValue;
        if (backRef.uri != null) {
            backRefValue = ContentUris.parseId(backRef.uri);
        } else {
            backRefValue = backRef.count;
        }
        return backRefValue;
    
public intdescribeContents()

        return 0;
    
public intgetType()

hide
exposed for unit tests

        return mType;
    
public android.net.UrigetUri()

        return mUri;
    
public android.content.ContentProviderOperationgetWithoutUserIdInUri()

hide

        if (ContentProvider.uriHasUserId(mUri)) {
            return new ContentProviderOperation(this, true);
        }
        return this;
    
public booleanisReadOperation()

        return mType == TYPE_ASSERT;
    
public booleanisWriteOperation()

        return mType == TYPE_DELETE || mType == TYPE_INSERT || mType == TYPE_UPDATE;
    
public booleanisYieldAllowed()

        return mYieldAllowed;
    
public static android.content.ContentProviderOperation$BuildernewAssertQuery(android.net.Uri uri)
Create a {@link Builder} suitable for building a {@link ContentProviderOperation} to assert a set of values as provided through {@link Builder#withValues(ContentValues)}.

        return new Builder(TYPE_ASSERT, uri);
    
public static android.content.ContentProviderOperation$BuildernewDelete(android.net.Uri uri)
Create a {@link Builder} suitable for building a delete {@link ContentProviderOperation}.

param
uri The {@link Uri} that is the target of the delete.
return
a {@link Builder}

        return new Builder(TYPE_DELETE, uri);
    
public static android.content.ContentProviderOperation$BuildernewInsert(android.net.Uri uri)
Create a {@link Builder} suitable for building an insert {@link ContentProviderOperation}.

param
uri The {@link Uri} that is the target of the insert.
return
a {@link Builder}

        return new Builder(TYPE_INSERT, uri);
    
public static android.content.ContentProviderOperation$BuildernewUpdate(android.net.Uri uri)
Create a {@link Builder} suitable for building an update {@link ContentProviderOperation}.

param
uri The {@link Uri} that is the target of the update.
return
a {@link Builder}

        return new Builder(TYPE_UPDATE, uri);
    
public java.lang.String[]resolveSelectionArgsBackReferences(ContentProviderResult[] backRefs, int numBackRefs)
The Selection Arguments back references are represented as a Map of Integer->Integer where the key is an index into the selection argument array (see {@link Builder#withSelection}) and the value is the index of the previous result that should be used for that selection argument array slot.

This is intended to be a private method but it is exposed for unit testing purposes

param
backRefs an array of previous results
param
numBackRefs the number of valid previous results in backRefs
return
the ContentValues that should be used in this operation application after expansion of back references. This can be called if either mValues or mValuesBackReferences is null

        if (mSelectionArgsBackReferences == null) {
            return mSelectionArgs;
        }
        String[] newArgs = new String[mSelectionArgs.length];
        System.arraycopy(mSelectionArgs, 0, newArgs, 0, mSelectionArgs.length);
        for (Map.Entry<Integer, Integer> selectionArgBackRef
                : mSelectionArgsBackReferences.entrySet()) {
            final Integer selectionArgIndex = selectionArgBackRef.getKey();
            final int backRefIndex = selectionArgBackRef.getValue();
            newArgs[selectionArgIndex] =
                    String.valueOf(backRefToValue(backRefs, numBackRefs, backRefIndex));
        }
        return newArgs;
    
public ContentValuesresolveValueBackReferences(ContentProviderResult[] backRefs, int numBackRefs)
The ContentValues back references are represented as a ContentValues object where the key refers to a column and the value is an index of the back reference whose valued should be associated with the column.

This is intended to be a private method but it is exposed for unit testing purposes

param
backRefs an array of previous results
param
numBackRefs the number of valid previous results in backRefs
return
the ContentValues that should be used in this operation application after expansion of back references. This can be called if either mValues or mValuesBackReferences is null

        if (mValuesBackReferences == null) {
            return mValues;
        }
        final ContentValues values;
        if (mValues == null) {
            values = new ContentValues();
        } else {
            values = new ContentValues(mValues);
        }
        for (Map.Entry<String, Object> entry : mValuesBackReferences.valueSet()) {
            String key = entry.getKey();
            Integer backRefIndex = mValuesBackReferences.getAsInteger(key);
            if (backRefIndex == null) {
                Log.e(TAG, this.toString());
                throw new IllegalArgumentException("values backref " + key + " is not an integer");
            }
            values.put(key, backRefToValue(backRefs, numBackRefs, backRefIndex));
        }
        return values;
    
public java.lang.StringtoString()

        return "mType: " + mType + ", mUri: " + mUri +
                ", mSelection: " + mSelection +
                ", mExpectedCount: " + mExpectedCount +
                ", mYieldAllowed: " + mYieldAllowed +
                ", mValues: " + mValues +
                ", mValuesBackReferences: " + mValuesBackReferences +
                ", mSelectionArgsBackReferences: " + mSelectionArgsBackReferences;
    
public voidwriteToParcel(android.os.Parcel dest, int flags)

        dest.writeInt(mType);
        Uri.writeToParcel(dest, mUri);
        if (mValues != null) {
            dest.writeInt(1);
            mValues.writeToParcel(dest, 0);
        } else {
            dest.writeInt(0);
        }
        if (mSelection != null) {
            dest.writeInt(1);
            dest.writeString(mSelection);
        } else {
            dest.writeInt(0);
        }
        if (mSelectionArgs != null) {
            dest.writeInt(1);
            dest.writeStringArray(mSelectionArgs);
        } else {
            dest.writeInt(0);
        }
        if (mExpectedCount != null) {
            dest.writeInt(1);
            dest.writeInt(mExpectedCount);
        } else {
            dest.writeInt(0);
        }
        if (mValuesBackReferences != null) {
            dest.writeInt(1);
            mValuesBackReferences.writeToParcel(dest, 0);
        } else {
            dest.writeInt(0);
        }
        if (mSelectionArgsBackReferences != null) {
            dest.writeInt(1);
            dest.writeInt(mSelectionArgsBackReferences.size());
            for (Map.Entry<Integer, Integer> entry : mSelectionArgsBackReferences.entrySet()) {
                dest.writeInt(entry.getKey());
                dest.writeInt(entry.getValue());
            }
        } else {
            dest.writeInt(0);
        }
        dest.writeInt(mYieldAllowed ? 1 : 0);