예제 #1
0
 protected virtual FieldMixin GenerateFieldMixin(PropertyRoute route, NameSequence name, Table table)
 {
     return(new FieldMixin(route.Type, table)
     {
         Fields = GenerateFields(route, table, name, forceNull: false, inMList: false)
     });
 }
예제 #2
0
        protected virtual FieldEmbedded GenerateFieldEmbedded(ITable table, PropertyRoute route, NameSequence name, bool forceNull, bool inMList)
        {
            bool nullable = Settings.IsNullable(route, false);

            return(new FieldEmbedded(route.Type)
            {
                HasValue = nullable ? new FieldEmbedded.EmbeddedHasValueColumn()
                {
                    Name = name.Add("HasValue").ToString()
                } : null,
                EmbeddedFields = GenerateFields(route, table, name, forceNull: nullable || forceNull, inMList: inMList)
            });
        }
예제 #3
0
        protected virtual FieldImplementedByAll GenerateFieldImplementedByAll(PropertyRoute route, ITable table, NameSequence preName, bool forceNull)
        {
            bool nullable = Settings.IsNullable(route, forceNull);

            return(new FieldImplementedByAll(route.Type)
            {
                Column = new ImplementationStringColumn
                {
                    Name = preName.ToString(),
                    Nullable = nullable,
                    Size = Settings.DefaultImplementedBySize,
                },
                ColumnType = new ImplementationColumn
                {
                    Name = preName.Add("Type").ToString(),
                    Nullable = nullable,
                    ReferenceTable = Include(typeof(TypeEntity), route),
                    AvoidForeignKey = Settings.FieldAttribute <AvoidForeignKeyAttribute>(route) != null,
                },
                IsLite = route.Type.IsLite(),
                AvoidExpandOnRetrieving = Settings.FieldAttribute <AvoidExpandQueryAttribute>(route) != null
            }.Do(f => f.UniqueIndex = f.GenerateUniqueIndex(table, Settings.FieldAttribute <UniqueIndexAttribute>(route))));
        }
예제 #4
0
        protected virtual FieldMList GenerateFieldMList(Table table, PropertyRoute route, NameSequence name)
        {
            Type elementType = route.Type.ElementType();

            if (table.Ticks == null)
            {
                throw new InvalidOperationException("Type '{0}' has field '{1}' but does not Ticks. MList requires concurrency control.".FormatWith(route.Parent.Type.TypeName(), route.FieldInfo.FieldName()));
            }

            var orderAttr = Settings.FieldAttribute <PreserveOrderAttribute>(route);

            FieldValue order = null;

            if (orderAttr != null)
            {
                var pair = Settings.GetSqlDbTypePair(typeof(int));

                order = new FieldValue(typeof(int))
                {
                    Name                = orderAttr.Name ?? "Order",
                    SqlDbType           = pair.SqlDbType,
                    UserDefinedTypeName = pair.UserDefinedTypeName,
                    Nullable            = false,
                    Size                = Settings.GetSqlSize(orderAttr, pair.SqlDbType),
                    Scale               = Settings.GetSqlScale(orderAttr, pair.SqlDbType),
                };
            }

            var keyAttr = Settings.FieldAttribute <PrimaryKeyAttribute>(route) ?? Settings.DefaultPrimaryKeyAttribute;

            TableMList.PrimaryKeyColumn primaryKey;
            {
                var pair = Settings.GetSqlDbType(keyAttr, keyAttr.Type);

                primaryKey = new TableMList.PrimaryKeyColumn
                {
                    Name                = keyAttr.Name,
                    Type                = keyAttr.Type,
                    SqlDbType           = pair.SqlDbType,
                    UserDefinedTypeName = pair.UserDefinedTypeName,
                    Default             = keyAttr.Default,
                    Identity            = keyAttr.Identity,
                };
            }

            TableMList relationalTable = new TableMList(route.Type)
            {
                Name          = GenerateTableNameCollection(table, name, Settings.FieldAttribute <TableNameAttribute>(route)),
                PrimaryKey    = primaryKey,
                BackReference = new FieldReference(table.Type)
                {
                    Name            = GenerateBackReferenceName(table.Type, Settings.FieldAttribute <BackReferenceColumnNameAttribute>(route)),
                    ReferenceTable  = table,
                    AvoidForeignKey = Settings.FieldAttribute <AvoidForeignKeyAttribute>(route) != null,
                },
                Order = order,
            };

            relationalTable.Field = GenerateField(relationalTable, route.Add("Item"), NameSequence.Void, forceNull: false, inMList: true);

            relationalTable.GenerateColumns();

            return(new FieldMList(route.Type)
            {
                TableMList = relationalTable,
            });
        }
