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;
        }
Beispiel #3
0
        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));
            }
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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));
            }
        }