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);
        }
예제 #3
0
        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));
                }
            }
        }
예제 #4
0
 /// <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>()));
 }
예제 #5
0
        /// <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));
        }
예제 #6
0
        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();
            }
        }