Пример #1
0
        protected override IEnumerable <MigrationOperation> Add(IColumn target, DiffContext diffContext, bool inline = false)
        {
            if (!inline)
            {
                foreach (var propertyMapping in target.PropertyMappings)
                {
                    if (propertyMapping.Property.FindTypeMapping() is RelationalTypeMapping storeType)
                    {
                        var valueGenerationStrategy = MySqlValueGenerationStrategyCompatibility.GetValueGenerationStrategy(
                            target.GetAnnotations()
                            .ToArray());

                        // Ensure that null will be set for the columns default value, if CURRENT_TIMESTAMP has been required,
                        // or when the store type of the column does not support default values at all.
                        inline = inline ||
                                 (storeType.StoreTypeNameBase == "datetime" ||
                                  storeType.StoreTypeNameBase == "timestamp") &&
                                 (valueGenerationStrategy == MySqlValueGenerationStrategy.IdentityColumn ||
                                  valueGenerationStrategy == MySqlValueGenerationStrategy.ComputedColumn) ||
                                 storeType.StoreTypeNameBase.Contains("text") ||
                                 storeType.StoreTypeNameBase.Contains("blob") ||
                                 storeType.StoreTypeNameBase == "geometry" ||
                                 storeType.StoreTypeNameBase == "json";

                        if (inline)
                        {
                            break;
                        }
                    }
                }
            }

            return(PostFilterOperations(base.Add(target, diffContext, inline)));
        }
        protected override IEnumerable <MigrationOperation> Add(IProperty target, DiffContext diffContext, bool inline = false)
        {
            if (target.FindTypeMapping() is RelationalTypeMapping storeType)
            {
                var valueGenerationStrategy = MySqlValueGenerationStrategyCompatibility.GetValueGenerationStrategy(MigrationsAnnotations.For(target).ToArray());

                // Ensure that null will be set for the columns default value, if CURRENT_TIMESTAMP has been required.
                inline = inline ||
                         (storeType.StoreTypeNameBase == "datetime" ||
                          storeType.StoreTypeNameBase == "timestamp") &&
                         (valueGenerationStrategy == MySqlValueGenerationStrategy.IdentityColumn ||
                          valueGenerationStrategy == MySqlValueGenerationStrategy.ComputedColumn);
            }

            return(base.Add(target, diffContext, inline));
        }
Пример #3
0
        /// <summary>
        ///     Generates a SQL fragment for a column definition for the given column metadata.
        /// </summary>
        /// <param name="schema"> The schema that contains the table, or <c>null</c> to use the default schema. </param>
        /// <param name="table"> The table that contains the column. </param>
        /// <param name="name"> The column name. </param>
        /// <param name="operation"> The column metadata. </param>
        /// <param name="model"> The target model which may be <c>null</c> if the operations exist without a model. </param>
        /// <param name="builder"> The command builder to use to add the SQL fragment. </param>
        protected override void ColumnDefinition(
            [CanBeNull] string schema,
            [NotNull] string table,
            [NotNull] string name,
            [NotNull] ColumnOperation operation,
            [CanBeNull] IModel model,
            [NotNull] MigrationCommandListBuilder builder)
        {
            Check.NotEmpty(name, nameof(name));
            Check.NotNull(operation, nameof(operation));
            Check.NotNull(builder, nameof(builder));

            var matchType = operation.ColumnType ?? GetColumnType(schema, table, name, operation, model);
            var matchLen  = "";
            var match     = _typeRe.Match(matchType ?? "-");

            if (match.Success)
            {
                matchType = match.Groups[1].Value.ToLower();
                if (!string.IsNullOrWhiteSpace(match.Groups[2].Value))
                {
                    matchLen = match.Groups[2].Value;
                }
            }

            var valueGenerationStrategy = MySqlValueGenerationStrategyCompatibility.GetValueGenerationStrategy(operation.GetAnnotations().OfType <IAnnotation>().ToArray());

            var autoIncrement = false;

            if (valueGenerationStrategy == MySqlValueGenerationStrategy.IdentityColumn &&
                string.IsNullOrWhiteSpace(operation.DefaultValueSql) && operation.DefaultValue == null)
            {
                switch (matchType)
                {
                case "tinyint":
                case "smallint":
                case "mediumint":
                case "int":
                case "bigint":
                    autoIncrement = true;
                    break;

                case "datetime":
                    if (!_connectionInfo.ServerVersion.SupportsDateTime6)
                    {
                        throw new InvalidOperationException(
                                  $"Error in {table}.{name}: DATETIME does not support values generated " +
                                  "on Add or Update in MySql <= 5.5, try explicitly setting the column type to TIMESTAMP");
                    }

                    goto case "timestamp";

                case "timestamp":
                    operation.DefaultValueSql = $"CURRENT_TIMESTAMP({matchLen})";
                    break;
                }
            }

            string onUpdateSql = null;

            if (operation.IsRowVersion || valueGenerationStrategy == MySqlValueGenerationStrategy.ComputedColumn)
            {
                switch (matchType)
                {
                case "datetime":
                    if (!_connectionInfo.ServerVersion.SupportsDateTime6)
                    {
                        throw new InvalidOperationException(
                                  $"Error in {table}.{name}: DATETIME does not support values generated " +
                                  "on Add or Update in MySql <= 5.5, try explicitly setting the column type to TIMESTAMP");
                    }

                    goto case "timestamp";

                case "timestamp":
                    if (string.IsNullOrWhiteSpace(operation.DefaultValueSql) && operation.DefaultValue == null)
                    {
                        operation.DefaultValueSql = $"CURRENT_TIMESTAMP({matchLen})";
                    }

                    onUpdateSql = $"CURRENT_TIMESTAMP({matchLen})";
                    break;
                }
            }

            if (operation.ComputedColumnSql == null)
            {
                base.ColumnDefinition(
                    schema,
                    table,
                    name,
                    operation,
                    model,
                    builder);

                if (autoIncrement)
                {
                    builder.Append(" AUTO_INCREMENT");
                }
                else
                {
                    if (onUpdateSql != null)
                    {
                        builder
                        .Append(" ON UPDATE ")
                        .Append(onUpdateSql);
                    }
                }
            }
            else
            {
                builder
                .Append(Dependencies.SqlGenerationHelper.DelimitIdentifier(name))
                .Append(" ")
                .Append(operation.ColumnType ?? GetColumnType(schema, table, name, operation, model));
                builder
                .Append(" AS ")
                .Append($"({operation.ComputedColumnSql})");

                if (operation.IsNullable && _connectionInfo.ServerVersion.SupportsNullableGeneratedColumns)
                {
                    builder.Append(" NULL");
                }
            }
        }