/// <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)); }
/// <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); }
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); }
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()); } } } } } }