internal ProcessTaskArgument(ShareManager shareManager, ShareDefinition shareDefinition) { shareManager.UpsertAndHydrate(this, shareDefinition); try { //if the import is into a repository other than the master original repository if (!shareManager.IsExportedObject(this.ProcessTask.LoadMetadata)) { //and we are a reference type e.g. to a ColumnInfo or something var t = GetConcreteSystemType(); if (typeof(IMapsDirectlyToDatabaseTable).IsAssignableFrom(t) || typeof(IEnumerable <IMapsDirectlyToDatabaseTable>).IsAssignableFrom(t)) { //then use the value Null because whatever ID is stored in us won't be pointing to the same object //as when we were exported! Value = null; SaveToDatabase(); } } } catch (Exception e) { //couldn't work out the Type, maybe it is broken or something, or otherwise someone elses problem Console.WriteLine(e); } }
internal ExternalDatabaseServer(ShareManager shareManager, ShareDefinition shareDefinition) { var repo = shareManager.RepositoryLocator.CatalogueRepository; Repository = repo; _selfCertifyingDataAccessPoint = new SelfCertifyingDataAccessPoint(CatalogueRepository, DatabaseType.MicrosoftSQLServer /*will get changed by UpsertAndHydrate*/); shareManager.UpsertAndHydrate(this, shareDefinition); }
/// <summary> /// Updates the user configurable (non ID) properties of the object <pararef name="o"/> to match the <paramref name="shareDefinition"/> /// </summary> /// <param name="o"></param> /// <param name="shareDefinition"></param> public void ImportPropertiesOnly(IMapsDirectlyToDatabaseTable o, ShareDefinition shareDefinition) { if (shareDefinition.Type != o.GetType()) { throw new Exception("Share Definition is not for a " + o.GetType()); } AttributePropertyFinder <RelationshipAttribute> relationshipPropertyFinder = new AttributePropertyFinder <RelationshipAttribute>(o); AttributePropertyFinder <DoNotImportDescriptionsAttribute> skipPropertyFinder = new AttributePropertyFinder <DoNotImportDescriptionsAttribute>(o); //for each property that isn't [NoMappingToDatabase] foreach (var kvp in shareDefinition.GetDictionaryForImport()) { if (kvp.Key == "Name") { continue; } var prop = o.GetType().GetProperty(kvp.Key); //If the property is a relationship e.g. _ID skip it if (relationshipPropertyFinder.GetAttribute(prop) != null) { continue; } //do we skip this property? var skip = skipPropertyFinder.GetAttribute(prop); if (skip != null) { //yes but only if blank if (skip.AllowOverwriteIfBlank) { //is it currently not null? (if so skip) var oldVal = prop.GetValue(o); if (!(oldVal == DBNull.Value || oldVal == null || string.IsNullOrWhiteSpace(oldVal.ToString()))) { continue; } } else { continue; //always skip } } SetValue(prop, kvp.Value, o); } }
internal LoadMetadata(ShareManager shareManager, ShareDefinition shareDefinition) : base() { shareManager.UpsertAndHydrate(this, shareDefinition); }
internal CatalogueItem(ShareManager shareManager, ShareDefinition shareDefinition) { shareManager.UpsertAndHydrate(this, shareDefinition); }
private int?LocalReferenceGetter(PropertyInfo property, RelationshipAttribute relationshipAttribute, ShareDefinition shareDefinition) { MessageBox.Show("Choose a local object for '" + property + "' on " + Environment.NewLine + string.Join(Environment.NewLine, shareDefinition.Properties.Select(kvp => kvp.Key + ": " + kvp.Value))); var requiredType = relationshipAttribute.Cref; if (Activator.RepositoryLocator.CatalogueRepository.SupportsObjectType(requiredType)) { var selected = SelectOne(Activator.RepositoryLocator.CatalogueRepository.GetAllObjects(requiredType).Cast <DatabaseEntity>().ToArray()); if (selected != null) { return(selected.ID); } } if (Activator.RepositoryLocator.DataExportRepository.SupportsObjectType(requiredType)) { var selected = SelectOne(Activator.RepositoryLocator.DataExportRepository.GetAllObjects(requiredType).Cast <DatabaseEntity>().ToArray()); if (selected != null) { return(selected.ID); } } return(null); }
internal ProcessTask(ShareManager shareManager, ShareDefinition shareDefinition) { shareManager.UpsertAndHydrate(this, shareDefinition); }
internal Plugin(ShareManager shareManager, ShareDefinition shareDefinition) { shareManager.UpsertAndHydrate(this, shareDefinition); }
internal ANOTable(ShareManager shareManager, ShareDefinition shareDefinition) { shareManager.UpsertAndHydrate(this, shareDefinition); }
private int?LocalReferenceGetter(PropertyInfo property, RelationshipAttribute relationshipattribute, ShareDefinition sharedefinition) { if (property.Name.EndsWith("LoggingServer_ID")) { return(_loggingServer.ID); } throw new SharingException("Could not figure out a sensible value to assign to Property " + property); }
internal Catalogue(ShareManager shareManager, ShareDefinition shareDefinition) { shareManager.UpsertAndHydrate(this, shareDefinition); ClearAllInjections(); }
private int?DefaultLocalReferenceGetter(PropertyInfo property, RelationshipAttribute relationshipattribute, ShareDefinition sharedefinition) { var defaults = RepositoryLocator.CatalogueRepository.GetServerDefaults(); if (property.Name == "LiveLoggingServer_ID" || property.Name == "TestLoggingServer_ID") { var server = defaults.GetDefaultFor(PermissableDefaults.LiveLoggingServer_ID); if (server == null) { return(null); } return(server.ID); } throw new SharingException("No default implementation exists for LocalReferenceGetterDelegate for property " + property.Name); }
public void UpsertAndHydrate <T>(T toCreate, ShareDefinition shareDefinition) where T : class, IMapsDirectlyToDatabaseTable { IRepository repo; if (RepositoryLocator.CatalogueRepository.SupportsObjectType(typeof(T))) { repo = RepositoryLocator.CatalogueRepository; } else if (RepositoryLocator.DataExportRepository.SupportsObjectType(typeof(T))) { repo = RepositoryLocator.DataExportRepository; } else { throw new NotSupportedException("No Repository supported object type '" + typeof(T) + "'"); } //Make a dictionary of the normal properties we are supposed to be importing Dictionary <string, object> propertiesDictionary = shareDefinition.GetDictionaryForImport(); //for finding properties decorated with [Relationship] var finder = new AttributePropertyFinder <RelationshipAttribute>(toCreate); //If we have already got a local copy of this shared object? //either as an import or as an export T actual = (T)GetExistingImportObject(shareDefinition.SharingGuid) ?? (T)GetExistingExportObject(shareDefinition.SharingGuid); //we already have a copy imported of the shared object if (actual != null) { //It's an UPDATE i.e. take the new shared properties and apply them to the database copy / memory copy //copy all the values out of the share definition / database copy foreach (PropertyInfo prop in TableRepository.GetPropertyInfos(typeof(T))) { //don't update any ID columns or any with relationships on UPDATE if (propertiesDictionary.ContainsKey(prop.Name) && finder.GetAttribute(prop) == null) { SetValue(prop, propertiesDictionary[prop.Name], toCreate); } else { prop.SetValue(toCreate, prop.GetValue(actual)); //or use the database one if it isn't shared (e.g. ID, MyParent_ID etc) } } toCreate.Repository = actual.Repository; //commit the updated values to the database repo.SaveToDatabase(toCreate); } else { //It's an INSERT i.e. create a new database copy with the correct foreign key values and update the memory copy //for each relationship property on the class we are trying to hydrate foreach (PropertyInfo property in TableRepository.GetPropertyInfos(typeof(T))) { RelationshipAttribute relationshipAttribute = finder.GetAttribute(property); //if it has a relationship attribute then we would expect the ShareDefinition to include a dependency relationship with the sharing UID of the parent //and also that we had already imported it since dependencies must be imported in order if (relationshipAttribute != null) { int?newValue; switch (relationshipAttribute.Type) { case RelationshipType.OptionalSharedObject: case RelationshipType.SharedObject: //Confirm that the share definition includes the knowledge that theres a parent class to this object if (!shareDefinition.RelationshipProperties.ContainsKey(relationshipAttribute)) { //if it doesn't but the field is optional, ignore it if (relationshipAttribute.Type == RelationshipType.OptionalSharedObject) { newValue = null; break; } else { //otherwise we are missing a required shared object being referenced. That's bad news. throw new Exception("Share Definition for object of Type " + typeof(T) + " is missing an expected RelationshipProperty called " + property.Name); } } //Get the SharingUID of the parent for this property Guid importGuidOfParent = shareDefinition.RelationshipProperties[relationshipAttribute]; //Confirm that we have a local import of the parent var parentImport = GetExistingImport(importGuidOfParent); //if we don't have a share reference if (parentImport == null) { //and it isn't optional if (relationshipAttribute.Type == RelationshipType.SharedObject) { throw new Exception("Cannot import an object of type " + typeof(T) + " because the ShareDefinition specifies a relationship to an object that has not yet been imported (A " + relationshipAttribute.Cref + " with a SharingUID of " + importGuidOfParent); } else { newValue = null; //it was optional and missing so just set to null } } else { newValue = parentImport.ReferencedObjectID; //we have the shared object } break; case RelationshipType.LocalReference: newValue = GetLocalReference(property, relationshipAttribute, shareDefinition); break; case RelationshipType.IgnoreableLocalReference: newValue = null; break; default: throw new ArgumentOutOfRangeException(); } //get the ID of the local import of the parent if (propertiesDictionary.ContainsKey(property.Name)) { propertiesDictionary[property.Name] = newValue; } else { propertiesDictionary.Add(property.Name, newValue); } } } //insert the full dictionary into the database under the Type repo.InsertAndHydrate(toCreate, propertiesDictionary); //document that a local import of the share now exists and should be updated/reused from now on when that same GUID comes in / gets used by child objects GetImportAs(shareDefinition.SharingGuid.ToString(), toCreate); } }
/// <summary> /// When importing a <paramref name="shareDefinition"/> for a child class with a parent, this method will return the ID of parent for the given <paramref name="property"/> /// on the child. For example if you are importing a <see cref="ShareDefinition"/> for a <see cref="CatalogueItem"/> then the property <see cref="CatalogueItem.Catalogue_ID"/> should /// have the ID of the locally held <see cref="Catalogue"/> to which it will become a part of. /// </summary> /// <param name="property">The child class property you need to fill e.g. <see cref="CatalogueItem.Catalogue_ID"/></param> /// <param name="relationshipAttribute">The attribute that decorates the <paramref name="property"/> which indicates what type of object the parent is etc</param> /// <param name="shareDefinition">The serialization of the child you are trying to import</param> /// <returns></returns> public int?GetLocalReference(PropertyInfo property, RelationshipAttribute relationshipAttribute, ShareDefinition shareDefinition) { if (property.DeclaringType == null) { throw new Exception("DeclaringType on Property '" + property + "' is null"); } if (relationshipAttribute.Type != RelationshipType.LocalReference) { throw new Exception("Relationship was of Type " + relationshipAttribute.Type + " expected " + RelationshipType.LocalReference); } if (LocalReferenceGetter == null) { throw new Exception( string.Format("No LocalReferenceGetter has been set, cannot populate Property {0} {1}", property.Name, " on class " + property.DeclaringType.Name)); } return(LocalReferenceGetter(property, relationshipAttribute, shareDefinition)); }
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(); } }
internal LoadModuleAssembly(ShareManager shareManager, ShareDefinition shareDefinition) { shareManager.UpsertAndHydrate(this, shareDefinition); ClearAllInjections(); }