Beispiel #1
0
        public static void AddTaskCreateOrUpdate <TRollback, TDocument>(this RollbackAsync <TRollback> rollback,
                                                                        Guid docId, string partitionKey,
                                                                        Func <bool, TDocument, bool> isMutated,
                                                                        Action <TDocument> mutateRollback,
                                                                        AzureStorageRepository repo)
            where TDocument : class, ITableEntity
        {
            rollback.AddTask(
                (success, failure) =>
            {
                return(repo.CreateOrUpdateAsync <TDocument, RollbackAsync <TRollback> .RollbackResult>(docId, partitionKey,
                                                                                                       async(created, doc, save) =>
                {
                    if (!isMutated(created, doc))
                    {
                        return success(
                            async() =>
                        {
                            if (created)
                            {
                                await repo.DeleteAsync(doc,
                                                       () => true,
                                                       () => false);
                            }
                        });
                    }

                    await save(doc);
                    return success(
                        async() =>
                    {
                        if (created)
                        {
                            await repo.DeleteIfAsync <TDocument, bool>(docId,
                                                                       async(docDelete, delete) =>
                            {
                                // TODO: Check etag if(docDelete.ET)
                                await delete();
                                return true;
                            },
                                                                       () => false);
                            return;
                        }
                        await repo.UpdateAsync <TDocument, bool>(docId,
                                                                 async(docRollback, saveRollback) =>
                        {
                            mutateRollback(docRollback);
                            await saveRollback(docRollback);
                            return true;
                        },
                                                                 () => false);
                    });
                }));
            });
        }
Beispiel #2
0
 public static void AddTaskCheckup <TRollback, TDocument>(this RollbackAsync <TRollback> rollback,
                                                          Guid docId,
                                                          Func <TRollback> onDoesNotExists,
                                                          AzureStorageRepository repo)
     where TDocument : class, ITableEntity
 {
     rollback.AddTask(
         async(success, failure) =>
     {
         return(await repo.FindByIdAsync(docId,
                                         (TDocument doc) => success(() => 1.ToTask()), () => failure(onDoesNotExists())));
     });
 }
Beispiel #3
0
        public static void AddTaskAsyncCreateOrUpdate <TRollback, TDocument>(this RollbackAsync <TRollback> rollback,
                                                                             Guid docId,
                                                                             Func <TDocument, Task <bool> > isValidAndMutate,
                                                                             Func <TDocument, Task <bool> > mutateRollback,
                                                                             Func <TRollback> onFail,
                                                                             AzureStorageRepository repo)
            where TDocument : class, ITableEntity
        {
            rollback.AddTask(
                (success, failure) =>
            {
                return(repo.CreateOrUpdateAsync <TDocument, RollbackAsync <TRollback> .RollbackResult>(docId,
                                                                                                       async(created, doc, save) =>
                {
                    if (!await isValidAndMutate(doc))
                    {
                        return failure(onFail());
                    }

                    await save(doc);
                    return success(
                        async() =>
                    {
                        if (created)
                        {
                            await repo.DeleteIfAsync <TDocument, bool>(docId,
                                                                       async(docDelete, delete) =>
                            {
                                // TODO: Check etag if(docDelete.ET)
                                await delete();
                                return true;
                            },
                                                                       () => false);
                            return;
                        }
                        await repo.UpdateAsync <TDocument, bool>(docId,
                                                                 async(docRollback, saveRollback) =>
                        {
                            if (await mutateRollback(docRollback))
                            {
                                await saveRollback(docRollback);
                            }
                            return true;
                        },
                                                                 () => false);
                    });
                }));
            });
        }
Beispiel #4
0
        public static void AddTaskAsyncUpdate <TRollback, TDocument>(this RollbackAsync <TRollback> rollback,
                                                                     Guid docId,
                                                                     Func <TDocument, Task <bool> > mutateUpdate,
                                                                     Func <TDocument, Task> mutateRollback,
                                                                     Func <TRollback> onNotFound,
                                                                     AzureStorageRepository repo)
            where TDocument : class, ITableEntity
        {
            rollback.AddTask(
                async(success, failure) =>
            {
                var r = await repo.UpdateAsync <TDocument, int>(docId,
                                                                async(doc, save) =>
                {
                    if (!await mutateUpdate(doc))
                    {
                        return(1);
                    }
                    await save(doc);
                    return(0);
                },
                                                                () => - 1);
                if (r == 0)
                {
                    return(success(
                               async() =>
                    {
                        await repo.UpdateAsync <TDocument, bool>(docId,
                                                                 async(doc, save) =>
                        {
                            await mutateRollback(doc);
                            await save(doc);
                            return true;
                        },
                                                                 () => false);
                    }));
                }
                if (r == 1)
                {
                    return(success(() => true.ToTask()));
                }

                return(failure(onNotFound()));
            });
        }
