From a0995b7ddf03119e1fd2ee729b06f1861fa16c6f Mon Sep 17 00:00:00 2001 From: Marten Gajda Date: Sat, 2 Dec 2017 22:22:37 +0100 Subject: [PATCH] Introduce TransactionEndTask. Implements #531 This commit introduces a TransactionEndTask which is run right before a transaction is ended. It also adds a simple implementation if TransactionEndTask which performs the call to setTransactionSuccessful() and runs it as the very last of these tasks. --- gradle.properties | 2 +- .../provider/tasks/SQLiteContentProvider.java | 55 ++++++++++++++++--- .../org/dmfs/provider/tasks/TaskProvider.java | 8 +++ 3 files changed, 55 insertions(+), 10 deletions(-) diff --git a/gradle.properties b/gradle.properties index 5b920fabe..7534c2a63 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ BUILD_TOOLS_VERSION=26.0.2 MIN_SDK_VERSION=9 TARGET_SDK_VERSION=25 # dependency versions -SUPPORT_LIBRARY_VERSION=25.0.1 +SUPPORT_LIBRARY_VERSION=25.4.0 CONTENTPAL_VERSION=3effe48 ROBOLECTRIC_VERSION=3.1.4 JEMS_VERSION=1.13 diff --git a/opentasks-provider/src/main/java/org/dmfs/provider/tasks/SQLiteContentProvider.java b/opentasks-provider/src/main/java/org/dmfs/provider/tasks/SQLiteContentProvider.java index cc421204f..336b256ab 100644 --- a/opentasks-provider/src/main/java/org/dmfs/provider/tasks/SQLiteContentProvider.java +++ b/opentasks-provider/src/main/java/org/dmfs/provider/tasks/SQLiteContentProvider.java @@ -27,6 +27,9 @@ import android.database.sqlite.SQLiteOpenHelper; import android.net.Uri; +import org.dmfs.iterables.SingletonIterable; +import org.dmfs.iterables.decorators.Flattened; + import java.util.ArrayList; import java.util.HashSet; import java.util.Set; @@ -46,11 +49,17 @@ abstract class SQLiteContentProvider extends ContentProvider { + interface TransactionEndTask + { + void execute(SQLiteDatabase database); + } + + @SuppressWarnings("unused") private static final String TAG = "SQLiteContentProvider"; private SQLiteOpenHelper mOpenHelper; - private Set mChangedUris; + private final Set mChangedUris = new HashSet<>(); private final ThreadLocal mApplyingBatch = new ThreadLocal(); private static final int SLEEP_AFTER_YIELD_DELAY = 4000; @@ -60,13 +69,20 @@ abstract class SQLiteContentProvider extends ContentProvider */ private static final int MAX_OPERATIONS_PER_YIELD_POINT = 500; + private final Iterable mTransactionEndTasks; + + + protected SQLiteContentProvider(Iterable transactionEndTasks) + { + // append a task to set the transaction to successful + mTransactionEndTasks = new Flattened<>(transactionEndTasks, new SingletonIterable(new SuccessfulTransactionEndTask())); + } + @Override public boolean onCreate() { - Context context = getContext(); - mOpenHelper = getDatabaseHelper(context); - mChangedUris = new HashSet(); + mOpenHelper = getDatabaseHelper(getContext()); return true; } @@ -136,7 +152,7 @@ public Uri insert(Uri uri, ContentValues values) try { result = insertInTransaction(db, uri, values, callerIsSyncAdapter); - db.setTransactionSuccessful(); + endTransaction(db); } finally { @@ -167,7 +183,7 @@ public int bulkInsert(Uri uri, ContentValues[] values) insertInTransaction(db, uri, values[i], callerIsSyncAdapter); db.yieldIfContendedSafely(); } - db.setTransactionSuccessful(); + endTransaction(db); } finally { @@ -192,7 +208,7 @@ public int update(Uri uri, ContentValues values, String selection, String[] sele try { count = updateInTransaction(db, uri, values, selection, selectionArgs, callerIsSyncAdapter); - db.setTransactionSuccessful(); + endTransaction(db); } finally { @@ -223,7 +239,7 @@ public int delete(Uri uri, String selection, String[] selectionArgs) try { count = deleteInTransaction(db, uri, selection, selectionArgs, callerIsSyncAdapter); - db.setTransactionSuccessful(); + endTransaction(db); } finally { @@ -275,7 +291,7 @@ public ContentProviderResult[] applyBatch(ArrayList op } results[i] = operation.apply(this, results, i); } - db.setTransactionSuccessful(); + endTransaction(db); return results; } finally @@ -309,4 +325,25 @@ protected boolean syncToNetwork(Uri uri) return false; } + + private void endTransaction(SQLiteDatabase database) + { + for (TransactionEndTask task : mTransactionEndTasks) + { + task.execute(database); + } + } + + + /** + * A {@link TransactionEndTask} which sets the transaction to be successful. + */ + private static class SuccessfulTransactionEndTask implements TransactionEndTask + { + @Override + public void execute(SQLiteDatabase database) + { + database.setTransactionSuccessful(); + } + } } diff --git a/opentasks-provider/src/main/java/org/dmfs/provider/tasks/TaskProvider.java b/opentasks-provider/src/main/java/org/dmfs/provider/tasks/TaskProvider.java index 6c0208e24..3333735d1 100644 --- a/opentasks-provider/src/main/java/org/dmfs/provider/tasks/TaskProvider.java +++ b/opentasks-provider/src/main/java/org/dmfs/provider/tasks/TaskProvider.java @@ -38,6 +38,7 @@ import android.os.HandlerThread; import android.text.TextUtils; +import org.dmfs.iterables.EmptyIterable; import org.dmfs.provider.tasks.TaskDatabaseHelper.OnDatabaseOperationListener; import org.dmfs.provider.tasks.TaskDatabaseHelper.Tables; import org.dmfs.provider.tasks.handler.PropertyHandler; @@ -148,6 +149,13 @@ public final class TaskProvider extends SQLiteContentProvider implements OnAccou private ProviderOperationsLog mOperationsLog = new ProviderOperationsLog(); + public TaskProvider() + { + // for now we don't have anything specific to execute before the transaction ends. + super(EmptyIterable.instance()); + } + + @Override public boolean onCreate() {