Пример #1
0
        internal static string Format(ClickHouseType type, object value)
        {
            return(type.TypeCode switch
            {
                var simpleType when
                simpleType == ClickHouseTypeCode.UInt8 ||
                simpleType == ClickHouseTypeCode.UInt16 ||
                simpleType == ClickHouseTypeCode.UInt32 ||
                simpleType == ClickHouseTypeCode.UInt64 ||
                simpleType == ClickHouseTypeCode.Int8 ||
                simpleType == ClickHouseTypeCode.Int16 ||
                simpleType == ClickHouseTypeCode.Int32 ||
                simpleType == ClickHouseTypeCode.Int64 => Convert.ToString(value, CultureInfo.InvariantCulture),

                var floatType when
                floatType == ClickHouseTypeCode.Float32 ||
                floatType == ClickHouseTypeCode.Float64 => FormatFloat(value),

                ClickHouseTypeCode.Decimal when value is decimal decimalValue => decimalValue.ToString(CultureInfo.InvariantCulture),

                var stringType when
                stringType == ClickHouseTypeCode.String ||
                stringType == ClickHouseTypeCode.FixedString ||
                stringType == ClickHouseTypeCode.LowCardinality ||
                stringType == ClickHouseTypeCode.Enum8 ||
                stringType == ClickHouseTypeCode.Enum16 ||
                stringType == ClickHouseTypeCode.UUID ||
                stringType == ClickHouseTypeCode.IPv4 ||
                stringType == ClickHouseTypeCode.IPv6 => value.ToString(),

                ClickHouseTypeCode.Nothing => $"null",

                ClickHouseTypeCode.Date when value is DateTime date => $"{date:yyyy-MM-dd}",
                ClickHouseTypeCode.DateTime when type is DateTimeType dateTimeType && value is DateTime dateTime =>
                dateTimeType.TimeZone == null
                        ? $"{dateTime:yyyy-MM-dd HH:mm:ss}"
                        : $"{dateTime.ToUniversalTime():yyyy-MM-dd HH:mm:ss}",
                ClickHouseTypeCode.DateTime64 when type is DateTime64Type dateTimeType && value is DateTime dateTime =>
                dateTimeType.TimeZone == null
                        ? $"{dateTime:yyyy-MM-dd HH:mm:ss.fffffff}"
                        : $"{dateTime.ToUniversalTime():yyyy-MM-dd HH:mm:ss.fffffff}",

                ClickHouseTypeCode.Nullable when type is NullableType nullableType =>
                value is null || value == DBNull.Value ?
                "null" :
                $"{Format(nullableType.UnderlyingType, value)}",

                ClickHouseTypeCode.Array when type is ArrayType arrayType && value is IEnumerable enumerable =>
                $"[{string.Join(",", enumerable.Cast<object>().Select(obj => InlineParameterFormatter.Format(arrayType.UnderlyingType, obj)))}]",

                ClickHouseTypeCode.Tuple when type is TupleType tupleType && value is ITuple tuple =>
                $"({string.Join(",", tupleType.UnderlyingTypes.Select((x, i) => InlineParameterFormatter.Format(x, tuple[i])))})",

                _ => throw new NotSupportedException($"Cannot convert value {value} to type {type.TypeCode}")
            });
        internal static string Format(ClickHouseType type, object value)
        {
            switch (type)
            {
            case NothingType nt:
                return(NullValueString);

            case IntegerType it:
            case FloatType ft:
                return(Convert.ToString(value, CultureInfo.InvariantCulture));

            case DecimalType dt:
                return(Convert.ToDecimal(value).ToString(CultureInfo.InvariantCulture));

            case DateType dt when value is DateTimeOffset @do:
                return(@do.Date.ToString("yyyy-MM-dd"));

            case DateType dt:
                return(Convert.ToDateTime(value).ToString("yyyy-MM-dd"));

            case StringType st:
            case FixedStringType tt:
            case Enum8Type e8t:
            case Enum16Type e16t:
            case IPv4Type ip4:
            case IPv6Type ip6:
            case UuidType uuidType:
                return(value.ToString());

            case LowCardinalityType lt:
                return(Format(lt.UnderlyingType, value));

            case DateTimeType dtt when value is DateTime dt:
                return(dt.ToString("s", CultureInfo.InvariantCulture));

            case DateTimeType dtt when value is DateTimeOffset dto:
                return(dto.ToString("s", CultureInfo.InvariantCulture));

            case DateTime64Type dtt when value is DateTime dtv:
                return($"{dtv:yyyy-MM-dd HH:mm:ss.fffffff}");

            case DateTime64Type dtt when value is DateTimeOffset dto:
                return($"{dto:yyyy-MM-dd HH:mm:ss.fffffff}");

            case NullableType nt:
                return(value is null || value is DBNull ? NullValueString : $"{Format(nt.UnderlyingType, value)}");

            case ArrayType arrayType when value is IEnumerable enumerable:
                return($"[{string.Join(",", enumerable.Cast<object>().Select(obj => InlineParameterFormatter.Format(arrayType.UnderlyingType, obj)))}]");

            case TupleType tupleType when value is ITuple tuple:
                return($"({string.Join(",", tupleType.UnderlyingTypes.Select((x, i) => InlineParameterFormatter.Format(x, tuple[i])))})");

            case MapType mapType when value is IDictionary dict:
                var strings = string.Join(",", dict.Keys.Cast <object>().Select(k => $"{InlineParameterFormatter.Format(mapType.KeyType, k)} : {InlineParameterFormatter.Format(mapType.ValueType, dict[k])}"));
                return($"{{{string.Join(",", strings)}}}");

            default:
                throw new Exception($"Cannot convert {value} to {type}");
            }
        }