/// <summary>
        /// Returns the <see cref="CharSet"/> used by the property's column.
        /// </summary>
        /// <param name="property">The property of which get its column's <see cref="CharSet"/> from.</param>
        /// <returns>The <see cref="CharSet"/> or null, if no explicit <see cref="CharSet"/> was set.</returns>
        public static CharSet GetCharSet([NotNull] this IProperty property)
        {
            var charSetName = property[MySqlAnnotationNames.CharSet] as string;

            if (string.IsNullOrEmpty(charSetName))
            {
                return(null);
            }

            return(CharSet.GetCharSetFromName(charSetName));
        }
Exemple #2
0
        /// <summary>
        /// Sets a predefined <see cref="CharSet"/> by its name, that is in use by the property's column.
        /// </summary>
        /// <param name="property">The property to set the <see cref="CharSet"/> for.</param>
        /// <param name="predefinedCharSetName">The charset name used by the property's column, that is
        /// being resolved into a <see cref="CharSet"/> object.</param>
        public static void SetCharSet([NotNull] this IMutableProperty property, string predefinedCharSetName)
        {
            Check.NotNull(property, nameof(property));
            Check.NotEmpty(predefinedCharSetName, nameof(predefinedCharSetName));

            var charSet = CharSet.GetCharSetFromName(predefinedCharSetName);

            if (charSet == null)
            {
                throw new ArgumentOutOfRangeException($"Cannot find a predefined charset with the name of \"{predefinedCharSetName}\".");
            }

            property.SetCharSet(charSet);
        }
Exemple #3
0
        public virtual void AddColumnOperation_with_charSet_implicit(bool?isUnicode, bool isIndex, CharSetBehavior charSetBehavior,
                                                                     string charSetName, bool expectExplicitCharSet)
        {
            var charSet             = CharSet.GetCharSetFromName(charSetName);
            var expectedCharSetName = expectExplicitCharSet ? $" CHARACTER SET {charSet}" : string.Empty;

            Generate(
                modelBuilder => modelBuilder.Entity("Person", eb =>
            {
                var pb = eb.Property <string>("Name");

                if (isUnicode.HasValue)
                {
                    pb.IsUnicode(isUnicode.Value);
                }

                if (isIndex)
                {
                    eb.HasIndex("Name");
                }
            }),
                charSetBehavior,
                charSet,
                new AddColumnOperation
            {
                Table      = "Person",
                Name       = "Name",
                ClrType    = typeof(string),
                IsUnicode  = isUnicode,
                IsNullable = true
            });

            var columnType = "longtext";

            if (isIndex)
            {
                var serverVersion = new ServerVersion();
                var columnSize    = Math.Min(serverVersion.MaxKeyLength / (charSet.MaxBytesPerChar * 2), 255);
                columnType = $"varchar({columnSize})";
            }

            Assert.Equal(
                $"ALTER TABLE `Person` ADD `Name` {columnType}{expectedCharSetName} NULL;" + EOL,
                Sql);
        }
        public virtual void AddColumnOperation_with_charSet_implicit(bool?isUnicode, bool isIndex, string charSetName)
        {
            var charSet             = CharSet.GetCharSetFromName(charSetName);
            var expectedCharSetName = charSet != null ? $" CHARACTER SET {charSet}" : null;

            Generate(
                modelBuilder => modelBuilder.Entity("Person", eb =>
            {
                var pb = eb.Property <string>("Name");

                if (isUnicode.HasValue)
                {
                    pb.IsUnicode(isUnicode.Value);
                }

                if (isIndex)
                {
                    eb.HasIndex("Name");
                }
            }),
                new AddColumnOperation
            {
                Table      = "Person",
                Name       = "Name",
                ClrType    = typeof(string),
                IsUnicode  = isUnicode,
                IsNullable = true,
                [MySqlAnnotationNames.CharSet] = charSet,
            },
                charSet);

            var columnType = "longtext";

            if (isIndex)
            {
                // TODO: Implementation should be changed to use a prefix, instead of a type change.
                var columnSize = Math.Min(AppConfig.ServerVersion.MaxKeyLength / ((charSet ?? CharSet.Utf8Mb4).MaxBytesPerChar * 2), 255);
                columnType = $"varchar({columnSize})";
            }

            Assert.Equal(
                $"ALTER TABLE `Person` ADD `Name` {columnType}{expectedCharSetName} NULL;" + EOL,
                Sql);
        }
Exemple #5
0
        public void EnsureSufficientKeySpace(IMutableModel model, TestStore testStore = null, bool limitColumnSize = false)
        {
            if (!AppConfig.ServerVersion.Supports.LargerKeyLength)
            {
                var databaseCharSet = CharSet.GetCharSetFromName((testStore as MySqlTestStore)?.DatabaseCharSet) ?? CharSet.Utf8Mb4;

                foreach (var entityType in model.GetEntityTypes())
                {
                    var indexes = entityType.GetIndexes();
                    var indexedStringProperties = entityType.GetProperties()
                                                  .Where(p => p.ClrType == typeof(string) &&
                                                         indexes.Any(i => i.Properties.Contains(p)))
                                                  .ToList();

                    if (indexedStringProperties.Count > 0)
                    {
                        var safePropertyLength = AppConfig.ServerVersion.MaxKeyLength /
                                                 databaseCharSet.MaxBytesPerChar /
                                                 indexedStringProperties.Count;

                        if (limitColumnSize)
                        {
                            foreach (var property in indexedStringProperties)
                            {
                                property.SetMaxLength(safePropertyLength);
                            }
                        }
                        else
                        {
                            foreach (var index in indexes)
                            {
                                index.SetPrefixLength(
                                    index.Properties.Select(
                                        p => indexedStringProperties.Contains(p) && p.GetMaxLength() > safePropertyLength
                                                ? safePropertyLength
                                                : 0)
                                    .ToArray());
                            }
                        }
                    }
                }
            }
        }