Пример #1
0
        private async Task <int> SaveChangesBatch(IDbConnection connection, IList <IReplicaInfo> localKnowledge,
                                                  int startItem)
        {
            var request = new JObject
            {
                { "sessionID", _remoteSessionId },
                { "startItem", startItem },
                { "maxBatchCount", PullMaxBatchCount },
                { "maxBatchSize", PullMaxBatchSize }
            };

            JObject response = await _transport.TransportAsync(SyncEndpoint.GetItemDataBatch, request);

            var batch = (JArray)response["batch"];

            foreach (var item in batch)
            {
                ISyncableItemInfo remoteSyncableItemInfo = SyncUtil.SyncableItemInfoFromJson(item["item"]);
                var itemData = new JObject {
                    { "item", item["item"] }
                };

                var status = SyncStatus.MayBeNeeded;
                if (!SyncUtil.KnowledgeContains(localKnowledge, remoteSyncableItemInfo.Modified))
                {
                    ISyncableItemInfo localSyncableItemInfo = _store.LocateCurrentItemInfo(remoteSyncableItemInfo);
                    status = SyncUtil.CalculateSyncStatus(remoteSyncableItemInfo, localSyncableItemInfo,
                                                          _remoteKnowledge);
                }
                SessionDbHelper.SaveItemData(connection, remoteSyncableItemInfo, status, itemData);
                var itemRefs = (JArray)itemData["item"]["itemRefs"];
                foreach (var itemRef in itemRefs)
                {
                    ISyncableItemInfo itemRefInfo      = SyncUtil.SyncableItemInfoFromJson(itemRef);
                    ISyncableItemInfo localItemRefInfo = _store.LocateCurrentItemInfo(itemRefInfo);
                    if (localItemRefInfo != null && localItemRefInfo.Deleted)
                    {
                        await SaveSyncData(connection, itemRefInfo, SyncStatus.MayBeNeeded);
                    }
                }
            }
            return(batch.Count);
        }
Пример #2
0
        private IEnumerable <SyncConflict> CheckForDuplicates(IDbConnection connection)
        {
            var conflicts = new List <SyncConflict>();

            var changedItemInfos = _store.LocateChangedItems(_remoteKnowledge).ToList();

            foreach (string itemType in _store.GetItemTypes())
            {
                IDbCommand getInsertedItemsCommand = connection.CreateCommand();
                getInsertedItemsCommand.CommandText =
                    String.Format(
                        "SELECT ItemID, SyncStatus, ItemType, GlobalCreatedReplica, CreatedTickCount, GlobalModifiedReplica, ModifiedTickCount, ItemData  FROM SyncItems WHERE SyncStatus={0} AND ItemType='{1}'",
                        (int)SyncStatus.Insert, itemType);
                using (IDataReader reader = getInsertedItemsCommand.ExecuteReader())
                {
                    while (reader != null && reader.Read())
                    {
                        long              itemId              = Convert.ToInt64(reader["ItemID"]);
                        IReplicaInfo      createdReplicaInfo  = SessionDbHelper.ReplicaInfoFromDataReader(reader, "Created");
                        IReplicaInfo      modifiedReplicaInfo = SessionDbHelper.ReplicaInfoFromDataReader(reader, "Modified");
                        ISyncableItemInfo remoteItemInfo      = new SyncableItemInfo
                        {
                            ItemType = itemType,
                            Created  = createdReplicaInfo,
                            Modified = modifiedReplicaInfo,
                            Deleted  = false
                        };
                        var remoteItemData = JObject.Parse((string)reader["ItemData"]);

                        foreach (var changedItemInfo in changedItemInfos)
                        {
                            if (changedItemInfo.ItemType != remoteItemInfo.ItemType)
                            {
                                continue;
                            }
                            if (SyncUtil.KnowledgeContains(_remoteKnowledge, changedItemInfo.Created))
                            {
                                continue;
                            }

                            // Inserted here without remote knowledge, could be a dup
                            var builder = SyncUtil.JsonItemFromSyncableItemInfo(changedItemInfo);
                            _store.BuildItemData(changedItemInfo, builder);

                            var localItemData = new JObject {
                                { "item", builder }
                            };

                            DuplicateStatus dupStatus = _store.GetDuplicateStatus(remoteItemInfo.ItemType, localItemData,
                                                                                  remoteItemData);
                            if (dupStatus == DuplicateStatus.Exact)
                            {
                                SessionDbHelper.ReplaceAllItemRefs(connection, _store, remoteItemInfo, changedItemInfo);
                                long         tickCount       = _store.IncrementLocalRepilcaTickCount();
                                IReplicaInfo modifiedReplica = new ReplicaInfo
                                {
                                    ReplicaId        = _store.GetLocalReplicaId(),
                                    ReplicaTickCount = tickCount
                                };
                                SessionDbHelper.ResolveItemNoData(connection, remoteItemInfo,
                                                                  SyncStatus.DeleteNonExisting, modifiedReplica);
                                break;
                            }
                            if (dupStatus == DuplicateStatus.Possible)
                            {
                                // TODO: clean this up, this call does more than we need
                                SessionDbHelper.ResolveItemNoData(connection, remoteItemInfo, SyncStatus.InsertConflict,
                                                                  remoteItemInfo.Modified);
                                conflicts.Add(new SyncConflict(itemId, SyncStatus.InsertConflict, changedItemInfo,
                                                               remoteItemInfo));
                                break;
                            }
                        }
                    }
                }
            }
            return(conflicts);
        }