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}"); } }