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(); }
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()); }
private void CopyStateAcross(IReplicationReference sourceRef, IReplicationProviderInside sourceProvider, IReplicationProviderInside targetProvider) { if (!sourceRef.IsMarkedForReplicating()) { return; } CopyStateAcross(sourceRef.Object(), sourceRef.Counterpart(), sourceProvider, targetProvider ); }
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); }
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); }
public virtual void ReplicateDeletion(IReplicationReference reference) { Sharpen.Collections.Remove(_storedObjects, reference.Object()); }