Beispiel #5
0
 public static void AddTaskCreate <TRollback, TDocument>(this RollbackAsync <TRollback> rollback,
                                                         Guid docId, string partitionKey, TDocument document,
                                                         Func <TRollback> onAlreadyExists,
                                                         AzureStorageRepository repo)
     where TDocument : class, ITableEntity
 {
     rollback.AddTask(
         async(success, failure) =>
     {
         return(await repo.CreateAsync(docId, partitionKey, document,
                                       () => success(
                                           async() =>
         {
             await repo.DeleteIfAsync <TDocument, bool>(docId, partitionKey,
                                                        async(doc, delete) => { await delete(); return true; },
                                                        () => false);
         }),
                                       () => failure(onAlreadyExists())));
     });
 }
Beispiel #6
0
 public static void AddTaskUpdate <T, TRollback, TDocument>(this RollbackAsync <T, TRollback> rollback,
                                                            Guid docId,
                                                            Func <TDocument, T> mutateUpdate,
                                                            Func <T, TDocument, bool> mutateRollback,
                                                            Func <T> ifNotFound,
                                                            AzureStorageRepository repo)
     where TDocument : class, ITableEntity
 {
     rollback.AddTask(
         async(success, failure) =>
     {
         var r = await repo.UpdateAsync <TDocument, Carry <T>?>(docId,
                                                                async(doc, save) =>
         {
             var carry = mutateUpdate(doc);
             await save(doc);
             return(new Carry <T>
             {
                 carry = carry,
             });
         },
                                                                () => default(Carry <T>?));
         if (r.HasValue)
         {
             return(success(r.Value.carry,
                            async() =>
             {
                 await repo.UpdateAsync <TDocument, bool>(docId,
                                                          async(doc, save) =>
                 {
                     mutateRollback(r.Value.carry, doc);
                     await save(doc);
                     return true;
                 },
                                                          () => false);
             }));
         }
         return(success(ifNotFound(), () => ((object)null).ToTask()));
     });
 }
Beispiel #7
0
        public static void AddTaskUpdate <T, TRollback, TDocument>(this RollbackAsync <TRollback> rollback,
                                                                   Guid docId,
                                                                   Func <
                                                                       TDocument,
                                                                       Func <T, UpdateCallback <T> >, // Save + Success
                                                                       Func <UpdateCallback <T> >,    // No Save + Success
                                                                       Func <UpdateCallback <T> >,    // Reject
                                                                       UpdateCallback <T> > mutateUpdate,
                                                                   Func <T, TDocument, bool> mutateRollback,
                                                                   Func <TRollback> onMutateRejected,
                                                                   Func <TRollback> onNotFound,
                                                                   AzureStorageRepository repo)
            where TDocument : class, ITableEntity
        {
            rollback.AddTask(
                async(success, failure) =>
            {
                var r = await repo.UpdateAsync <TDocument, UpdateCallback <T> >(docId,
                                                                                async(doc, save) =>
                {
                    var passThrough = mutateUpdate(doc,
                                                   (passThroughSuccess) => UpdateCallback <T> .Save(passThroughSuccess),
                                                   () => UpdateCallback <T> .SuccessNoSave(),
                                                   () => UpdateCallback <T> .Reject());
                    if (passThrough.save)
                    {
                        await save(doc);
                    }
                    return(passThrough);
                },
                                                                                () => UpdateCallback <T> .NotFound());

                if (!r.found)
                {
                    return(failure(onNotFound()));
                }
                if (!r.success)
                {
                    return(failure(onMutateRejected()));
                }

                return(success(
                           async() =>
                {
                    if (r.save)
                    {
                        await repo.UpdateAsync <TDocument, bool>(docId,
                                                                 async(doc, save) =>
                        {
                            if (mutateRollback(r.t, doc))
                            {
                                await save(doc);
                            }
                            return true;
                        },
                                                                 () => false);
                    }

                    // If this was not saved, there is no reason to do anything on the rollback
                }));
            });
        }