예제 #1
0
 public EntityImpl()
 {
     Key = new EntityKeyImpl();
     Generator = new EntityGenerator("assigned");
     Cache = new Cache()
     {
         Include = Cache.IncludeTypes.All,
         Region = "",
         Usage = Cache.UsageTypes.None
     };
     Discriminator = new Discriminator();
 }
예제 #2
0
 public EntityImpl()
 {
     Key       = new EntityKeyImpl();
     Generator = new EntityGenerator("assigned");
     Cache     = new Cache()
     {
         Include = Cache.IncludeTypes.All,
         Region  = "",
         Usage   = Cache.UsageTypes.None
     };
     Discriminator = new Discriminator();
 }
예제 #3
0
        public Discriminator DeserialiseDiscriminator(XmlNode discriminatorNode)
        {
            NodeProcessor processor = new NodeProcessor(discriminatorNode);

            Discriminator discriminator = new Discriminator();

            discriminator.AllowNull         = processor.GetBool("AllowNull");
            discriminator.ColumnName        = processor.GetString("ColumnName");
            discriminator.DiscriminatorType = (Enums.DiscriminatorTypes)Enum.Parse(typeof(Enums.DiscriminatorTypes), processor.GetString("DiscriminatorType"), true);
            discriminator.Force             = processor.GetBool("Force");
            discriminator.Formula           = processor.GetString("Formula");
            discriminator.Insert            = processor.GetBool("Insert");
            return(discriminator);
        }
