예제 #1
0
        public async void Column__Error_On_Identity_Column_Nullable(string errorLocation, string column)
        {
            var mb = @"mb.Database(nameof(Database))
                         .Table(d => d.Table(t => t.Users)
                                      " + string.Format(column, errorLocation) + @"
                                      .Build())
                         .Build();";

            await VerifyErrorRaised(mb, ModelBuilderError.ColumnIdentityNullable(), errorLocation);
        }
예제 #2
0
        static FuzzyTableModel ParseTableColumn(SyntaxNodeAnalysisContext context, InvocationExpressionSyntax expression, FuzzyDatabaseModel partialDatabase)
        {
            var innerModel = ParseTableChain(context, expression, partialDatabase);

            var arguments       = AH.ParseArguments(context, expression);
            var columnArg       = arguments["column"];
            var typeArg         = arguments["type"];
            var nullableArg     = arguments["nullable"];
            var maxLengthArg    = arguments["maxLength"];
            var nameArg         = arguments["name"];
            var defaultValueArg = arguments["defaultValue"];
            var identityArg     = arguments["identity"];
            var converterArg    = arguments["converter"];

            if (AH.IsNull(context, columnArg))
            {
                context.ReportDiagnostic(BuilderError.ArgumentNull("column").MakeDiagnostic(columnArg.GetLocation()));
            }

            var property = AH.ParseSelector(context, columnArg);

            var fuzzyColumnModel = new FuzzyColumnModel()
            {
                Property   = property,
                MaxLength  = AH.ParseConstantArgument(context, maxLengthArg, () => AH.Just(null as int?)),
                IsIdentity = AH.ParseConstantArgument(context, identityArg, () => AH.Just(false)),
                IsNullable = AH.ParseConstantArgument(context, nullableArg, () => AH.Just(false)),
                Type       = AH.ParseConstantArgument(context, typeArg, () => new Optional <SqlType>()),
                Name       = AH.ParseConstantArgument(context, nameArg, () => !property.HasValue ?
                                                      new Optional <string>() :
                                                      AH.Just(property.Value?.Name))
            };



            if (fuzzyColumnModel.Property.HasValue)
            {
                var otherColumn = innerModel.Columns.FirstOrDefault(t => t.Property.HasValue && t.Property.Value.Name == fuzzyColumnModel.Property.Value.Name);
                if (otherColumn != null)
                {
                    context.ReportDiagnostic(ModelBuilderError.ColumnRepeatedSelector(ToTypeString(innerModel.Property), ToString(fuzzyColumnModel.Property), ToString(otherColumn.Name)).MakeDiagnostic(columnArg.GetLocation()));
                }
            }

            if (fuzzyColumnModel.Name.HasValue)
            {
                if (innerModel.Columns.Any(c => c.Name.HasValue &&
                                           c.Name.Value == fuzzyColumnModel.Name.Value))
                {
                    context.ReportDiagnostic(ModelBuilderError.ColumnRepeatedName(ToString(innerModel.Name), ToString(fuzzyColumnModel.Name)).MakeDiagnostic(nameArg == null ? columnArg.GetLocation() : nameArg.GetLocation()));
                }
            }

            if (fuzzyColumnModel.Property.HasValue && fuzzyColumnModel.Type.HasValue)
            {
                if (fuzzyColumnModel.Property.Value.Type.TypeKind == TypeKind.Enum)
                {
                    if (!(fuzzyColumnModel.Type.Value == SqlType.String || SqlTypeHelpers.IsIntegral(fuzzyColumnModel.Type.Value)))
                    {
                        context.ReportDiagnostic(ModelBuilderError.ColumnEnumNotStringOrIntegralType().MakeDiagnostic(typeArg.GetLocation()));
                    }

                    if (fuzzyColumnModel.Type.Value == SqlType.String && fuzzyColumnModel.MaxLength.HasValue)
                    {
                        var namedType   = fuzzyColumnModel.Property.Value.Type as INamedTypeSymbol;
                        var longestEnum = namedType.MemberNames.OrderByDescending(n => n.Length).First();

                        if (fuzzyColumnModel.MaxLength.Value != null &&
                            longestEnum.Length > fuzzyColumnModel.MaxLength.Value)
                        {
                            context.ReportDiagnostic(ModelBuilderError.ColumnEnumLongerThanMaxStringSize($"{namedType.Name}.{longestEnum}", (int)fuzzyColumnModel.MaxLength.Value).MakeDiagnostic(maxLengthArg.GetLocation()));
                        }
                    }
                }
                else if (fuzzyColumnModel.Property.Value.Type.Name == "DateTimeOffset" ||
                         fuzzyColumnModel.Property.Value.Type.Name == "Guid")
                {
                    //if ((fuzzyColumnModel.Property.Value.Type.Name == "DateTimeOffset" && fuzzyColumnModel.Type.Value != SqlType.DateTimeOffset) ||
                    //    (fuzzyColumnModel.Property.Value.Type.Name == "Guid" && fuzzyColumnModel.Type.Value != SqlType.Guid))
                    //    context.ReportDiagnostic(Diagnostic.Create(_descriptors[InvalidSqlType], typeArg.GetLocation()));
                }
                else
                {
                    var propertyType = fuzzyColumnModel.Property.Value.Type.SpecialType;

                    //if (!_defaultTypeMappings[propertyType].Contains(fuzzyColumnModel.Type.Value))
                    //    context.ReportDiagnostic(Diagnostic.Create(_descriptors[InvalidSqlType], typeArg.GetLocation()));
                }
            }

            if (fuzzyColumnModel.Type.HasValue &&
                fuzzyColumnModel.IsIdentity.HasValue &&
                fuzzyColumnModel.IsIdentity.Value == true)
            {
                var nonIdentityTypes = new List <SqlType>()
                {
                    SqlType.String,
                    SqlType.Bit,
                    SqlType.Date,
                    SqlType.Time,
                    SqlType.DateTime,
                    SqlType.DateTimeOffset,
                    SqlType.Single,
                    SqlType.Double,
                    SqlType.Guid
                };

                //if (nonIdentityTypes.Contains(fuzzyColumnModel.Type.Value))
                //    context.ReportDiagnostic(Diagnostic.Create(_descriptors[InvalidSqlTypeForIdentity], identityArg.GetLocation()));
            }

            if (fuzzyColumnModel.IsIdentity.HasValue && fuzzyColumnModel.IsIdentity.Value == true &&
                fuzzyColumnModel.IsNullable.HasValue && fuzzyColumnModel.IsNullable.Value == true)
            {
                context.ReportDiagnostic(ModelBuilderError.ColumnIdentityNullable().MakeDiagnostic(nullableArg.GetLocation()));
            }

            innerModel.Columns.Add(fuzzyColumnModel);

            return(innerModel);
        }