예제 #5
0
 protected override FieldReference GenerateFieldReference(ITable table, PropertyRoute route, NameSequence name, bool forceNull)
 {
     return(base.GenerateFieldReference(table, route, name, forceNull));
 }
예제 #6
0
        protected virtual FieldImplementedBy GenerateFieldImplementedBy(ITable table, PropertyRoute route, NameSequence name, bool forceNull, IEnumerable <Type> types)
        {
            Type   cleanType = Lite.Extract(route.Type) ?? route.Type;
            string errors    = types.Where(t => !cleanType.IsAssignableFrom(t)).ToString(t => t.TypeName(), ", ");

            if (errors.Length != 0)
            {
                throw new InvalidOperationException("Type {0} do not implement {1}".FormatWith(errors, cleanType));
            }

            bool nullable = Settings.IsNullable(route, forceNull) || types.Count() > 1;

            CombineStrategy strategy = Settings.FieldAttribute <CombineStrategyAttribute>(route)?.Strategy ?? CombineStrategy.Case;

            bool avoidForeignKey = Settings.FieldAttribute <AvoidForeignKeyAttribute>(route) != null;

            return(new FieldImplementedBy(route.Type)
            {
                SplitStrategy = strategy,
                ImplementationColumns = types.ToDictionary(t => t, t => new ImplementationColumn
                {
                    ReferenceTable = Include(t, route),
                    Name = name.Add(TypeLogic.GetCleanName(t)).ToString(),
                    Nullable = nullable,
                    AvoidForeignKey = avoidForeignKey,
                }),
                IsLite = route.Type.IsLite(),
                AvoidExpandOnRetrieving = Settings.FieldAttribute <AvoidExpandQueryAttribute>(route) != null
            }.Do(f => f.UniqueIndex = f.GenerateUniqueIndex(table, Settings.FieldAttribute <UniqueIndexAttribute>(route))));
        }
예제 #7
0
        protected virtual FieldValue GenerateFieldValue(ITable table, PropertyRoute route, NameSequence name, bool forceNull)
        {
            var att = Settings.FieldAttribute <SqlDbTypeAttribute>(route);

            SqlDbTypePair pair = Settings.GetSqlDbType(att, route.Type);

            return(new FieldValue(route.Type)
            {
                Name = name.ToString(),
                SqlDbType = pair.SqlDbType,
                UserDefinedTypeName = pair.UserDefinedTypeName,
                Nullable = Settings.IsNullable(route, forceNull),
                Size = Settings.GetSqlSize(att, pair.SqlDbType),
                Scale = Settings.GetSqlScale(att, pair.SqlDbType),
                Default = att?.Default,
            }.Do(f => f.UniqueIndex = f.GenerateUniqueIndex(table, Settings.FieldAttribute <UniqueIndexAttribute>(route))));
        }
예제 #8
0
 public override ObjectName GenerateTableNameCollection(Table table, NameSequence name, TableNameAttribute tn)
 {
     return base.GenerateTableNameCollection(table, name, tn).OnSchema(GetSchemaName(table.Type));
 }
예제 #9
0
        protected virtual Field GenerateFieldPrimaryKey(Table table, PropertyRoute route, NameSequence name)
        {
            var attr = GetPrimaryKeyAttribute(table.Type);

            PrimaryKey.PrimaryKeyType.SetDefinition(table.Type, attr.Type);

            SqlDbTypePair pair = Settings.GetSqlDbType(attr, attr.Type);

            return(table.PrimaryKey = new FieldPrimaryKey(route.Type, table)
            {
                Name = attr.Name,
                Type = attr.Type,
                SqlDbType = pair.SqlDbType,
                UserDefinedTypeName = pair.UserDefinedTypeName,
                Default = attr.Default,
                Identity = attr.Identity,
            });
        }
예제 #10
0
        protected virtual FieldValue GenerateFieldTicks(Table table, PropertyRoute route, NameSequence name)
        {
            var ticksAttr = Settings.TypeAttribute <TicksColumnAttribute>(table.Type);

            if (ticksAttr != null && !ticksAttr.HasTicks)
            {
                throw new InvalidOperationException("HastTicks is false");
            }

            Type type = ticksAttr?.Type ?? route.Type;

            SqlDbTypePair pair = Settings.GetSqlDbType(ticksAttr, type);

            return(table.Ticks = new FieldTicks(route.Type)
            {
                Type = type,
                Name = ticksAttr?.Name ?? name.ToString(),
                SqlDbType = pair.SqlDbType,
                UserDefinedTypeName = pair.UserDefinedTypeName,
                Nullable = false,
                Size = Settings.GetSqlSize(ticksAttr, pair.SqlDbType),
                Scale = Settings.GetSqlScale(ticksAttr, pair.SqlDbType),
                Default = ticksAttr?.Default,
            });
        }
