public void TestPruning() { Catalogue c = new Catalogue(CatalogueRepository, "Catapault"); var ci = new CatalogueItem(CatalogueRepository, c, "string"); Catalogue c2 = new Catalogue(CatalogueRepository, "Catapault (Import)"); var ci2 = new CatalogueItem(CatalogueRepository, c2, "string (Import)"); Assert.AreEqual(CatalogueRepository.GetAllObjects <ObjectExport>().Count(), 0); var ec = _share.GetNewOrExistingExportFor(c); var eci = _share.GetNewOrExistingExportFor(ci); _share.GetImportAs(ec.SharingUID, c2); _share.GetImportAs(eci.SharingUID, ci2); Assert.AreEqual(2, CatalogueRepository.GetAllObjects <ObjectExport>().Count()); Assert.AreEqual(2, CatalogueRepository.GetAllObjects <ObjectImport>().Count()); Assert.AreEqual(2, CatalogueRepository.GetAllObjects <ObjectImport>().Count());//successive calls shouldhn't generate extra entries since they are same obj Assert.AreEqual(2, CatalogueRepository.GetAllObjects <ObjectImport>().Count()); //cannot delete the shared object Assert.Throws <Exception>(c.DeleteInDatabase); //can delete the import because that's ok Assert.DoesNotThrow(c2.DeleteInDatabase); //now that we deleted the import it should have deleted everything else including the CatalogueItem import which magically disapeared when we deleted the Catalogue via database level cascade events Assert.AreEqual(0, CatalogueRepository.GetAllObjects <ObjectImport>().Count()); _share.GetImportAs(eci.SharingUID, ci2); }
private void AuditParenthood(IMapsDirectlyToDatabaseTable parent, IMapsDirectlyToDatabaseTable child) { //make it shareable var export = _shareManager.GetNewOrExistingExportFor(parent); //share it to yourself where the child is the realisation of the share (this creates relationship in database) _shareManager.GetImportAs(export.SharingUID, child); //record in memory dictionary _parenthoodDictionary.Add(parent, child); }
private void EnsureNotAlreadySharedLocally <T>(ICheckNotifier notifier, T m) where T : IMapsDirectlyToDatabaseTable { if (_shareManager.IsExportedObject(m)) { var existingExport = _shareManager.GetNewOrExistingExportFor(m); var existingImportReference = _shareManager.GetExistingImport(existingExport.SharingUID); if (existingImportReference != null) { T existingImportInstance = m.Repository.GetObjectByID <T>(existingImportReference.ReferencedObjectID); notifier.OnCheckPerformed(new CheckEventArgs(typeof(T) + " '" + m + "' is already locally shared as '" + existingImportInstance + "'", CheckResult.Fail)); } } }
/// <inheritdoc cref="WhenIHaveA{T}()"/> protected ObjectExport WhenIHaveA <T>(out ShareManager shareManager) where T : ObjectExport { shareManager = new ShareManager(new RepositoryProvider(Repository)); return(shareManager.GetNewOrExistingExportFor(WhenIHaveA <Catalogue>())); }
/// <summary> /// Creates a sharing export (<see cref="ObjectExport"/>) for the current <see cref="GatheredObject.Object"/> and then serializes it as a <see cref="ShareDefinition"/>. /// This includes mapping any [<see cref="RelationshipAttribute"/>] properties on the <see cref="GatheredObject.Object"/> to the relevant Share Guid (which must /// exist in branchParents). /// /// <para>ToShareDefinitionWithChildren if you want a full list of shares for the whole tree</para> /// </summary> /// <param name="shareManager"></param> /// <param name="branchParents"></param> /// <returns></returns> public ShareDefinition ToShareDefinition(ShareManager shareManager, List <ShareDefinition> branchParents) { var export = shareManager.GetNewOrExistingExportFor(Object); Dictionary <string, object> properties = new Dictionary <string, object>(); Dictionary <RelationshipAttribute, Guid> relationshipProperties = new Dictionary <RelationshipAttribute, Guid>(); AttributePropertyFinder <RelationshipAttribute> relationshipFinder = new AttributePropertyFinder <RelationshipAttribute>(Object); AttributePropertyFinder <NoMappingToDatabase> noMappingFinder = new AttributePropertyFinder <NoMappingToDatabase>(Object); //for each property in the Object class foreach (PropertyInfo property in Object.GetType().GetProperties()) { //if it's the ID column skip it if (property.Name == "ID") { continue; } //skip [NoMapping] columns if (noMappingFinder.GetAttribute(property) != null) { continue; } //skip IRepositories (these tell you where the object came from) if (typeof(IRepository).IsAssignableFrom(property.PropertyType)) { continue; } RelationshipAttribute attribute = relationshipFinder.GetAttribute(property); //if it's a relationship to a shared object if (attribute != null && (attribute.Type == RelationshipType.SharedObject || attribute.Type == RelationshipType.OptionalSharedObject)) { var idOfParent = property.GetValue(Object); Type typeOfParent = attribute.Cref; var parent = branchParents.SingleOrDefault(d => d.Type == typeOfParent && d.ID.Equals(idOfParent)); //if the parent is not being shared along with us if (parent == null) { //if a reference is required (i.e. not optional) if (attribute.Type != RelationshipType.OptionalSharedObject) { throw new SharingException("Property " + property + " on Type " + Object.GetType() + " is marked [Relationship] but we found no ShareDefinition amongst the current objects parents to satisfy this property"); } } else { relationshipProperties.Add(attribute, parent.SharingGuid); } } else { properties.Add(property.Name, property.GetValue(Object)); } } return(new ShareDefinition(export.SharingUIDAsGuid, Object.ID, Object.GetType(), properties, relationshipProperties)); }
public void GatherAndShare_ANOTable_Test(bool goViaJson) { var anoserver = new ExternalDatabaseServer(CatalogueRepository, "MyGatherAndShareTestANOServer", new ANOStorePatcher()); var anoTable = new ANOTable(CatalogueRepository, anoserver, "ANOMagad", "N"); Assert.AreEqual(anoTable.Server_ID, anoserver.ID); Gatherer g = new Gatherer(RepositoryLocator); Assert.IsTrue(g.CanGatherDependencies(anoTable)); var gObj = g.GatherDependencies(anoTable); //root should be the server Assert.AreEqual(gObj.Object, anoserver); Assert.AreEqual(gObj.Children.Single().Object, anoTable); //get the sharing definitions var shareManager = new ShareManager(RepositoryLocator); ShareDefinition defParent = gObj.ToShareDefinition(shareManager, new List <ShareDefinition>()); ShareDefinition defChild = gObj.Children.Single().ToShareDefinition(shareManager, new List <ShareDefinition>(new [] { defParent })); //make it look like we never had it in the first place shareManager.GetNewOrExistingExportFor(anoserver).DeleteInDatabase(); shareManager.GetNewOrExistingExportFor(anoTable).DeleteInDatabase(); anoTable.DeleteInDatabase(); anoserver.DeleteInDatabase(); if (goViaJson) { var sParent = JsonConvertExtensions.SerializeObject(defParent, RepositoryLocator); var sChild = JsonConvertExtensions.SerializeObject(defChild, RepositoryLocator); defParent = (ShareDefinition)JsonConvertExtensions.DeserializeObject(sParent, typeof(ShareDefinition), RepositoryLocator); defChild = (ShareDefinition)JsonConvertExtensions.DeserializeObject(sChild, typeof(ShareDefinition), RepositoryLocator); } var anoserverAfter = new ExternalDatabaseServer(shareManager, defParent); Assert.IsTrue(anoserverAfter.Exists()); //new instance Assert.AreNotEqual(anoserverAfter.ID, anoserver.ID); //same properties Assert.AreEqual(anoserverAfter.Name, anoserver.Name); Assert.AreEqual(anoserverAfter.CreatedByAssembly, anoserver.CreatedByAssembly); Assert.AreEqual(anoserverAfter.Database, anoserver.Database); Assert.AreEqual(anoserverAfter.DatabaseType, anoserver.DatabaseType); Assert.AreEqual(anoserverAfter.Username, anoserver.Username); Assert.AreEqual(anoserverAfter.Password, anoserver.Password); var anoTableAfter = new ANOTable(shareManager, defChild); //new instance Assert.AreNotEqual(anoTableAfter.ID, anoTable.ID); Assert.AreNotEqual(anoTableAfter.Server_ID, anoTable.Server_ID); //same properties Assert.AreEqual(anoTableAfter.NumberOfCharactersToUseInAnonymousRepresentation, anoTable.NumberOfCharactersToUseInAnonymousRepresentation); Assert.AreEqual(anoTableAfter.Suffix, anoTable.Suffix); //change a property and save it anoTableAfter.Suffix = "CAMMELS!"; CatalogueRepository.SaveToDatabase(anoTableAfter); //anoTableAfter.SaveToDatabase(); <- this decides to go check the ANOTable exists on the server refernced which is immaginary btw >< thats why we have the above line instead //reimport (this time it should be an update, we import the share definitions and it overrdies our database copy (sharing is UPSERT) var anoTableAfter2 = new ANOTable(shareManager, defChild); Assert.AreEqual(anoTableAfter.ID, anoTableAfter2.ID); Assert.AreEqual("N", anoTableAfter2.Suffix); Assert.AreEqual(ChangeDescription.DatabaseCopyDifferent, anoTableAfter.HasLocalChanges().Evaluation); anoTableAfter.DeleteInDatabase(); anoserverAfter.DeleteInDatabase(); foreach (ObjectImport o in RepositoryLocator.CatalogueRepository.GetAllObjects <ObjectImport>()) { o.DeleteInDatabase(); } }