diff options
Diffstat (limited to 'src/com/android/providers/contacts/ContactsTransaction.java')
-rw-r--r-- | src/com/android/providers/contacts/ContactsTransaction.java | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/src/com/android/providers/contacts/ContactsTransaction.java b/src/com/android/providers/contacts/ContactsTransaction.java new file mode 100644 index 0000000..1b4284d --- /dev/null +++ b/src/com/android/providers/contacts/ContactsTransaction.java @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2011 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 com.android.providers.contacts; + +import com.google.android.collect.Lists; +import com.google.android.collect.Maps; + +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteTransactionListener; + +import java.util.List; +import java.util.Map; + +/** + * A transaction for interacting with a Contacts provider. This is used to pass state around + * throughout the operations comprising the transaction, including which databases the overall + * transaction is involved in, and whether the operation being performed is a batch operation. + */ +public class ContactsTransaction { + + /** + * Whether this transaction is encompassing a batch of operations. If we're in batch mode, + * transactional operations from non-batch callers are ignored. + */ + private final boolean mBatch; + + /** + * The list of databases that have been enlisted in this transaction. + */ + private List<SQLiteDatabase> mDatabasesForTransaction; + + /** + * The mapping of tags to databases involved in this transaction. + */ + private Map<String, SQLiteDatabase> mDatabaseTagMap; + + /** + * Whether any actual changes have been made successfully in this transaction. + */ + private boolean mIsDirty; + + /** + * Creates a new transaction object, optionally marked as a batch transaction. + * @param batch Whether the transaction is in batch mode. + */ + public ContactsTransaction(boolean batch) { + mBatch = batch; + mDatabasesForTransaction = Lists.newArrayList(); + mDatabaseTagMap = Maps.newHashMap(); + mIsDirty = false; + } + + public boolean isBatch() { + return mBatch; + } + + public boolean isDirty() { + return mIsDirty; + } + + public void markDirty() { + mIsDirty = true; + } + + /** + * If the given database has not already been enlisted in this transaction, adds it to our + * list of affected databases and starts a transaction on it. If we already have the given + * database in this transaction, this is a no-op. + * @param db The database to start a transaction on, if necessary. + * @param tag A constant that can be used to retrieve the DB instance in this transaction. + * @param listener A transaction listener to attach to this transaction. May be null. + */ + public void startTransactionForDb(SQLiteDatabase db, String tag, + SQLiteTransactionListener listener) { + if (!hasDbInTransaction(tag)) { + mDatabasesForTransaction.add(db); + mDatabaseTagMap.put(tag, db); + if (listener != null) { + db.beginTransactionWithListener(listener); + } else { + db.beginTransaction(); + } + } + } + + /** + * Returns whether DB corresponding to the given tag is currently enlisted in this transaction. + */ + public boolean hasDbInTransaction(String tag) { + return mDatabaseTagMap.containsKey(tag); + } + + /** + * Retrieves the database enlisted in the transaction corresponding to the given tag. + * @param tag The tag of the database to look up. + * @return The database corresponding to the tag, or null if no database with that tag has been + * enlisted in this transaction. + */ + public SQLiteDatabase getDbForTag(String tag) { + return mDatabaseTagMap.get(tag); + } + + /** + * Removes the database corresponding to the given tag from this transaction. It is now the + * caller's responsibility to do whatever needs to happen with this database - it is no longer + * a part of this transaction. + * @param tag The tag of the database to remove. + * @return The database corresponding to the tag, or null if no database with that tag has been + * enlisted in this transaction. + */ + public SQLiteDatabase removeDbForTag(String tag) { + SQLiteDatabase db = mDatabaseTagMap.get(tag); + mDatabaseTagMap.remove(tag); + mDatabasesForTransaction.remove(db); + return db; + } + + /** + * Marks all active DB transactions as successful. + * @param callerIsBatch Whether this is being performed in the context of a batch operation. + * If it is not, and the transaction is marked as batch, this call is a no-op. + */ + public void markSuccessful(boolean callerIsBatch) { + if (!mBatch || callerIsBatch) { + for (SQLiteDatabase db : mDatabasesForTransaction) { + db.setTransactionSuccessful(); + } + } + } + + /** + * Completes the transaction, marking the transactions for all databases as successful (or not), + * and ending them. + * @param callerIsBatch Whether this is being performed in the context of a batch operation. + * If it is not, and the transaction is marked as batch, this call is a no-op. + */ + public void finish(boolean callerIsBatch) { + if (!mBatch || callerIsBatch) { + for (SQLiteDatabase db : mDatabasesForTransaction) { + db.endTransaction(); + } + mDatabasesForTransaction.clear(); + mDatabaseTagMap.clear(); + mIsDirty = false; + } + } +} |