예제 #3
0
        public static IColumn <TDatabase, TTable> Column <TDatabase, TTable, TColumn>(this IColumnBuilder <TDatabase, TTable> @this,
                                                                                      Expression <Func <TTable, TColumn> > column,
                                                                                      SqlType type,
                                                                                      bool nullable        = false,
                                                                                      int?maxLength        = null,
                                                                                      string name          = null,
                                                                                      TColumn defaultValue = default(TColumn),
                                                                                      bool identity        = false,
                                                                                      IDatabaseTypeConverter <TColumn> converter = null)
        {
            var builder = @this as InternalTableBuilder <TDatabase, TTable>;

            var property = ExpressionHelpers.ParsePropertySelector(column ?? throw ModelBuilderError.ArgumentNull(nameof(column)).AsException());

            {
                var priorColumn = builder.Columns.FirstOrDefault(c => c.Property.Name == property.Name);
                if (priorColumn != null)
                {
                    throw ModelBuilderError.ColumnRepeatedSelector(typeof(TTable).Name, property.Name, priorColumn.Name).AsException();
                }
            }

            var columnName = name ?? property.Name;

            if (builder.Columns.Any(t => t.Name == columnName))
            {
                throw ModelBuilderError.ColumnRepeatedName(builder.Name, columnName).AsException();
            }

            if (nullable && identity)
            {
                throw ModelBuilderError.ColumnIdentityNullable().AsException();
            }

            if (property.Type.GetTypeInfo().IsEnum)
            {
                if (!(type == SqlType.String || SqlTypeHelpers.IsIntegral(type)))
                {
                    throw ModelBuilderError.ColumnEnumNotStringOrIntegralType().AsException();
                }

                var values = Enum.GetValues(property.Type);

                if (type == SqlType.String)
                {
                    var maxValue = values.Cast <object>()
                                   .Select(e => e.ToString())
                                   .OrderByDescending(e => e.Length)
                                   .First();

                    if (maxLength != null && maxValue.Length > maxLength)
                    {
                        throw ModelBuilderError.ColumnEnumLongerThanMaxStringSize($"{property.Type.ToString()}.{maxValue}", (int)maxLength).AsException();
                    }
                }
                else
                {
                }
            }

            builder.Columns.Add(new ColumnModel(name: columnName,
                                                property: property,
                                                sqlType: type,
                                                isNullable: nullable,
                                                isIdentity: identity,
                                                defaultValue: defaultValue));

            return(builder);
        }