예제 #11
0
        protected virtual Field GenerateField(ITable table, PropertyRoute route, NameSequence preName, bool forceNull, bool inMList)
        {
            KindOfField kof = GetKindOfField(route).ThrowIfNull(() => "Field {0} of type {1} has no database representation".FormatWith(route, route.Type.Name));

            if (kof == KindOfField.MList && inMList)
            {
                throw new InvalidOperationException("Field {0} of type {1} can not be nested in another MList".FormatWith(route, route.Type.TypeName(), kof));
            }

            //field name generation
            NameSequence        name;
            ColumnNameAttribute vc = Settings.FieldAttribute <ColumnNameAttribute>(route);

            if (vc != null && vc.Name.HasText())
            {
                name = NameSequence.Void.Add(vc.Name);
            }
            else if (route.PropertyRouteType != PropertyRouteType.MListItems)
            {
                name = preName.Add(GenerateFieldName(route, kof));
            }
            else if (kof == KindOfField.Enum || kof == KindOfField.Reference)
            {
                name = preName.Add(GenerateMListFieldName(route, kof));
            }
            else
            {
                name = preName;
            }

            switch (kof)
            {
            case KindOfField.PrimaryKey:
                return(GenerateFieldPrimaryKey((Table)table, route, name));

            case KindOfField.Ticks:
                return(GenerateFieldTicks((Table)table, route, name));

            case KindOfField.Value:
                return(GenerateFieldValue(table, route, name, forceNull));

            case KindOfField.Reference:
            {
                Implementations at = Settings.GetImplementations(route);
                if (at.IsByAll)
                {
                    return(GenerateFieldImplementedByAll(route, table, name, forceNull));
                }
                else if (at.Types.Only() == route.Type.CleanType())
                {
                    return(GenerateFieldReference(table, route, name, forceNull));
                }
                else
                {
                    return(GenerateFieldImplementedBy(table, route, name, forceNull, at.Types));
                }
            }

            case KindOfField.Enum:
                return(GenerateFieldEnum(table, route, name, forceNull));

            case KindOfField.Embedded:
                return(GenerateFieldEmbedded(table, route, name, forceNull, inMList));

            case KindOfField.MList:
                return(GenerateFieldMList((Table)table, route, name));

            default:
                throw new NotSupportedException(EngineMessage.NoWayOfMappingType0Found.NiceToString().FormatWith(route.Type));
            }
        }
예제 #12
0
        protected Dictionary <string, EntityField> GenerateFields(PropertyRoute root, ITable table, NameSequence preName, bool forceNull, bool inMList)
        {
            Dictionary <string, EntityField> result = new Dictionary <string, EntityField>();
            var type = root.Type;

            if (type.IsEntity())
            {
                {
                    PropertyRoute route = root.Add(fiId);

                    Field field = GenerateField(table, route, preName, forceNull, inMList);

                    result.Add(fiId.Name, new EntityField(type, fiId)
                    {
                        Field = field
                    });
                }

                TicksColumnAttribute t = type.GetCustomAttribute <TicksColumnAttribute>();
                if (t == null || t.HasTicks)
                {
                    PropertyRoute route = root.Add(fiTicks);

                    Field field = GenerateField(table, route, preName, forceNull, inMList);

                    result.Add(fiTicks.Name, new EntityField(type, fiTicks)
                    {
                        Field = field
                    });
                }

                Expression exp = ExpressionCleaner.GetFieldExpansion(type, EntityExpression.ToStringMethod);

                if (exp == null)
                {
                    PropertyRoute route = root.Add(fiToStr);

                    Field field = GenerateField(table, route, preName, forceNull, inMList);

                    if (result.ContainsKey(fiToStr.Name))
                    {
                        throw new InvalidOperationException("Duplicated field with name {0} on {1}, shadowing not supported".FormatWith(fiToStr.Name, type.TypeName()));
                    }

                    result.Add(fiToStr.Name, new EntityField(type, fiToStr)
                    {
                        Field = field
                    });
                }
            }

            foreach (FieldInfo fi in Reflector.InstanceFieldsInOrder(type))
            {
                PropertyRoute route = root.Add(fi);

                if (Settings.FieldAttribute <IgnoreAttribute>(route) == null)
                {
                    if (Reflector.TryFindPropertyInfo(fi) == null && !fi.IsPublic && !fi.HasAttribute <FieldWithoutPropertyAttribute>())
                    {
                        throw new InvalidOperationException("Field '{0}' of type '{1}' has no property".FormatWith(fi.Name, type.Name));
                    }

                    Field field = GenerateField(table, route, preName, forceNull, inMList);

                    if (result.ContainsKey(fi.Name))
                    {
                        throw new InvalidOperationException("Duplicated field with name '{0}' on '{1}', shadowing not supported".FormatWith(fi.Name, type.TypeName()));
                    }

                    result.Add(fi.Name, new EntityField(type, fi)
                    {
                        Field = field
                    });
                }
            }

            return(result);
        }
