public void MaxLength() { using var reader = m_database.Connection.ExecuteReader(@"select coll.ID, cs.MAXLEN from information_schema.collations coll inner join information_schema.character_sets cs using(CHARACTER_SET_NAME);"); while (reader.Read()) { var characterSet = (CharacterSet)reader.GetInt32(0); var maxLength = reader.GetInt32(1); Assert.Equal(maxLength, ProtocolUtility.GetBytesPerCharacter(characterSet)); } }
internal MySqlDbColumn(int ordinal, ColumnDefinitionPayload column, MySqlDbType mySqlDbType) { var columnTypeMetadata = TypeMapper.Instance.GetColumnTypeMetadata(mySqlDbType); var type = columnTypeMetadata.DbTypeMapping.ClrType; var columnSize = type == typeof(string) || type == typeof(Guid) ? column.ColumnLength / ProtocolUtility.GetBytesPerCharacter(column.CharacterSet) : column.ColumnLength; AllowDBNull = (column.ColumnFlags & ColumnFlags.NotNull) == 0; BaseCatalogName = null; BaseColumnName = column.PhysicalName; BaseSchemaName = column.SchemaName; BaseTableName = column.PhysicalTable; ColumnName = column.Name; ColumnOrdinal = ordinal; ColumnSize = columnSize > int.MaxValue ? int.MaxValue : unchecked ((int)columnSize); DataType = type; DataTypeName = columnTypeMetadata.SimpleDataTypeName; if (mySqlDbType == MySqlDbType.String) { DataTypeName += string.Format(CultureInfo.InvariantCulture, "({0})", columnSize); } IsAliased = column.PhysicalName != column.Name; IsAutoIncrement = (column.ColumnFlags & ColumnFlags.AutoIncrement) != 0; IsExpression = false; IsHidden = false; IsKey = (column.ColumnFlags & ColumnFlags.PrimaryKey) != 0; IsLong = column.ColumnLength > 255 && ((column.ColumnFlags & ColumnFlags.Blob) != 0 || column.ColumnType == ColumnType.TinyBlob || column.ColumnType == ColumnType.Blob || column.ColumnType == ColumnType.MediumBlob || column.ColumnType == ColumnType.LongBlob); IsReadOnly = false; IsUnique = (column.ColumnFlags & ColumnFlags.UniqueKey) != 0; if (column.ColumnType == ColumnType.Decimal || column.ColumnType == ColumnType.NewDecimal) { NumericPrecision = (int)column.ColumnLength; if ((column.ColumnFlags & ColumnFlags.Unsigned) == 0) { NumericPrecision--; } if (column.Decimals > 0) { NumericPrecision--; } } NumericScale = column.Decimals; ProviderType = mySqlDbType; }
public static MySqlDbType ConvertToMySqlDbType(ColumnDefinitionPayload columnDefinition, bool treatTinyAsBoolean, MySqlGuidFormat guidFormat) { var isUnsigned = (columnDefinition.ColumnFlags & ColumnFlags.Unsigned) != 0; switch (columnDefinition.ColumnType) { case ColumnType.Tiny: return(treatTinyAsBoolean && columnDefinition.ColumnLength == 1 ? MySqlDbType.Bool : isUnsigned?MySqlDbType.UByte : MySqlDbType.Byte); case ColumnType.Int24: return(isUnsigned ? MySqlDbType.UInt24 : MySqlDbType.Int24); case ColumnType.Long: return(isUnsigned ? MySqlDbType.UInt32 : MySqlDbType.Int32); case ColumnType.Longlong: return(isUnsigned ? MySqlDbType.UInt64 : MySqlDbType.Int64); case ColumnType.Bit: return(MySqlDbType.Bit); case ColumnType.String: if (guidFormat == MySqlGuidFormat.Char36 && columnDefinition.ColumnLength / ProtocolUtility.GetBytesPerCharacter(columnDefinition.CharacterSet) == 36) { return(MySqlDbType.Guid); } if (guidFormat == MySqlGuidFormat.Char32 && columnDefinition.ColumnLength / ProtocolUtility.GetBytesPerCharacter(columnDefinition.CharacterSet) == 32) { return(MySqlDbType.Guid); } if ((columnDefinition.ColumnFlags & ColumnFlags.Enum) != 0) { return(MySqlDbType.Enum); } if ((columnDefinition.ColumnFlags & ColumnFlags.Set) != 0) { return(MySqlDbType.Set); } goto case ColumnType.VarString; case ColumnType.VarString: case ColumnType.TinyBlob: case ColumnType.Blob: case ColumnType.MediumBlob: case ColumnType.LongBlob: var type = columnDefinition.ColumnType; if (columnDefinition.CharacterSet == CharacterSet.Binary) { if ((guidFormat == MySqlGuidFormat.Binary16 || guidFormat == MySqlGuidFormat.TimeSwapBinary16 || guidFormat == MySqlGuidFormat.LittleEndianBinary16) && columnDefinition.ColumnLength == 16) { return(MySqlDbType.Guid); } return(type == ColumnType.String ? MySqlDbType.Binary : type == ColumnType.VarString ? MySqlDbType.VarBinary : type == ColumnType.TinyBlob ? MySqlDbType.TinyBlob : type == ColumnType.Blob ? MySqlDbType.Blob : type == ColumnType.MediumBlob ? MySqlDbType.MediumBlob : MySqlDbType.LongBlob); } return(type == ColumnType.String ? MySqlDbType.String : type == ColumnType.VarString ? MySqlDbType.VarChar : type == ColumnType.TinyBlob ? MySqlDbType.TinyText : type == ColumnType.Blob ? MySqlDbType.Text : type == ColumnType.MediumBlob ? MySqlDbType.MediumText : MySqlDbType.LongText); case ColumnType.Json: return(MySqlDbType.JSON); case ColumnType.Short: return(isUnsigned ? MySqlDbType.UInt16 : MySqlDbType.Int16); case ColumnType.Date: return(MySqlDbType.Date); case ColumnType.DateTime: return(MySqlDbType.DateTime); case ColumnType.Timestamp: return(MySqlDbType.Timestamp); case ColumnType.Time: return(MySqlDbType.Time); case ColumnType.Year: return(MySqlDbType.Year); case ColumnType.Float: return(MySqlDbType.Float); case ColumnType.Double: return(MySqlDbType.Double); case ColumnType.Decimal: return(MySqlDbType.Decimal); case ColumnType.NewDecimal: return(MySqlDbType.NewDecimal); case ColumnType.Geometry: return(MySqlDbType.Geometry); case ColumnType.Null: return(MySqlDbType.Null); default: throw new NotImplementedException("ConvertToMySqlDbType for {0} is not implemented".FormatInvariant(columnDefinition.ColumnType)); } }
public string GetDataTypeName(int ordinal) { if (ordinal < 0 || ordinal > ColumnDefinitions.Length) { throw new ArgumentOutOfRangeException(nameof(ordinal), "value must be between 0 and {0}.".FormatInvariant(ColumnDefinitions.Length)); } var mySqlDbType = ColumnTypes[ordinal]; if (mySqlDbType == MySqlDbType.String) { return(string.Format(CultureInfo.InvariantCulture, "CHAR({0})", ColumnDefinitions[ordinal].ColumnLength / ProtocolUtility.GetBytesPerCharacter(ColumnDefinitions[ordinal].CharacterSet))); } return(TypeMapper.Instance.GetColumnTypeMetadata(mySqlDbType).SimpleDataTypeName); }
protected override object GetValueCore(ReadOnlySpan <byte> data, ColumnDefinitionPayload columnDefinition) { var isUnsigned = (columnDefinition.ColumnFlags & ColumnFlags.Unsigned) != 0; switch (columnDefinition.ColumnType) { case ColumnType.Tiny: var value = ParseInt32(data); if (Connection.TreatTinyAsBoolean && columnDefinition.ColumnLength == 1 && !isUnsigned) { return(value != 0); } return(isUnsigned ? (object)(byte)value : (sbyte)value); case ColumnType.Int24: case ColumnType.Long: return(isUnsigned ? (object)ParseUInt32(data) : ParseInt32(data)); case ColumnType.Longlong: return(isUnsigned ? (object)ParseUInt64(data) : ParseInt64(data)); case ColumnType.Bit: return(ReadBit(data, columnDefinition)); case ColumnType.String: if (Connection.GuidFormat == MySqlGuidFormat.Char36 && columnDefinition.ColumnLength / ProtocolUtility.GetBytesPerCharacter(columnDefinition.CharacterSet) == 36) { return(Utf8Parser.TryParse(data, out Guid guid, out int guid36BytesConsumed, 'D') && guid36BytesConsumed == 36 ? guid : throw new FormatException()); } if (Connection.GuidFormat == MySqlGuidFormat.Char32 && columnDefinition.ColumnLength / ProtocolUtility.GetBytesPerCharacter(columnDefinition.CharacterSet) == 32) { return(Utf8Parser.TryParse(data, out Guid guid, out int guid32BytesConsumed, 'N') && guid32BytesConsumed == 32 ? guid : throw new FormatException()); } goto case ColumnType.VarString; case ColumnType.VarString: case ColumnType.VarChar: case ColumnType.TinyBlob: case ColumnType.Blob: case ColumnType.MediumBlob: case ColumnType.LongBlob: if (columnDefinition.CharacterSet == CharacterSet.Binary) { var guidFormat = Connection.GuidFormat; if ((guidFormat == MySqlGuidFormat.Binary16 || guidFormat == MySqlGuidFormat.TimeSwapBinary16 || guidFormat == MySqlGuidFormat.LittleEndianBinary16) && columnDefinition.ColumnLength == 16) { return(CreateGuidFromBytes(guidFormat, data)); } return(data.ToArray()); } return(Encoding.UTF8.GetString(data)); case ColumnType.Json: return(Encoding.UTF8.GetString(data)); case ColumnType.Short: return(isUnsigned ? (object)ParseUInt16(data) : ParseInt16(data)); case ColumnType.Date: case ColumnType.DateTime: case ColumnType.Timestamp: return(ParseDateTime(data)); case ColumnType.Time: return(Utility.ParseTimeSpan(data)); case ColumnType.Year: return(ParseInt32(data)); case ColumnType.Float: return(!Utf8Parser.TryParse(data, out float floatValue, out var floatBytesConsumed) || floatBytesConsumed != data.Length ? throw new FormatException() : floatValue); case ColumnType.Double: return(!Utf8Parser.TryParse(data, out double doubleValue, out var doubleBytesConsumed) || doubleBytesConsumed != data.Length ? throw new FormatException() : doubleValue); case ColumnType.Decimal: case ColumnType.NewDecimal: return(Utf8Parser.TryParse(data, out decimal decimalValue, out int bytesConsumed) && bytesConsumed == data.Length ? decimalValue : throw new FormatException()); case ColumnType.Geometry: return(data.ToArray()); default: throw new NotImplementedException("Reading {0} not implemented".FormatInvariant(columnDefinition.ColumnType)); } }
protected override object GetValueCore(ReadOnlySpan <byte> data, ColumnDefinitionPayload columnDefinition) { var isUnsigned = (columnDefinition.ColumnFlags & ColumnFlags.Unsigned) != 0; switch (columnDefinition.ColumnType) { case ColumnType.Tiny: if (Connection.TreatTinyAsBoolean && columnDefinition.ColumnLength == 1 && !isUnsigned) { return(data[0] != 0); } return(isUnsigned ? (object)data[0] : (sbyte)data[0]); case ColumnType.Int24: case ColumnType.Long: return(isUnsigned ? (object)MemoryMarshal.Read <uint>(data) : MemoryMarshal.Read <int>(data)); case ColumnType.Longlong: return(isUnsigned ? (object)MemoryMarshal.Read <ulong>(data) : MemoryMarshal.Read <long>(data)); case ColumnType.Bit: // BIT column is transmitted as MSB byte array ulong bitValue = 0; for (int i = 0; i < data.Length; i++) { bitValue = bitValue * 256 + data[i]; } return(bitValue); case ColumnType.String: if (Connection.GuidFormat == MySqlGuidFormat.Char36 && columnDefinition.ColumnLength / ProtocolUtility.GetBytesPerCharacter(columnDefinition.CharacterSet) == 36) { return(Utf8Parser.TryParse(data, out Guid guid, out int guid36BytesConsumed, 'D') && guid36BytesConsumed == 36 ? guid : throw new FormatException()); } if (Connection.GuidFormat == MySqlGuidFormat.Char32 && columnDefinition.ColumnLength / ProtocolUtility.GetBytesPerCharacter(columnDefinition.CharacterSet) == 32) { return(Utf8Parser.TryParse(data, out Guid guid, out int guid32BytesConsumed, 'N') && guid32BytesConsumed == 32 ? guid : throw new FormatException()); } goto case ColumnType.VarString; case ColumnType.VarString: case ColumnType.VarChar: case ColumnType.TinyBlob: case ColumnType.Blob: case ColumnType.MediumBlob: case ColumnType.LongBlob: if (columnDefinition.CharacterSet == CharacterSet.Binary) { var guidFormat = Connection.GuidFormat; if ((guidFormat == MySqlGuidFormat.Binary16 || guidFormat == MySqlGuidFormat.TimeSwapBinary16 || guidFormat == MySqlGuidFormat.LittleEndianBinary16) && columnDefinition.ColumnLength == 16) { return(CreateGuidFromBytes(guidFormat, data)); } return(data.ToArray()); } return(Encoding.UTF8.GetString(data)); case ColumnType.Json: return(Encoding.UTF8.GetString(data)); case ColumnType.Short: return(isUnsigned ? (object)MemoryMarshal.Read <ushort>(data) : MemoryMarshal.Read <short>(data)); case ColumnType.Date: case ColumnType.DateTime: case ColumnType.Timestamp: return(ReadDateTime(data)); case ColumnType.Time: return(ReadTimeSpan(data)); case ColumnType.Year: return((int)MemoryMarshal.Read <short>(data)); case ColumnType.Float: return(MemoryMarshal.Read <float>(data)); case ColumnType.Double: return(MemoryMarshal.Read <double>(data)); case ColumnType.Decimal: case ColumnType.NewDecimal: return(Utf8Parser.TryParse(data, out decimal decimalValue, out int bytesConsumed) && bytesConsumed == data.Length ? decimalValue : throw new FormatException()); case ColumnType.Geometry: return(data.ToArray()); default: throw new NotImplementedException("Reading {0} not implemented".FormatInvariant(columnDefinition.ColumnType)); } }