public OperationBatch(IMobileServiceSyncHandler syncHandler, IMobileServiceLocalStore store, MobileServiceSyncContext context)
 {
     this.OtherErrors = new List<Exception>();
     this.SyncHandler = syncHandler;
     this.Store = store;
     this.context = context;
 }
 public OperationBatch(IMobileServiceSyncHandler syncHandler, IMobileServiceLocalStore store, MobileServiceSyncContext context)
 {
     this.OtherErrors = new List <Exception>();
     this.SyncHandler = syncHandler;
     this.Store       = store;
     this.context     = context;
 }
        public MobileServiceSyncTable(string tableName, MobileServiceTableKind Kind, MobileServiceClient client)
        {
            Debug.Assert(tableName != null);
            Debug.Assert(client != null);

            this.MobileServiceClient = client;
            this.TableName = tableName;
            this.Kind = Kind;
            this.syncContext = (MobileServiceSyncContext)client.SyncContext;
            this.SupportedOptions = MobileServiceRemoteTableOptions.All;
        }
        public MobileServiceSyncTable(string tableName, MobileServiceTableKind Kind, MobileServiceClient client)
        {
            Debug.Assert(tableName != null);
            Debug.Assert(client != null);

            this.MobileServiceClient = client;
            this.TableName           = tableName;
            this.Kind             = Kind;
            this.syncContext      = (MobileServiceSyncContext)client.SyncContext;
            this.SupportedOptions = MobileServiceRemoteTableOptions.All;
        }
