internal QueryParameter ToQueryParameter(BigqueryParameterMode parameterMode) { if (parameterMode == BigqueryParameterMode.Named && string.IsNullOrEmpty(Name)) { throw new InvalidOperationException("Unnamed parameters cannot be used in command using BigqueryParameterMode.Named"); } var value = Value; if (Type == null && value == null) { throw new InvalidOperationException("A null-valued parameter must have an explicitly specified type"); } var type = Type ?? InferParameterType(value); var parameter = new QueryParameter { Name = Name, ParameterType = new QueryParameterType { Type = EnumMap.ToApiValue(type) }, }; switch (type) { case BigqueryParameterType.Array: return(PopulateArrayParameter(parameter, value, ArrayType)); case BigqueryParameterType.Bool: return(parameter.PopulateScalar <bool>(value, x => x ? "TRUE" : "FALSE") ?? parameter.PopulateScalar <string>(value, x => x) ?? parameter.UseNullScalarOrThrow(value)); case BigqueryParameterType.Bytes: return(parameter.PopulateScalar <byte[]>(value, x => Convert.ToBase64String(x)) ?? parameter.PopulateScalar <string>(value, x => x) ?? parameter.UseNullScalarOrThrow(value)); case BigqueryParameterType.Date: return(parameter.PopulateScalar <DateTime>(value, x => x.ToString("yyyy-MM-dd", InvariantCulture)) ?? parameter.PopulateScalar <DateTimeOffset>(value, x => x.ToString("yyyy-MM-dd", InvariantCulture)) ?? parameter.PopulateScalar <string>(value, x => x) ?? parameter.UseNullScalarOrThrow(value)); case BigqueryParameterType.DateTime: return(parameter.PopulateScalar <DateTime>(value, x => x.ToString("yyyy-MM-dd HH:mm:ss.FFFFFF", InvariantCulture)) ?? parameter.PopulateScalar <DateTimeOffset>(value, x => x.ToString("yyyy-MM-dd HH:mm:ss.FFFFFF", InvariantCulture)) ?? parameter.PopulateScalar <string>(value, x => x) ?? parameter.UseNullScalarOrThrow(value)); case BigqueryParameterType.Float64: return(parameter.PopulateInteger(value) ?? parameter.PopulateFloatingPoint(value) ?? parameter.PopulateScalar <string>(value, x => x) ?? parameter.UseNullScalarOrThrow(value)); case BigqueryParameterType.Int64: return(parameter.PopulateInteger(value) ?? parameter.PopulateScalar <string>(value, x => x) ?? parameter.UseNullScalarOrThrow(value)); case BigqueryParameterType.String: return(parameter.PopulateScalar <string>(value, x => x) ?? parameter.UseNullScalarOrThrow(value)); case BigqueryParameterType.Struct: throw new NotImplementedException("Struct parameters are not yet implemented"); case BigqueryParameterType.Time: return(parameter.PopulateScalar <TimeSpan>(value, FormatTimeSpan) ?? parameter.PopulateScalar <DateTimeOffset>(value, x => x.ToString("HH:mm:ss.FFFFFF", InvariantCulture)) ?? parameter.PopulateScalar <DateTime>(value, x => x.ToString("HH:mm:ss.FFFFFF", InvariantCulture)) ?? parameter.PopulateScalar <string>(value, x => x) ?? parameter.UseNullScalarOrThrow(value)); case BigqueryParameterType.Timestamp: return(parameter.PopulateScalar <DateTime>(value, x => { if (x.Kind != DateTimeKind.Utc) { throw new InvalidOperationException($"A DateTime with a Kind of {x.Kind} cannot be used for a Timestamp parameter"); } return x.ToString("yyyy-MM-dd HH:mm:ss.FFFFFF"); }) ?? parameter.PopulateScalar <DateTimeOffset>(value, x => x.ToString("yyyy-MM-dd HH:mm:ss.FFFFFFzzz", InvariantCulture)) ?? parameter.PopulateScalar <string>(value, x => x) ?? parameter.UseNullScalarOrThrow(value)); default: throw new InvalidOperationException($"No conversion available for parameter type {type}"); } }
internal QueryParameter ToQueryParameter() { var value = Value; if (Type == null && value == null) { throw new InvalidOperationException("A null-valued parameter must have an explicitly specified type"); } var type = Type ?? InferParameterType(value); var parameter = new QueryParameter { Name = Name, ParameterType = new QueryParameterType { Type = type.ToParameterApiType() }, }; switch (type) { case BigQueryDbType.Array: return(PopulateArrayParameter(parameter, value, ArrayElementType)); case BigQueryDbType.Bool: return(parameter.PopulateScalar <bool>(value, x => x ? "TRUE" : "FALSE") ?? parameter.PopulateScalar <string>(value, x => x) ?? parameter.UseNullScalarOrThrow(value)); case BigQueryDbType.Bytes: return(parameter.PopulateScalar <byte[]>(value, x => Convert.ToBase64String(x)) ?? parameter.PopulateScalar <string>(value, x => x) ?? parameter.UseNullScalarOrThrow(value)); case BigQueryDbType.Date: return(parameter.PopulateScalar <DateTime>(value, x => x.AsBigQueryDate()) ?? parameter.PopulateScalar <DateTimeOffset>(value, x => x.AsBigQueryDate()) ?? parameter.PopulateScalar <string>(value, x => x) ?? parameter.UseNullScalarOrThrow(value)); case BigQueryDbType.DateTime: return(parameter.PopulateScalar <DateTime>(value, x => x.ToString("yyyy-MM-dd HH:mm:ss.FFFFFF", InvariantCulture)) ?? parameter.PopulateScalar <DateTimeOffset>(value, x => x.ToString("yyyy-MM-dd HH:mm:ss.FFFFFF", InvariantCulture)) ?? parameter.PopulateScalar <string>(value, x => x) ?? parameter.UseNullScalarOrThrow(value)); case BigQueryDbType.Float64: return(parameter.PopulateInteger(value) ?? parameter.PopulateFloatingPoint(value) ?? parameter.PopulateScalar <string>(value, x => x) ?? parameter.UseNullScalarOrThrow(value)); case BigQueryDbType.Int64: return(parameter.PopulateInteger(value) ?? parameter.PopulateScalar <string>(value, x => x) ?? parameter.UseNullScalarOrThrow(value)); case BigQueryDbType.String: return(parameter.PopulateScalar <string>(value, x => x) ?? parameter.UseNullScalarOrThrow(value)); case BigQueryDbType.Struct: throw new NotImplementedException("Struct parameters are not yet implemented"); case BigQueryDbType.Time: return(parameter.PopulateScalar <TimeSpan>(value, FormatTimeSpan) ?? parameter.PopulateScalar <DateTimeOffset>(value, x => x.ToString("HH:mm:ss.FFFFFF", InvariantCulture)) ?? parameter.PopulateScalar <DateTime>(value, x => x.ToString("HH:mm:ss.FFFFFF", InvariantCulture)) ?? parameter.PopulateScalar <string>(value, x => x) ?? parameter.UseNullScalarOrThrow(value)); case BigQueryDbType.Numeric: return(parameter.PopulateScalar <BigQueryNumeric>(value, x => x.ToString()) ?? parameter.PopulateScalar <string>(value, x => x) ?? parameter.UseNullScalarOrThrow(value)); case BigQueryDbType.Geography: return(parameter.PopulateScalar <BigQueryGeography>(value, x => x.Text) ?? parameter.PopulateScalar <string>(value, x => x) ?? parameter.UseNullScalarOrThrow(value)); case BigQueryDbType.Timestamp: return(parameter.PopulateScalar <DateTime>(value, x => { if (x.Kind != DateTimeKind.Utc) { throw new InvalidOperationException($"A DateTime with a Kind of {x.Kind} cannot be used for a Timestamp parameter"); } return x.ToString("yyyy-MM-dd HH:mm:ss.FFFFFF+00", InvariantCulture); }) ?? parameter.PopulateScalar <DateTimeOffset>(value, x => x.ToString("yyyy-MM-dd HH:mm:ss.FFFFFFzzz", InvariantCulture)) ?? parameter.PopulateScalar <string>(value, x => x) ?? parameter.UseNullScalarOrThrow(value)); default: throw new InvalidOperationException($"No conversion available for parameter type {type}"); } }