Example #1
0
        public override List <SyncOperation> GetSyncOperations(DBreeze.Transactions.Transaction tran, out bool repeatSync)
        {
            var syncList = new List <SyncOperation>();

            _newLocalSyncTimeStamp = DateTime.UtcNow.Ticks; //This value will be applied if there is nothing to synchronize
            repeatSync             = false;

            var changedEntities = new Dictionary <long, Tuple <long, bool> >();    //Key is entityId, Value is Synctimestamp
            var entityType      = typeof(T).FullName;

            var lastLocalSyncTimeStamp = tran.Select <byte[], long>(_entitySync.entityTable, new byte[] { LocalSyncTS, 1 }).Value;

            foreach (var row in
                     tran.SelectForwardFromTo <byte[], byte[]>(_entitySync.entityTable,
                                                               new byte[] { SyncLog }.ConcatMany((lastLocalSyncTimeStamp + 1).To_8_bytes_array_BigEndian(), long.MinValue.To_8_bytes_array_BigEndian()),
                                                               true, //true, but LastLocalSyncTimeStamp+1 is used
                                                               new byte[] { SyncLog }.ConcatMany(long.MaxValue.To_8_bytes_array_BigEndian(), long.MaxValue.To_8_bytes_array_BigEndian()),
                                                               true))
            {
                if (changedEntities.Count > _entitySync.LimitationOfEntitesPerRound)
                {
                    repeatSync = true;
                    break;
                }

                //We will leave only last update of the particular entity
                if (!changedEntities.TryGetValue(row.Key.Substring(9, 8).To_Int64_BigEndian(), out var tpl1))
                {
                    changedEntities[row.Key.Substring(9, 8).To_Int64_BigEndian()] = new Tuple <long, bool>(row.Key.Substring(1, 8).To_Int64_BigEndian(),
                                                                                                           (row.Value?.Length >= 1 && row.Value[0] == 1) ? true : false) //indicating that new entity was inserted
                    ;
                }
                else
                {
                    changedEntities[row.Key.Substring(9, 8).To_Int64_BigEndian()] = new Tuple <long, bool>(row.Key.Substring(1, 8).To_Int64_BigEndian(),
                                                                                                           (tpl1.Item2 || (row.Value?.Length >= 1 && row.Value[0] == 1)) ? true : false) //indicating that new entity was inserted (from any of inserts that must be done for the id)
                    ;
                }

                _newLocalSyncTimeStamp = row.Key.Substring(1, 8).To_Int64_BigEndian();
            }

            foreach (var ent in changedEntities.OrderBy(r => r.Key))
            {
                var rowEntity = tran.Select <byte[], byte[]>(_entitySync.entityTable, new byte[] { Entity }.Concat(ent.Key.To_8_bytes_array_BigEndian()));

                var syncOperation = new SyncOperation()
                {
                    ExternalId    = ent.Value.Item2 ? 0 : ent.Key, //if entity new ExternalId will be 0 otherwise will equal to InternalId and higher than 0
                    InternalId    = ent.Key,
                    Operation     = rowEntity.Exists ? SyncOperation.eOperation.INSERT : SyncOperation.eOperation.REMOVE,
                    Type          = entityType,
                    SyncTimestamp = ent.Value.Item1
                };
                if (rowEntity.Exists)
                {
                    syncOperation.SerializedObject = rowEntity.GetDataBlockWithFixedAddress <byte[]>();
                }
                syncList.Add(syncOperation);
            }
            return(syncList);
        }