lib/google/cloud/bigquery/service.rb in google-cloud-bigquery-0.21.0 vs lib/google/cloud/bigquery/service.rb in google-cloud-bigquery-0.23.0
- old
+ new
@@ -17,10 +17,11 @@
require "google/cloud/errors"
require "google/apis/bigquery_v2"
require "pathname"
require "digest/md5"
require "mime/types"
+require "date"
module Google
module Cloud
module Bigquery
##
@@ -378,16 +379,18 @@
dry_run: options[:dryrun]
)
)
end
+ # rubocop:disable all
+
##
# Job description for query job
def query_table_config query, options
dest_table = table_ref_from options[:table]
default_dataset = dataset_ref_from options[:dataset]
- API::Job.new(
+ req = API::Job.new(
configuration: API::JobConfiguration.new(
query: API::JobConfigurationQuery.new(
query: query,
# tableDefinitions: { ... },
priority: priority_value(options[:priority]),
@@ -395,26 +398,171 @@
destination_table: dest_table,
create_disposition: create_disposition(options[:create]),
write_disposition: write_disposition(options[:write]),
allow_large_results: options[:large_results],
flatten_results: options[:flatten],
- default_dataset: default_dataset
+ default_dataset: default_dataset,
+ use_legacy_sql: resolve_legacy_sql(options[:legacy_sql],
+ options[:standard_sql])
)
)
)
+
+ if options[:params]
+ if Array === options[:params]
+ req.configuration.query.use_legacy_sql = false
+ req.configuration.query.parameter_mode = "POSITIONAL"
+ req.configuration.query.query_parameters = options[:params].map do |param|
+ to_query_param param
+ end
+ elsif Hash === options[:params]
+ req.configuration.query.use_legacy_sql = false
+ req.configuration.query.parameter_mode = "NAMED"
+ req.configuration.query.query_parameters = options[:params].map do |name, param|
+ to_query_param(param).tap do |named_param|
+ named_param.name = String name
+ end
+ end
+ else
+ fail "Query parameters must be an Array or a Hash."
+ end
+ end
+
+ req
end
def query_config query, options = {}
dataset_config = dataset_ref_from options[:dataset], options[:project]
- API::QueryRequest.new(
+ req = API::QueryRequest.new(
query: query,
max_results: options[:max],
default_dataset: dataset_config,
timeout_ms: options[:timeout],
dry_run: options[:dryrun],
- use_query_cache: options[:cache]
+ use_query_cache: options[:cache],
+ use_legacy_sql: resolve_legacy_sql(options[:legacy_sql],
+ options[:standard_sql])
)
+
+ if options[:params]
+ if Array === options[:params]
+ req.use_legacy_sql = false
+ req.parameter_mode = "POSITIONAL"
+ req.query_parameters = options[:params].map do |param|
+ to_query_param param
+ end
+ elsif Hash === options[:params]
+ req.use_legacy_sql = false
+ req.parameter_mode = "NAMED"
+ req.query_parameters = options[:params].map do |name, param|
+ to_query_param(param).tap do |named_param|
+ named_param.name = String name
+ end
+ end
+ else
+ fail "Query parameters must be an Array or a Hash."
+ end
+ end
+
+ req
+ end
+
+ def to_query_param value
+ if TrueClass === value
+ return API::QueryParameter.new(
+ parameter_type: API::QueryParameterType.new(type: "BOOL"),
+ parameter_value: API::QueryParameterValue.new(value: true)
+ )
+ elsif FalseClass === value
+ return API::QueryParameter.new(
+ parameter_type: API::QueryParameterType.new(type: "BOOL"),
+ parameter_value: API::QueryParameterValue.new(value: false)
+ )
+ elsif Integer === value
+ return API::QueryParameter.new(
+ parameter_type: API::QueryParameterType.new(type: "INT64"),
+ parameter_value: API::QueryParameterValue.new(value: value)
+ )
+ elsif Float === value
+ return API::QueryParameter.new(
+ parameter_type: API::QueryParameterType.new(type: "FLOAT64"),
+ parameter_value: API::QueryParameterValue.new(value: value)
+ )
+ elsif String === value
+ return API::QueryParameter.new(
+ parameter_type: API::QueryParameterType.new(type: "STRING"),
+ parameter_value: API::QueryParameterValue.new(value: value)
+ )
+ elsif DateTime === value
+ return API::QueryParameter.new(
+ parameter_type: API::QueryParameterType.new(type: "DATETIME"),
+ parameter_value: API::QueryParameterValue.new(
+ value: value.strftime("%Y-%m-%d %H:%M:%S.%6N"))
+ )
+ elsif Date === value
+ return API::QueryParameter.new(
+ parameter_type: API::QueryParameterType.new(type: "DATE"),
+ parameter_value: API::QueryParameterValue.new(value: value.to_s)
+ )
+ elsif ::Time === value
+ return API::QueryParameter.new(
+ parameter_type: API::QueryParameterType.new(type: "TIMESTAMP"),
+ parameter_value: API::QueryParameterValue.new(
+ value: value.strftime("%Y-%m-%d %H:%M:%S.%6N%:z"))
+ )
+ elsif Bigquery::Time === value
+ return API::QueryParameter.new(
+ parameter_type: API::QueryParameterType.new(type: "TIME"),
+ parameter_value: API::QueryParameterValue.new(value: value.value)
+ )
+ elsif value.respond_to?(:read) && value.respond_to?(:rewind)
+ value.rewind
+ return API::QueryParameter.new(
+ parameter_type: API::QueryParameterType.new(type: "BYTES"),
+ parameter_value: API::QueryParameterValue.new(
+ value: value.read.force_encoding("ASCII-8BIT"))
+ )
+ elsif Array === value
+ array_params = value.map { |param| to_query_param param }
+ return API::QueryParameter.new(
+ parameter_type: API::QueryParameterType.new(
+ type: "ARRAY",
+ array_type: array_params.first.parameter_type
+ ),
+ parameter_value: API::QueryParameterValue.new(
+ array_values: array_params.map(&:parameter_value)
+ )
+ )
+ elsif Hash === value
+ struct_pairs = value.map do |name, param|
+ struct_param = to_query_param param
+ [API::QueryParameterType::StructType.new(
+ name: String(name),
+ type: struct_param.parameter_type
+ ), struct_param.parameter_value]
+ end
+
+ return API::QueryParameter.new(
+ parameter_type: API::QueryParameterType.new(
+ type: "STRUCT",
+ struct_types: struct_pairs.map(&:first)
+ ),
+ parameter_value: API::QueryParameterValue.new(
+ struct_values: struct_pairs.map(&:last)
+ )
+ )
+ else
+ fail "A query parameter of type #{value.class} is not supported."
+ end
+ v
+ end
+
+ # rubocop:enable all
+
+ def resolve_legacy_sql legacy_sql, standard_sql
+ return legacy_sql unless legacy_sql.nil?
+ return !standard_sql unless standard_sql.nil?
end
##
# Job description for copy job
def copy_table_config source, target, options = {}