예제 #4
0
        public MappingSet GetEntities(IEnumerable<string> hbmFiles, ParseResults parseResults, IDatabase database)
        {
            EntitySet entities = new EntitySetImpl();
            MappingSet mappingSet = new MappingSetImpl(database, entities);
            Dictionary<Class, ComponentSpecification> existingComponentSpecs = new Dictionary<Class, ComponentSpecification>();

            List<hibernatemapping> mappingFiles = new List<hibernatemapping>();
            List<ValidationEventArgs> mappingErrors = new List<ValidationEventArgs>();
            List<NHibernateLoaderException.HbmXmlFile> errorFiles = new List<NHibernateLoaderException.HbmXmlFile>();

            GetMappingFiles(hbmFiles, mappingFiles, mappingErrors, errorFiles);

            if (errorFiles.Count > 0)
                throw new NHibernateLoaderException(string.Format("Unsupported Elements found in HBM file."), errorFiles, mappingErrors);

            foreach (var hm in mappingFiles)
            {
                ArchAngel.Interfaces.SharedData.CurrentProject.SetUserOption("AutoImport", hm.autoimport);
                ArchAngel.Interfaces.SharedData.CurrentProject.SetUserOption("DefaultAccess", (TopLevelAccessTypes)Enum.Parse(typeof(TopLevelAccessTypes), hm.defaultaccess));
                ArchAngel.Interfaces.SharedData.CurrentProject.SetUserOption("DefaultCascade", (TopLevelCascadeTypes)Enum.Parse(typeof(TopLevelCascadeTypes), hm.defaultcascade.Replace("-", "_"), true));
                ArchAngel.Interfaces.SharedData.CurrentProject.SetUserOption("DefaultLazy", hm.defaultlazy);
                ArchAngel.Interfaces.SharedData.CurrentProject.SetUserOption("ProjectNamespace", hm.@namespace);

                foreach (var hClass in hm.Classes())
                {
                    Entity newEntity;
                    string @namespace;
                    string name;

                    if (IsNameFullyQualified(hClass.name, out @namespace, out name))
                    {
                        newEntity = new EntityImpl(name);

                        string currentNamespace = ArchAngel.Interfaces.SharedData.CurrentProject.GetUserOption("ProjectNamespace") == null ? "" : ArchAngel.Interfaces.SharedData.CurrentProject.GetUserOption("ProjectNamespace").ToString();

                        if (string.IsNullOrWhiteSpace(currentNamespace))
                            ArchAngel.Interfaces.SharedData.CurrentProject.SetUserOption("ProjectNamespace", @namespace);
                    }
                    else
                        newEntity = new EntityImpl(hClass.name);

                    if (entities.GetEntity(newEntity.Name) != null)
                        // This entity has already been added - the existing project probably has both HBM XML and Fluent mappings.
                        continue;

                    if (hClass.lazySpecified)
                        newEntity.SetEntityLazy(hClass.lazy);
                    else
                        newEntity.SetEntityLazy(hm.defaultlazy);

                    newEntity.SetEntitySqlWhereClause(hClass.where);
                    newEntity.SetEntityDynamicInsert(hClass.dynamicinsert);
                    newEntity.SetEntityDynamicUpdate(hClass.dynamicupdate);
                    newEntity.SetEntityMutable(hClass.mutable);
                    newEntity.SetEntityOptimisticLock((OptimisticLockModes)Enum.Parse(typeof(OptimisticLockModes), hClass.optimisticlock.ToString(), true));
                    newEntity.SetEntityProxy(hClass.proxy);
                    newEntity.SetEntitySelectBeforeUpdate(hClass.selectbeforeupdate);
                    newEntity.SetEntityBatchSize(hClass.batchsize);

                    if (hClass.abstractSpecified)
                        newEntity.IsAbstract = hClass.@abstract;

                    newEntity.SetEntityPersister(hClass.persister);
                    Mapping mapping = null;

                    if (!newEntity.IsAbstract)
                        mapping = CreateMappingFor(newEntity, hClass, database, hm.schema);

                    entities.AddEntity(newEntity);

                    if (mapping != null)
                        mappingSet.AddMapping(mapping);

                    #region Cache
                    if (hClass.cache != null)
                    {
                        newEntity.Cache = new Cache();

                        switch (hClass.cache.include)
                        {
                            case cacheInclude.all:
                                newEntity.Cache.Include = Cache.IncludeTypes.All;
                                break;
                            case cacheInclude.nonlazy:
                                newEntity.Cache.Include = Cache.IncludeTypes.Non_Lazy;
                                break;
                            default:
                                throw new NotImplementedException("Unexpected cache include value:" + hClass.cache.include.ToString());
                        }
                        newEntity.Cache.Region = hClass.cache.region;

                        switch (hClass.cache.usage)
                        {
                            case cacheUsage.nonstrictreadwrite:
                                newEntity.Cache.Usage = Cache.UsageTypes.NonStrict_Read_Write;
                                break;
                            case cacheUsage.@readonly:
                                newEntity.Cache.Usage = Cache.UsageTypes.Read_Only;
                                break;
                            case cacheUsage.readwrite:
                                newEntity.Cache.Usage = Cache.UsageTypes.Read_Write;
                                break;
                            case cacheUsage.transactional:
                                newEntity.Cache.Usage = Cache.UsageTypes.Transactional;
                                break;
                            default:
                                throw new NotImplementedException("Unexpected cache usage value:" + hClass.cache.usage.ToString());
                        }
                    }
                    #endregion

                    #region Discriminator
                    if (hClass.discriminator != null)
                    {
                        ArchAngel.Providers.EntityModel.Model.EntityLayer.Discriminator d = new Discriminator()
                        {
                            AllowNull = !hClass.discriminator.notnull,
                            ColumnName = hClass.discriminator.column,
                            DiscriminatorType = string.IsNullOrWhiteSpace(hClass.discriminator.column) ? ArchAngel.Providers.EntityModel.Model.Enums.DiscriminatorTypes.Formula : ArchAngel.Providers.EntityModel.Model.Enums.DiscriminatorTypes.Column,
                            Force = hClass.discriminator.force,
                            Formula = hClass.discriminator.formula,
                            Insert = hClass.discriminator.insert
                        };
                        newEntity.Discriminator = d;
                        newEntity.DiscriminatorValue = d.DiscriminatorType == Enums.DiscriminatorTypes.Column ? hClass.discriminator.column : hClass.discriminator.formula;

                        //string columnName = hClass.discriminator.column;

                        //throw new NotImplementedException("TODO: fixup discriminator stuff");
                        //Grouping g = new AndGrouping();
                        //IColumn column = newEntity.MappedTables().First().Columns.Single(c => c.Name == columnName);
                        //ArchAngel.Providers.EntityModel.Model.DatabaseLayer.Discrimination.Operator op = ArchAngel.Providers.EntityModel.Model.DatabaseLayer.Discrimination.Operator.Equal;
                        //string discriminatorValue = string.IsNullOrWhiteSpace(hClass.discriminatorvalue) ? "" : hClass.discriminatorvalue;

                        //ExpressionValue value = new ExpressionValueImpl(discriminatorValue);

                        //if (column != null && op != null && value != null)
                        //    g.AddCondition(new ConditionImpl(column, op, value));

                        //if (newEntity.Discriminator == null)
                        //    newEntity.Discriminator = new DiscriminatorImpl();

                        //newEntity.Discriminator.RootGrouping = g;
                    }
                    #endregion

                    ///////////////////////////////////////////////////
                    //foreach (var hProperty in hClass.Properties())
                    //{
                    //    var property = CreateProperty(newEntity, mapping, hProperty);
                    //    SetPropertyInfoFromParsedCode(property, parseResults, hm.@namespace, mapping.FromTable.Schema, hClass.name);
                    //}

                    //foreach (var hComponent in hClass.Components())
                    //{
                    //    ProcessComponent(hComponent, newEntity, mapping.FromTable, existingComponentSpecs, hm.@namespace, parseResults);
                    //}
                    ///////////////////////////////////////////////////
                    id hId = hClass.Id();

                    if (hId != null)
                    {
                        var idProperty = CreateProperty(newEntity, mapping, hId);
                        string schema = mapping == null ? null : mapping.FromTable.Schema;
                        SetPropertyInfoFromParsedCode(idProperty, parseResults, hm.@namespace, schema, hClass.name);
                        idProperty.IsKeyProperty = true;

                        if (hId.generator == null)
                            newEntity.Generator.ClassName = NHibernateHelper.MappingFiles.Version_2_2.GeneratorTypes.assigned.ToString();
                        else
                        {
                            newEntity.Generator.ClassName = hId.generator.@class;

                            if (hId.generator.param != null)
                                foreach (var param in hId.generator.param)
                                    newEntity.Generator.Parameters.Add(new EntityGenerator.Parameter(param.name, param.Text[0]));
                        }
                    }
                    else
                    {
                        compositeid hCompId = hClass.CompositeId();

                        if (hCompId != null)
                        {
                            // Check if this is a component. If so, we need to do some additional processing.
                            if (!string.IsNullOrEmpty(hCompId.@class))
                            {
                                bool keyResult = ProcessComponentKey(hCompId, newEntity, mapping.FromTable, existingComponentSpecs, hm.@namespace, parseResults);

                                if (keyResult == false)
                                {
                                    // Fallback to composite key generation, log failure.
                                    ProcessCompositeKey(hm, hClass, newEntity, mapping, parseResults, hCompId);
                                    log.ErrorFormat("Could not create a component for composite key {0}", hCompId.name);
                                }
                            }
                            else
                            {
                                // It is not a component.
                                ProcessCompositeKey(hm, hClass, newEntity, mapping, parseResults, hCompId);
                            }
                        }
                    }

                    foreach (var hProperty in hClass.Properties())
                    {
                        var property = CreateProperty(newEntity, mapping, hProperty);
                        string schema = mapping == null ? null : mapping.FromTable.Schema;
                        SetPropertyInfoFromParsedCode(property, parseResults, hm.@namespace, schema, hClass.name);

                        property.SetPropertyFormula(hProperty.formula);
                        property.SetPropertyGenerated((ArchAngel.Interfaces.NHibernateEnums.PropertyGeneratedTypes)Enum.Parse(typeof(ArchAngel.Interfaces.NHibernateEnums.PropertyGeneratedTypes), hProperty.generated.ToString()));

                        if (hProperty.insertSpecified)
                            property.SetPropertyInsert(hProperty.insert);

                        property.SetPropertyOptimisticLock(hProperty.optimisticlock);

                        if (hProperty.updateSpecified)
                            property.SetPropertyUpdate(hProperty.update);
                    }

                    foreach (var hComponent in hClass.Components())
                        ProcessComponent(hComponent, newEntity, mapping.FromTable, existingComponentSpecs, hm.@namespace, parseResults);

                    if (hClass.Version() != null)
                    {
                        // Create a property from the version node.
                        ProcessVersionProperty(hm, hClass, newEntity, mapping, parseResults);
                    }
                    ProcessSubclasses(mappingSet, database, entities, newEntity, hClass.SubClasses(), hClass.schema.UnBackTick(), hClass.table.UnBackTick(), parseResults, hm.@namespace);
                    ProcessJoinedSubclasses(mappingSet, database, entities, newEntity, hClass.JoinedSubClasses(), parseResults, hm.@namespace);
                    ProcessUnionSubclasses(hClass, mappingSet, database, entities, newEntity, hClass.UnionSubClasses(), parseResults, hm.@namespace);
                }
            }
            List<string> processedClassNames = new List<string>();

            // Second pass, to add missing foreign key columns and properties
            foreach (var hm in mappingFiles)
            {
                foreach (var hClass in hm.Classes())
                {
                    string className;

                    if (!IsNameFullyQualified(hClass.name, out className))
                        className = hClass.name;

                    if (processedClassNames.Contains(className))
                        continue;

                    processedClassNames.Add(className);

                    foreach (var hManyToOne in hClass.ManyToOnes())
                    {
                        var fkColumnNames = ReferenceLoader.GetColumnNames(hManyToOne.column, hManyToOne.Columns()).ToList();
                        Entity entity = entities.Entities.Single(e => e.Name == className);
                        bool found = false;

                        foreach (var prop in entity.Properties)
                        {
                            IColumn mappedColumn = prop.MappedColumn();

                            if (mappedColumn != null)
                            {
                                string mappedColumnName = null;

                                if (hManyToOne.column != null)
                                    mappedColumnName = hManyToOne.column;
                                else if (hManyToOne.Columns().Count > 0)
                                    mappedColumnName = hManyToOne.Columns()[0].name;

                                if (!string.IsNullOrEmpty(mappedColumnName) &&
                                    mappedColumn.Name == mappedColumnName.UnBackTick())
                                {
                                    found = true;
                                    break;
                                }
                            }
                            //else
                            //{
                            //    string gfh2 = string.Format("{0}.{1}", hClass.name, hManyToOne.column1.UnBackTick());
                            //    gfh2 = "";
                            //    // TODO: we should create a column for this property
                            //    Entity referencedEntity = entities.Entities.Single(e => e.Name == hManyToOne.@class);
                            //    Property referencedProperty = referencedEntity.Key.Properties.ElementAt(0);
                            //    IColumn tempColumn = referencedProperty.MappedColumn();

                            //    IColumn newColumn = ArchAngel.Providers.EntityModel.Controller.MappingLayer.OneToOneEntityProcessor.CreateColumnFromProperty(referencedProperty);
                            //    newColumn.Name = hManyToOne.column1.UnBackTick();
                            //    ITable table = entity.MappedTables().First();
                            //    table.AddColumn(newColumn);
                            //    prop.SetMappedColumn(newColumn);
                            //}
                        }
                        if (!found)
                        {
                            string name;

                            string manyToOneClassName = hManyToOne.@class != null ? hManyToOne.@class : hManyToOne.name;
                            IsNameFullyQualified(manyToOneClassName, out name);
                            Entity referencedEntity = entities.Entities.Single(e => e.Name == name);
                            Property referencedProperty = referencedEntity.Key.Properties.ElementAt(0);
                            IColumn newColumn = null;

                            foreach (Table t in entity.MappedTables())
                            {
                                string colName = null;

                                if (hManyToOne.column != null)
                                    colName = hManyToOne.column;
                                else if (hManyToOne.Columns().Count > 0)
                                    colName = hManyToOne.Columns()[0].name;

                                newColumn = t.Columns.SingleOrDefault(c => !string.IsNullOrEmpty(colName) && c.Name == colName.UnBackTick());

                                if (newColumn != null)
                                    break;
                            }
                            if (newColumn == null)
                            {
                                newColumn = ArchAngel.Providers.EntityModel.Controller.MappingLayer.OneToOneEntityProcessor.CreateColumnFromProperty(referencedProperty);
                                ITable table = entity.MappedTables().First();
                                table.AddColumn(newColumn);
                            }
                            Property newProperty = ArchAngel.Providers.EntityModel.Controller.MappingLayer.OneToOneEntityProcessor.CreatePropertyFromColumn(newColumn);
                            //entity.Properties.SingleOrDefault(p => p.MappedColumn() ==
                            entity.AddProperty(newProperty);
                        }
                        //ITable table = entity.MappedTables().First();
                    }
                }
            }

            // Second pass, for references.
            var refProcessor = new ReferenceLoader();
            refProcessor.ProcessReferences(mappingFiles, mappingSet);

            processedClassNames.Clear();
            // Second pass, to add missing foreign key columns and properties
            foreach (var hm in mappingFiles)
            {
                foreach (var hClass in hm.Classes())
                {
                    string className;
                    IsNameFullyQualified(hClass.name, out className);

                    if (processedClassNames.Contains(className))
                        continue;

                    processedClassNames.Add(className);

                    foreach (var hManyToOne in hClass.ManyToOnes())
                    {
                        var fkColumnNames = ReferenceLoader.GetColumnNames(hManyToOne.column, hManyToOne.Columns()).ToList();
                        Entity entity = entities.Entities.Single(e => e.Name == className);

                        foreach (var prop in entity.Properties)
                        {
                            IColumn mappedColumn = prop.MappedColumn();

                            if (mappedColumn == null)
                            {
                                // TODO: we should create a column for this property
                                string manyToOneClassName;
                                IsNameFullyQualified(hManyToOne.@class, out manyToOneClassName);
                                Entity referencedEntity = entities.Entities.Single(e => e.Name == manyToOneClassName);
                                Property referencedProperty = referencedEntity.Key.Properties.ElementAt(0);
                                IColumn tempColumn = referencedProperty.MappedColumn();

                                IColumn newColumn = ArchAngel.Providers.EntityModel.Controller.MappingLayer.OneToOneEntityProcessor.CreateColumnFromProperty(referencedProperty);

                                string newColName = "";

                                if (hManyToOne.column != null)
                                    newColName = hManyToOne.column;
                                else if (hManyToOne.Columns().Count > 0)
                                    newColName = hManyToOne.Columns()[0].name;

                                newColumn.Name = newColName.UnBackTick();
                                ITable table = entity.MappedTables().First();

                                if (table.Columns.Count(c => c.Name == newColumn.Name) == 0)
                                    table.AddColumn(newColumn);
                                else
                                    newColumn = table.Columns.First(c => c.Name == newColumn.Name);

                                prop.SetMappedColumn(newColumn);
                            }
                        }
                    }
                }
            }
            return mappingSet;
        }