private void TstStore()
        {
            StartReplication();
            Pilot    object1           = new Pilot("John Cleese", 42);
            IDrsUUID uuid              = new DrsUUIDImpl(new Db4oUUID(15, BSignatureBytes));
            IReplicationReference @ref = new ReplicationReferenceImpl("ignoredSinceInOtherProvider"
                                                                      , uuid, 1);

            A().Provider().ReferenceNewObject(object1, @ref, null, null);
            A().Provider().StoreReplica(object1);
            IReplicationReference reference = A().Provider().ProduceReferenceByUUID(uuid, object1
                                                                                    .GetType());

            Assert.AreEqual(reference, A().Provider().ProduceReference(object1, null, null));
            Assert.AreEqual(object1, reference.Object());
            CommitReplication();
            StartReplication();
            IEnumerator storedObjects = A().Provider().GetStoredObjects(typeof(Pilot)).GetEnumerator
                                            ();
            Pilot reloaded = (Pilot)Next(storedObjects);

            Assert.IsFalse(storedObjects.MoveNext());
            reference = A().Provider().ProduceReferenceByUUID(uuid, object1.GetType());
            Assert.AreEqual(reference, A().Provider().ProduceReference(reloaded, null, null));
            reloaded.SetName("i am updated");
            A().Provider().StoreReplica(reloaded);
            A().Provider().ClearAllReferences();
            CommitReplication();
            StartReplication();
            reference = A().Provider().ProduceReferenceByUUID(uuid, reloaded.GetType());
            Assert.AreEqual("i am updated", ((Pilot)reference.Object()).Name());
            CommitReplication();
            A().Provider().DeleteAllInstances(typeof(Pilot));
            A().Provider().Commit();
        }
        private void TstReferences()
        {
            Pilot pilot = new Pilot("tst References", 42);

            A().Provider().StoreNew(pilot);
            A().Provider().Commit();
            StartReplication();
            Pilot object1 = (Pilot)Next(A().Provider().GetStoredObjects(typeof(Pilot)).GetEnumerator
                                            ());
            IReplicationReference reference = A().Provider().ProduceReference(object1, null,
                                                                              null);

            Assert.AreEqual(object1, reference.Object());
            IDrsUUID uuid = reference.Uuid();
            IReplicationReference ref2 = A().Provider().ProduceReferenceByUUID(uuid, typeof(Pilot
                                                                                            ));

            Assert.AreEqual(reference, ref2);
            A().Provider().ClearAllReferences();
            IDrsUUID db4oUUID = A().Provider().ProduceReference(object1, null, null).Uuid();

            Assert.AreEqual(uuid, db4oUUID);
            CommitReplication();
            A().Provider().DeleteAllInstances(typeof(Pilot));
            A().Provider().Commit();
        }
示例#3
0
        private object FindCounterpart(object value, IReplicationProviderInside sourceProvider
                                       , IReplicationProviderInside targetProvider)
        {
            if (value == null)
            {
                return(null);
            }
            value = sourceProvider.ReplaceIfSpecific(value);
            // TODO: need to clone and findCounterpart of each reference object in the
            // struct
            if (ReplicationPlatform.IsValueType(value))
            {
                return(value);
            }
            IReflectClass claxx = _reflector.ForObject(value);

            if (claxx.IsArray())
            {
                return(ArrayClone(value, claxx, sourceProvider, targetProvider));
            }
            if (Platform4.IsTransient(claxx))
            {
                return(null);
            }
            // TODO: make it a warning
            if (_reflector.IsValueType(claxx))
            {
                return(value);
            }
            if (_collectionHandler.CanHandle(value))
            {
                return(CollectionClone(value, claxx, sourceProvider, targetProvider));
            }
            //if value is a Collection, result should be found by passing in just the value
            IReplicationReference @ref = sourceProvider.ProduceReference(value, null, null);

            if (@ref == null)
            {
                throw new InvalidOperationException("unable to find the ref of " + value + " of class "
                                                    + value.GetType());
            }
            object result = @ref.Counterpart();

            if (result != null)
            {
                return(result);
            }
            IReplicationReference targetRef = targetProvider.ProduceReferenceByUUID(@ref.Uuid
                                                                                        (), value.GetType());

            if (targetRef == null)
            {
                throw new InvalidOperationException("unable to find the counterpart of " + value
                                                    + " of class " + value.GetType());
            }
            return(targetRef.Object());
        }