예제 #13
0
        protected override Field GenerateFieldPrimaryKey(Table table, PropertyRoute route, NameSequence name)
        {
            var att = Settings.FieldAttribute <SqlDbTypeAttribute>(route);

            SqlDbTypePair pair = Settings.GetSqlDbType(att, route.Type);

            var result = new FieldValue(route.Type)
            {
                PrimaryKey          = true,
                Name                = name.ToString(),
                SqlDbType           = pair.SqlDbType,
                UserDefinedTypeName = pair.UserDefinedTypeName,
                Nullable            = Settings.IsNullable(route, false),
                Size                = Settings.GetSqlSize(att, pair.SqlDbType),
                Scale               = Settings.GetSqlScale(att, pair.SqlDbType),
            };

            return(result);
        }
예제 #14
0
        public virtual ObjectName GenerateTableNameCollection(Table table, NameSequence name, TableNameAttribute tn)
        {
            SchemaName sn = tn != null?GetSchemaName(tn) : SchemaName.Default;

            return(new ObjectName(sn, tn?.Name ?? (table.Name.Name + name.ToString())));
        }
예제 #15
0
        protected virtual FieldEnum GenerateFieldEnum(ITable table, PropertyRoute route, NameSequence name, bool forceNull)
        {
            var att = Settings.FieldAttribute <SqlDbTypeAttribute>(route);

            Type cleanEnum = route.Type.UnNullify();

            var referenceTable = Include(EnumEntity.Generate(cleanEnum), route);

            return(new FieldEnum(route.Type)
            {
                Name = name.ToString(),
                Nullable = Settings.IsNullable(route, forceNull),
                IsLite = false,
                ReferenceTable = referenceTable,
                AvoidForeignKey = Settings.FieldAttribute <AvoidForeignKeyAttribute>(route) != null,
                Default = att?.Default,
            }.Do(f => f.UniqueIndex = f.GenerateUniqueIndex(table, Settings.FieldAttribute <UniqueIndexAttribute>(route))));
        }
예제 #16
0
 private NameSequence(string value, NameSequence preSequence)
 {
     this.Value       = value;
     this.PreSequence = preSequence;
 }
예제 #17
0
        protected virtual FieldReference GenerateFieldReference(ITable table, PropertyRoute route, NameSequence name, bool forceNull)
        {
            var referenceTable = Include(Lite.Extract(route.Type) ?? route.Type, route);

            var nullable = Settings.IsNullable(route, forceNull);

            return(new FieldReference(route.Type)
            {
                Name = name.ToString(),
                Nullable = nullable,
                IsLite = route.Type.IsLite(),
                ReferenceTable = referenceTable,
                AvoidForeignKey = Settings.FieldAttribute <AvoidForeignKeyAttribute>(route) != null,
                AvoidExpandOnRetrieving = Settings.FieldAttribute <AvoidExpandQueryAttribute>(route) != null,
                Default = Settings.FieldAttribute <SqlDbTypeAttribute>(route)?.Default
            }.Do(f => f.UniqueIndex = f.GenerateUniqueIndex(table, Settings.FieldAttribute <UniqueIndexAttribute>(route))));
        }
예제 #18
0
        private Dictionary <Type, FieldMixin> GenerateMixins(PropertyRoute propertyRoute, Table table, NameSequence nameSequence)
        {
            Dictionary <Type, FieldMixin> mixins = null;

            foreach (var t in MixinDeclarations.GetMixinDeclarations(table.Type))
            {
                if (mixins == null)
                {
                    mixins = new Dictionary <Type, FieldMixin>();
                }

                mixins.Add(t, this.GenerateFieldMixin(propertyRoute.Add(t), nameSequence, table));
            }

            return(mixins);
        }
예제 #19
0
 private NameSequence(string value, NameSequence preSequence)
 {
     this.Value = value;
     this.PreSequence = preSequence;
 }