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 bool HandleNewObject(object obj, IReplicationReference ownerRef, IReplicationProviderInside owner, IReplicationProviderInside other, object referencingObject, string fieldName , bool needsToBeActivated, bool listenerAlreadyNotified) { if (_directionTo == owner) { return(false); } if (needsToBeActivated) { owner.Activate(obj); } if (!listenerAlreadyNotified) { _event.ResetAction(); _event.Conflict(false); _event._creationDate = TimeStampIdGenerator.IdToMilliseconds(ownerRef.Uuid().GetLongPart ()); if (owner == _providerA) { _stateInA.SetAll(obj, true, false, ObjectStateImpl.Unknown); _stateInB.SetAll(null, false, false, ObjectStateImpl.Unknown); } else { _stateInA.SetAll(null, false, false, ObjectStateImpl.Unknown); _stateInB.SetAll(obj, true, false, ObjectStateImpl.Unknown); } if (_listener != null) { _listener.OnReplicate(_event); if (_event._actionWasChosen) { if (_event._actionChosenState == null) { return(false); } if (_event._actionChosenState.GetObject() != obj) { return(false); } } } } object counterpart = EmptyClone(owner, obj); ownerRef.SetCounterpart(counterpart); ownerRef.MarkForReplicating(true); IReplicationReference otherRef = other.ReferenceNewObject(counterpart, ownerRef, GetCounterpartRef(referencingObject), fieldName); otherRef.SetCounterpart(obj); PutCounterpartRef(obj, otherRef); if (_event._actionShouldStopTraversal) { return(false); } return(true); }
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 DeleteInDestination(IReplicationReference reference, IReplicationProviderInside destination) { if (!reference.IsMarkedForDeleting()) { return; } destination.ReplicateDeletion(reference.Uuid()); }
public virtual void StoreReplica(object obj) { IReplicationReference @ref = GetCachedReference(obj); if (@ref == null) { throw new Exception(); } Store(obj, @ref.Uuid(), @ref.Version()); }
public virtual IReplicationReference ReferenceNewObject(object obj, IReplicationReference counterpartReference, IReplicationReference unused, string unused2) { //System.out.println("referenceNewObject: " + obj + " UUID: " + counterpartReference.uuid()); IDrsUUID uuid = counterpartReference.Uuid(); long version = counterpartReference.Version(); if (GetObject(uuid) != null) { throw new Exception("Object exists already."); } IReplicationReference result = CreateReferenceFor(obj); Store(obj, uuid, version); return(result); }
public virtual void Test() { SPCChild child = StoreInA(); Replicate(); IReplicationReference @ref = A().Provider().ProduceReference(child); B().Provider().ClearAllReferences(); IDrsUUID expectedUuid = @ref.Uuid(); IReplicationReference referenceByUUID = B().Provider().ProduceReferenceByUUID(expectedUuid , null); Assert.IsNotNull(referenceByUUID); IDrsUUID actualUuid = referenceByUUID.Uuid(); Assert.AreEqual(expectedUuid.GetLongPart(), actualUuid.GetLongPart()); }
public virtual IReplicationReference ReferenceNewObject(object obj, IReplicationReference counterpartReference, IReplicationReference referencingObjCounterPartRef, string fieldName) { IDrsUUID uuid = counterpartReference.Uuid(); if (uuid == null) { return(null); } byte[] signature = uuid.GetSignaturePart(); long longPart = uuid.GetLongPart(); long version = counterpartReference.Version(); Db4oDatabase db = _signatureMap.Produce(signature, 0); Db4oReplicationReferenceImpl @ref = new Db4oReplicationReferenceImpl(obj, db, longPart , version); AddReference(@ref); return(@ref); }
private bool HandleMissingObjectInOther(object obj, IReplicationReference ownerRef , IReplicationProviderInside owner, IReplicationProviderInside other, object referencingObject , string fieldName) { bool isConflict = false; bool wasModified = owner.WasModifiedSinceLastReplication(ownerRef); if (wasModified) { isConflict = true; } if (_directionTo == other) { isConflict = true; } object prevailing = null; //by default, deletion prevails if (isConflict) { owner.Activate(obj); } _event.ResetAction(); _event.Conflict(isConflict); _event._creationDate = TimeStampIdGenerator.IdToMilliseconds(ownerRef.Uuid().GetLongPart ()); long modificationDate = TimeStampIdGenerator.IdToMilliseconds(ownerRef.Version()); if (owner == _providerA) { _stateInA.SetAll(obj, false, wasModified, modificationDate); _stateInB.SetAll(null, false, false, ObjectStateImpl.Unknown); } else { //owner == _providerB _stateInA.SetAll(null, false, false, ObjectStateImpl.Unknown); _stateInB.SetAll(obj, false, wasModified, modificationDate); } _listener.OnReplicate(_event); if (isConflict && !_event._actionWasChosen) { ThrowReplicationConflictException(); } if (_event._actionWasChosen) { if (_event._actionChosenState == null) { return(false); } if (_event._actionChosenState == _stateInA) { prevailing = _stateInA.GetObject(); } if (_event._actionChosenState == _stateInB) { prevailing = _stateInB.GetObject(); } } if (prevailing == null) { //Deletion has prevailed. if (_directionTo == other) { return(false); } ownerRef.MarkForDeleting(); return(!_event._actionShouldStopTraversal); } bool needsToBeActivated = !isConflict; //Already activated if there was a conflict. return(HandleNewObject(obj, ownerRef, owner, other, referencingObject, fieldName, needsToBeActivated, true)); }
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 IReplicationReference ReferenceNewObject(object obj, IReplicationReference counterpartReference, IReplicationReference referencingObjCounterPartRef, string fieldName) { IDrsUUID uuid = counterpartReference.Uuid(); if (uuid == null) { return null; } byte[] signature = uuid.GetSignaturePart(); long longPart = uuid.GetLongPart(); long version = counterpartReference.Version(); Db4oDatabase db = _signatureMap.Produce(signature, 0); Db4oReplicationReferenceImpl @ref = new Db4oReplicationReferenceImpl(obj, db, longPart , version); AddReference(@ref); return @ref; }
private bool HandleNewObject(object obj, IReplicationReference ownerRef, IReplicationProviderInside owner, IReplicationProviderInside other, object referencingObject, string fieldName , bool needsToBeActivated, bool listenerAlreadyNotified) { if (_directionTo == owner) { return false; } if (needsToBeActivated) { owner.Activate(obj); } if (!listenerAlreadyNotified) { _event.ResetAction(); _event._isConflict = false; _event._creationDate = TimeStampIdGenerator.IdToMilliseconds(ownerRef.Uuid().GetLongPart ()); if (owner == _providerA) { _stateInA.SetAll(obj, true, false, -1); _stateInB.SetAll(null, false, false, -1); } else { _stateInA.SetAll(null, false, false, -1); _stateInB.SetAll(obj, true, false, -1); } if (_listener != null) { _listener.OnReplicate(_event); if (_event._actionWasChosen) { if (_event._actionChosenState == null) { return false; } if (_event._actionChosenState.GetObject() != obj) { return false; } } } } object counterpart = EmptyClone(owner, obj); ownerRef.SetCounterpart(counterpart); ownerRef.MarkForReplicating(true); IReplicationReference otherRef = other.ReferenceNewObject(counterpart, ownerRef, GetCounterpartRef(referencingObject), fieldName); otherRef.SetCounterpart(obj); PutCounterpartRef(obj, otherRef); if (_event._actionShouldStopTraversal) { return false; } return true; }
private bool HandleMissingObjectInOther(object obj, IReplicationReference ownerRef , IReplicationProviderInside owner, IReplicationProviderInside other, object referencingObject , string fieldName) { bool isConflict = false; bool wasModified = owner.WasModifiedSinceLastReplication(ownerRef); if (wasModified) { isConflict = true; } if (_directionTo == other) { isConflict = true; } object prevailing = null; //by default, deletion prevails if (isConflict) { owner.Activate(obj); } _event.ResetAction(); _event._isConflict = isConflict; _event._creationDate = TimeStampIdGenerator.IdToMilliseconds(ownerRef.Uuid().GetLongPart ()); long modificationDate = TimeStampIdGenerator.IdToMilliseconds(ownerRef.Version()); if (owner == _providerA) { _stateInA.SetAll(obj, false, wasModified, modificationDate); _stateInB.SetAll(null, false, false, -1); } else { //owner == _providerB _stateInA.SetAll(null, false, false, -1); _stateInB.SetAll(obj, false, wasModified, modificationDate); } _listener.OnReplicate(_event); if (isConflict && !_event._actionWasChosen) { ThrowReplicationConflictException(); } if (_event._actionWasChosen) { if (_event._actionChosenState == null) { return false; } if (_event._actionChosenState == _stateInA) { prevailing = _stateInA.GetObject(); } if (_event._actionChosenState == _stateInB) { prevailing = _stateInB.GetObject(); } } if (prevailing == null) { //Deletion has prevailed. if (_directionTo == other) { return false; } ownerRef.MarkForDeleting(); return !_event._actionShouldStopTraversal; } bool needsToBeActivated = !isConflict; //Already activated if there was a conflict. return HandleNewObject(obj, ownerRef, owner, other, referencingObject, fieldName, needsToBeActivated, true); }
public virtual IReplicationReference ReferenceNewObject(object obj, IReplicationReference counterpartReference, IReplicationReference unused, string unused2) { //System.out.println("referenceNewObject: " + obj + " UUID: " + counterpartReference.uuid()); IDrsUUID uuid = counterpartReference.Uuid(); long version = counterpartReference.Version(); if (GetObject(uuid) != null) { throw new Exception("Object exists already."); } IReplicationReference result = CreateReferenceFor(obj); Store(obj, uuid, version); return result; }