示例#4
0
 private void CopyStateAcross(IReplicationReference sourceRef, IReplicationProviderInside
                              sourceProvider, IReplicationProviderInside targetProvider)
 {
     if (!sourceRef.IsMarkedForReplicating())
     {
         return;
     }
     CopyStateAcross(sourceRef.Object(), sourceRef.Counterpart(), sourceProvider, targetProvider
                     );
 }
示例#5
0
        private void CopyStateAcross(IReplicationReference sourceRef, IReplicationProviderInside
                                     sourceProvider, IReplicationProviderInside targetProvider)
        {
            if (!sourceRef.IsMarkedForReplicating())
            {
                return;
            }
            object source = sourceRef.Object();
            object target = sourceRef.Counterpart();

            if (source == null)
            {
                throw new InvalidOperationException("source may not be null");
            }
            if (target == null)
            {
                throw new InvalidOperationException("target may not be null");
            }
            CopyStateAcross(source, target, sourceProvider, targetProvider);
        }
示例#6
0
        private bool PrepareObjectToBeReplicated(object obj, object referencingObject, string
                                                 fieldName)
        {
            //TODO Optimization: keep track of the peer we are traversing to avoid having to look in both.
            Logger4Support.LogIdentity(obj);
            _obj = obj;
            _referencingObject = referencingObject;
            _fieldName         = fieldName;
            IReplicationReference refA = _providerA.ProduceReference(_obj, _referencingObject
                                                                     , _fieldName);
            IReplicationReference refB = _providerB.ProduceReference(_obj, _referencingObject
                                                                     , _fieldName);

            if (refA == null && refB == null)
            {
                throw new Exception(string.Empty + _obj.GetType() + " " + _obj + " must be stored in one of the databases being replicated."
                                    );
            }
            //FIXME: Use db4o's standard for throwing exceptions.
            if (refA != null && refB != null)
            {
                throw new Exception(string.Empty + _obj.GetType() + " " + _obj + " cannot be referenced by both databases being replicated."
                                    );
            }
            //FIXME: Use db4o's standard for throwing exceptions.
            IReplicationProviderInside owner    = refA == null ? _providerB : _providerA;
            IReplicationReference      ownerRef = refA == null ? refB : refA;
            IReplicationProviderInside other    = Other(owner);
            IDrsUUID uuid = ownerRef.Uuid();
            IReplicationReference otherRef = other.ProduceReferenceByUUID(uuid, _obj.GetType(
                                                                              ));

            if (refA == null)
            {
                refA = otherRef;
            }
            else
            {
                refB = otherRef;
            }
            //TODO for circular referenced object, otherRef should not be null in the subsequent pass.
            //But db4o always return null. A bug. check!
            if (otherRef == null)
            {
                //Object is only present in one ReplicationProvider. Missing in the other. Could have been deleted or never replicated.
                if (WasProcessed(uuid))
                {
                    IReplicationReference otherProcessedRef = other.ProduceReferenceByUUID(uuid, _obj
                                                                                           .GetType());
                    if (otherProcessedRef != null)
                    {
                        ownerRef.SetCounterpart(otherProcessedRef.Object());
                    }
                    return(false);
                }
                MarkAsProcessed(uuid);
                long creationTime = ownerRef.Uuid().GetLongPart();
                if (creationTime > owner.TimeStamps().From())
                {
                    //if it was created after the last time two ReplicationProviders were replicated it has to be treated as new.
                    if (_isReplicatingOnlyDeletions)
                    {
                        return(false);
                    }
                    return(HandleNewObject(_obj, ownerRef, owner, other, _referencingObject, _fieldName
                                           , true, false));
                }
                else
                {
                    // If it was created before the last time two ReplicationProviders were replicated it has to be treated as deleted.
                    // No, not always, in a three-way replication setup it can also be new.
                    return(HandleMissingObjectInOther(_obj, ownerRef, owner, other, _referencingObject
                                                      , _fieldName));
                }
            }
            if (_isReplicatingOnlyDeletions)
            {
                return(false);
            }
            ownerRef.SetCounterpart(otherRef.Object());
            otherRef.SetCounterpart(ownerRef.Object());
            if (WasProcessed(uuid))
            {
                return(false);
            }
            //Has to be done AFTER the counterpart is set because object yet to be replicated might reference the current one, replicated previously.
            MarkAsProcessed(uuid);
            object objectA    = refA.Object();
            object objectB    = refB.Object();
            bool   changedInA = _providerA.WasModifiedSinceLastReplication(refA);
            //System.out.println("changedInA = " + changedInA);
            bool changedInB = _providerB.WasModifiedSinceLastReplication(refB);

            //System.out.println("changedInB = " + changedInB);
            if (!changedInA && !changedInB)
            {
                return(false);
            }
            bool conflict = false;

            if (changedInA && changedInB)
            {
                conflict = true;
            }
            if (changedInA && _directionTo == _providerA)
            {
                conflict = true;
            }
            if (changedInB && _directionTo == _providerB)
            {
                conflict = true;
            }
            object prevailing = _obj;

            _providerA.Activate(objectA);
            _providerB.Activate(objectB);
            _event.ResetAction();
            _event.Conflict(conflict);
            _event._creationDate = TimeStampIdGenerator.IdToMilliseconds(uuid.GetLongPart());
            _stateInA.SetAll(objectA, false, changedInA, TimeStampIdGenerator.IdToMilliseconds
                                 (ownerRef.Version()));
            _stateInB.SetAll(objectB, false, changedInB, TimeStampIdGenerator.IdToMilliseconds
                                 (otherRef.Version()));
            _listener.OnReplicate(_event);
            if (conflict)
            {
                if (!_event._actionWasChosen)
                {
                    ThrowReplicationConflictException();
                }
                if (_event._actionChosenState == null)
                {
                    return(false);
                }
                if (_event._actionChosenState == _stateInA)
                {
                    prevailing = objectA;
                }
                if (_event._actionChosenState == _stateInB)
                {
                    prevailing = objectB;
                }
            }
            else
            {
                if (_event._actionWasChosen)
                {
                    if (_event._actionChosenState == _stateInA)
                    {
                        prevailing = objectA;
                    }
                    if (_event._actionChosenState == _stateInB)
                    {
                        prevailing = objectB;
                    }
                    if (_event._actionChosenState == null)
                    {
                        return(false);
                    }
                }
                else
                {
                    if (changedInA)
                    {
                        prevailing = objectA;
                    }
                    if (changedInB)
                    {
                        prevailing = objectB;
                    }
                }
            }
            IReplicationProviderInside prevailingPeer = prevailing == objectA ? _providerA :
                                                        _providerB;

            if (_directionTo == prevailingPeer)
            {
                return(false);
            }
            if (!conflict)
            {
                prevailingPeer.Activate(prevailing);
            }
            //Already activated if there was a conflict.
            if (prevailing != _obj)
            {
                otherRef.SetCounterpart(_obj);
                otherRef.MarkForReplicating(true);
                MarkAsNotProcessed(uuid);
                _traverser.ExtendTraversalTo(prevailing);
            }
            else
            {
                //Now we start traversing objects on the other peer! Is that cool or what? ;)
                ownerRef.MarkForReplicating(true);
            }
            return(!_event._actionShouldStopTraversal);
        }
		private void CopyStateAcross(IReplicationReference sourceRef, IReplicationProviderInside
			 sourceProvider, IReplicationProviderInside targetProvider)
		{
			if (!sourceRef.IsMarkedForReplicating())
			{
				return;
			}
			object source = sourceRef.Object();
			object target = sourceRef.Counterpart();
			if (source == null)
			{
				throw new InvalidOperationException("source may not be null");
			}
			if (target == null)
			{
				throw new InvalidOperationException("target may not be null");
			}
			CopyStateAcross(source, target, sourceProvider, targetProvider);
		}
		public virtual void ReplicateDeletion(IReplicationReference reference)
		{
			Sharpen.Collections.Remove(_storedObjects, reference.Object());
		}
		private void CopyStateAcross(IReplicationReference sourceRef, IReplicationProviderInside
			 sourceProvider, IReplicationProviderInside targetProvider)
		{
			if (!sourceRef.IsMarkedForReplicating())
			{
				return;
			}
			CopyStateAcross(sourceRef.Object(), sourceRef.Counterpart(), sourceProvider, targetProvider
				);
		}
示例#10
0
 public virtual void ReplicateDeletion(IReplicationReference reference)
 {
     Sharpen.Collections.Remove(_storedObjects, reference.Object());
 }