示例#5
0
 public PurgeAction(MobileServiceTable table,
                    MobileServiceTableKind tableKind,
                    string queryId,
                    MobileServiceTableQueryDescription query,
                    bool force,
                    MobileServiceSyncContext context,
                    OperationQueue operationQueue,
                    MobileServiceSyncSettingsManager settings,
                    IMobileServiceLocalStore store,
                    CancellationToken cancellationToken)
     : base(table, tableKind, queryId, query, null, context, operationQueue, settings, store, cancellationToken)
 {
     this.force = force;
 }
 public PurgeAction(MobileServiceTable table,
                    MobileServiceTableKind tableKind,
                    string queryId,
                    MobileServiceTableQueryDescription query,
                    bool force,
                    MobileServiceSyncContext context,
                    OperationQueue operationQueue,
                    MobileServiceSyncSettingsManager settings,
                    IMobileServiceLocalStore store,
                    CancellationToken cancellationToken)
     : base(table, tableKind, queryId, query, null, context, operationQueue, settings, store, cancellationToken)
 {
     this.force = force;
 }
 public PushAction(OperationQueue operationQueue,
                   IMobileServiceLocalStore store,
                   MobileServiceTableKind tableKind,
                   IEnumerable <string> tableNames,
                   IMobileServiceSyncHandler syncHandler,
                   MobileServiceClient client,
                   MobileServiceSyncContext context,
                   CancellationToken cancellationToken)
     : base(operationQueue, store, cancellationToken)
 {
     this.tableKind   = tableKind;
     this.tableNames  = tableNames;
     this.client      = client;
     this.syncHandler = syncHandler;
     this.context     = context;
 }
 public PushAction(OperationQueue operationQueue,
                   IMobileServiceLocalStore store,
                   MobileServiceTableKind tableKind,
                   IEnumerable<string> tableNames,
                   IMobileServiceSyncHandler syncHandler,
                   MobileServiceClient client,
                   MobileServiceSyncContext context,
                   CancellationToken cancellationToken)
     : base(operationQueue, store, cancellationToken)
 {
     this.tableKind = tableKind;
     this.tableNames = tableNames;
     this.client = client;
     this.syncHandler = syncHandler;
     this.context = context;
 }
 public TableAction(MobileServiceTable table,
                    MobileServiceTableKind tableKind,
                    string queryId,
                    MobileServiceTableQueryDescription query,
                    IEnumerable<string> relatedTables,
                    MobileServiceSyncContext context,
                    OperationQueue operationQueue,
                    MobileServiceSyncSettingsManager settings,
                    IMobileServiceLocalStore store,
                    CancellationToken cancellationToken)
     : base(operationQueue, store, cancellationToken)
 {
     this.Table = table;
     this.TableKind = tableKind;
     this.QueryId = queryId;
     this.Query = query;
     this.RelatedTables = relatedTables;
     this.Settings = settings;
     this.Context = context;
 }
 public PullAction(MobileServiceTable table,
                   MobileServiceTableKind tableKind,
                   MobileServiceSyncContext context,
                   string queryId,
                   MobileServiceTableQueryDescription query,
                   IDictionary <string, string> parameters,
                   IEnumerable <string> relatedTables,
                   OperationQueue operationQueue,
                   MobileServiceSyncSettingsManager settings,
                   IMobileServiceLocalStore store,
                   MobileServiceRemoteTableOptions options,
                   MobileServiceObjectReader reader,
                   CancellationToken cancellationToken)
     : base(table, tableKind, queryId, query, relatedTables, context, operationQueue, settings, store, cancellationToken)
 {
     this.options    = options;
     this.parameters = parameters;
     this.cursor     = new PullCursor(query);
     this.Reader     = reader ?? new MobileServiceObjectReader();
 }
 public PullAction(MobileServiceTable table,
                   MobileServiceTableKind tableKind,
                   MobileServiceSyncContext context,
                   string queryId,
                   MobileServiceTableQueryDescription query,
                   IDictionary<string, string> parameters,
                   IEnumerable<string> relatedTables,
                   OperationQueue operationQueue,
                   MobileServiceSyncSettingsManager settings,
                   IMobileServiceLocalStore store,
                   MobileServiceRemoteTableOptions options,
                   MobileServiceObjectReader reader,
                   CancellationToken cancellationToken)
     : base(table, tableKind, queryId, query, relatedTables, context, operationQueue, settings, store, cancellationToken)
 {
     this.options = options;
     this.parameters = parameters;
     this.cursor = new PullCursor(query);
     this.Reader = reader ?? new MobileServiceObjectReader();
 }
 public TableAction(MobileServiceTable table,
                    MobileServiceTableKind tableKind,
                    string queryId,
                    MobileServiceTableQueryDescription query,
                    IEnumerable <string> relatedTables,
                    MobileServiceSyncContext context,
                    OperationQueue operationQueue,
                    MobileServiceSyncSettingsManager settings,
                    IMobileServiceLocalStore store,
                    CancellationToken cancellationToken)
     : base(operationQueue, store, cancellationToken)
 {
     this.Table         = table;
     this.TableKind     = tableKind;
     this.QueryId       = queryId;
     this.Query         = query;
     this.RelatedTables = relatedTables;
     this.Settings      = settings;
     this.Context       = context;
 }
        private async Task UpdateOperationAsync_ConflictOperation_WithNotificationsEnabled_UsesTheCorrectStoreSource()
        {                        
            var client = new MobileServiceClient("http://www.test.com");
            var store = new MobileServiceLocalStoreMock();
            var context = new MobileServiceSyncContext(client);
            await context.InitializeAsync(store, StoreTrackingOptions.NotifyLocalConflictResolutionOperations);
            var manualResetEvent = new ManualResetEventSlim();

            string operationId = "abc";
            string itemId = "def";
            string tableName = "test";


            store.TableMap[MobileServiceLocalSystemTables.SyncErrors] = new Dictionary<string, JObject>() { { operationId, new JObject() { { "id", operationId }, { "version", 1 } } } };
            store.TableMap[MobileServiceLocalSystemTables.OperationQueue].Add(operationId, new JObject() { { "id", operationId }, { "version", 1 } });
            store.TableMap.Add(tableName, new Dictionary<string, JObject>() { { itemId, new JObject() } });

            // operation exists before cancel
            Assert.IsNotNull(await store.LookupAsync(MobileServiceLocalSystemTables.OperationQueue, operationId));
            // item exists before upsert
            Assert.IsNotNull(await store.LookupAsync(tableName, itemId));


            var error = new MobileServiceTableOperationError(operationId,
                                                             1,
                                                             MobileServiceTableOperationKind.Update,
                                                             HttpStatusCode.Conflict,
                                                             tableName,
                                                             item: new JObject() { { "id", itemId } },
                                                             rawResult: "{}",
                                                             result: new JObject());
            var item = new JObject() { { "id", itemId }, { "name", "unknown" } };                       
            
            bool sourceIsLocalConflict = false;
            IDisposable subscription = client.EventManager.Subscribe<StoreOperationCompletedEvent>(o =>
            {
                sourceIsLocalConflict = o.Operation.Source == StoreOperationSource.LocalConflictResolution;
                manualResetEvent.Set();
            });

            await context.UpdateOperationAsync(error, item);

            bool resetEventSignaled = manualResetEvent.Wait(1000);
            subscription.Dispose();

            Assert.IsTrue(resetEventSignaled);
            Assert.IsTrue(sourceIsLocalConflict);
        }
        private async Task ConflictOperation_WithNotificationsEnabled_UsesTheCorrectStoreOperationSource(Func<MobileServiceSyncContext, MobileServiceTableOperationError, Task> handler)
        {
            var client = new MobileServiceClient(MobileAppUriValidator.DummyMobileApp);
            var store = new MobileServiceLocalStoreMock();
            var context = new MobileServiceSyncContext(client);
            var manualResetEvent = new ManualResetEventSlim();

            await context.InitializeAsync(store, StoreTrackingOptions.NotifyLocalConflictResolutionOperations);

            string operationId = "abc";
            string itemId = string.Empty;
            string tableName = "test";

            store.TableMap[MobileServiceLocalSystemTables.OperationQueue].Add(operationId, new JObject() { { "version", 1 } });


            var error = new MobileServiceTableOperationError(operationId,
                                                             1,
                                                             MobileServiceTableOperationKind.Update,
                                                             HttpStatusCode.Conflict,
                                                             tableName,
                                                             item: new JObject() { { "id", itemId } },
                                                             rawResult: "{}",
                                                             result: new JObject());


            bool sourceIsLocalConflict = false;
            IDisposable subscription = client.EventManager.Subscribe<StoreOperationCompletedEvent>(o =>
            {
                sourceIsLocalConflict = o.Operation.Source == StoreOperationSource.LocalConflictResolution;
                manualResetEvent.Set();
            });

            await handler(context, error);

            bool resetEventSignaled = manualResetEvent.Wait(1000);
            subscription.Dispose();

            Assert.IsTrue(resetEventSignaled);
            Assert.IsTrue(sourceIsLocalConflict);
        }
        private async Task TestOperationModifiedException(bool operationExists, Func<MobileServiceTableOperationError, MobileServiceSyncContext, Task> action, String errorMessage)
        {
            var client = new MobileServiceClient(MobileAppUriValidator.DummyMobileApp);
            var store = new MobileServiceLocalStoreMock();
            var context = new MobileServiceSyncContext(client);
            await context.InitializeAsync(store);

            string operationId = "abc";
            string itemId = "def";
            string tableName = "test";

            if (operationExists)
            {
                store.TableMap[MobileServiceLocalSystemTables.OperationQueue].Add(operationId, new JObject() { { "version", 3 } });
            }
            else
            {
                // operation exists before cancel
                Assert.IsNull(await store.LookupAsync(MobileServiceLocalSystemTables.OperationQueue, operationId));
            }

            var error = new MobileServiceTableOperationError(operationId,
                                                             1,
                                                             MobileServiceTableOperationKind.Update,
                                                             HttpStatusCode.Conflict,
                                                             tableName,
                                                             item: new JObject() { { "id", itemId } },
                                                             rawResult: "{}",
                                                             result: new JObject());

            var ex = await ThrowsAsync<InvalidOperationException>(() => action(error, context));

            Assert.AreEqual(ex.Message, errorMessage);
        }
        public async Task CancelAndDiscardItemAsync_DeletesTheItemInLocalStore_AndDeletesTheOperationAndError()
        {
            var client = new MobileServiceClient(MobileAppUriValidator.DummyMobileApp);
            var store = new MobileServiceLocalStoreMock();
            var context = new MobileServiceSyncContext(client);
            await context.InitializeAsync(store);

            string operationId = "abc";
            string itemId = "def";
            string tableName = "test";

            store.TableMap[MobileServiceLocalSystemTables.SyncErrors] = new Dictionary<string, JObject>() { { operationId, new JObject() } };
            store.TableMap[MobileServiceLocalSystemTables.OperationQueue].Add(operationId, new JObject());
            store.TableMap.Add(tableName, new Dictionary<string, JObject>() { { itemId, new JObject() } });

            // operation exists before cancel
            Assert.IsNotNull(await store.LookupAsync(MobileServiceLocalSystemTables.OperationQueue, operationId));
            // item exists before upsert
            Assert.IsNotNull(await store.LookupAsync(tableName, itemId));

            var error = new MobileServiceTableOperationError(operationId,
                                                             0,
                                                             MobileServiceTableOperationKind.Update,
                                                             HttpStatusCode.Conflict,
                                                             tableName,
                                                             item: new JObject() { { "id", itemId } },
                                                             rawResult: "{}",
                                                             result: new JObject());

            await context.CancelAndDiscardItemAsync(error);

            // operation is deleted
            Assert.IsNull(await store.LookupAsync(MobileServiceLocalSystemTables.OperationQueue, operationId));
            // error is deleted
            Assert.IsNull(await store.LookupAsync(MobileServiceLocalSystemTables.SyncErrors, operationId));

            // item is upserted
            Assert.IsNull(await store.LookupAsync(tableName, itemId));
        }
        public async Task UpdateOperationAsync_UpsertTheItemInOperation_AndDeletesTheError()
        {
            var client = new MobileServiceClient("http://www.test.com");
            var store = new MobileServiceLocalStoreMock();
            var context = new MobileServiceSyncContext(client);
            await context.InitializeAsync(store);

            string operationId = "abc";
            string itemId = "def";
            string tableName = "test";

            var item = new JObject() { { "id", itemId }, { "name", "unknown" } };

            store.TableMap[MobileServiceLocalSystemTables.SyncErrors] = new Dictionary<string, JObject>() { { operationId, new JObject() { { "id", operationId }, { "version", 1 } } } };
            store.TableMap[MobileServiceLocalSystemTables.OperationQueue].Add(operationId, new JObject() { { "id", operationId }, { "version", 1 }, { "item", item.ToString() }, { "kind", (int)MobileServiceTableOperationKind.Delete } });

            // operation exists before cancel
            Assert.IsNotNull(await store.LookupAsync(MobileServiceLocalSystemTables.OperationQueue, operationId));
            // item does not exist
            Assert.IsNull(await store.LookupAsync(tableName, itemId));

            var error = new MobileServiceTableOperationError(operationId,
                                                             1,
                                                             MobileServiceTableOperationKind.Delete,
                                                             HttpStatusCode.PreconditionFailed,
                                                             tableName,
                                                             item: new JObject() { { "id", itemId } },
                                                             rawResult: "{}",
                                                             result: new JObject());
            var item2 = new JObject() { { "id", itemId }, { "name", "unknown" }, { "version", 2 } };
            await context.UpdateOperationAsync(error, item2);

            var operation = await store.LookupAsync(MobileServiceLocalSystemTables.OperationQueue, operationId);
            // operation is updated
            Assert.IsNotNull(operation);
            // error is deleted
            Assert.IsNull(await store.LookupAsync(MobileServiceLocalSystemTables.SyncErrors, operationId));

            Assert.AreEqual(operation.GetValue("item").ToString(), item2.ToString(Formatting.None));
        }
        public async Task UpdateOperationAsync_UpsertsTheItemInLocalStore_AndDeletesTheError_AndUpdatesTheOperation()
        {
            var client = new MobileServiceClient("http://www.test.com");
            var store = new MobileServiceLocalStoreMock();
            var context = new MobileServiceSyncContext(client);
            await context.InitializeAsync(store);

            string operationId = "abc";
            string itemId = "def";
            string tableName = "test";


            store.TableMap[MobileServiceLocalSystemTables.SyncErrors] = new Dictionary<string, JObject>() { { operationId, new JObject() { { "id", operationId }, { "version", 1 } } } };
            store.TableMap[MobileServiceLocalSystemTables.OperationQueue].Add(operationId, new JObject() { { "id", operationId }, { "version", 1 } });
            store.TableMap.Add(tableName, new Dictionary<string, JObject>() { { itemId, new JObject() } });

            // operation exists before cancel
            Assert.IsNotNull(await store.LookupAsync(MobileServiceLocalSystemTables.OperationQueue, operationId));
            // item exists before upsert
            Assert.IsNotNull(await store.LookupAsync(tableName, itemId));

            var error = new MobileServiceTableOperationError(operationId,
                                                             1,
                                                             MobileServiceTableOperationKind.Update,
                                                             HttpStatusCode.Conflict,
                                                             tableName,
                                                             item: new JObject() { { "id", itemId } },
                                                             rawResult: "{}",
                                                             result: new JObject());

            var item = new JObject() { { "id", itemId }, { "name", "unknown" } };
            await context.UpdateOperationAsync(error, item);

            // operation is updated
            Assert.IsNotNull(await store.LookupAsync(MobileServiceLocalSystemTables.OperationQueue, operationId));
            // error is deleted
            Assert.IsNull(await store.LookupAsync(MobileServiceLocalSystemTables.SyncErrors, operationId));

            JObject upserted = await store.LookupAsync(tableName, itemId);
            // item is upserted
            Assert.IsNotNull(upserted);
            Assert.AreEqual(item, upserted);
        }
 public void Initialize()
 {
     this.client = new Mock<MobileServiceClient>();
     this.context = new MobileServiceSyncContext(this.client.Object);
 }