lib/wise_gopher/base.rb in wise_gopher-0.1.0 vs lib/wise_gopher/base.rb in wise_gopher-0.2.0
- old
+ new
@@ -5,30 +5,41 @@
module WiseGopher
# Main inteface of the gem. Class to be inherited by the query class
class Base
def self.inherited(base)
base.class_eval do
- @params = {}
+ @raw_params = {}
+ @params = {}
end
base.include Methods
base.extend ClassMethods
end
# class methods for WiseGopher::Base
module ClassMethods
- attr_reader :row_class, :params
+ attr_reader :row_class, :params, :raw_params
def query(query)
const_set "QUERY", query.freeze
end
def param(name, type, transform = nil)
- param = WiseGopher::Param.new(name, type, transform)
+ new_param = WiseGopher::Param.new(name, type, transform)
- params[param.name] = param
+ ensure_param_name_is_available(new_param.name)
+
+ params[new_param.name] = new_param
end
+ def raw_param(name, **kwargs)
+ raw_param = WiseGopher::RawParam.new(name, **kwargs)
+
+ ensure_param_name_is_available(raw_param.name)
+
+ raw_params[raw_param.name] = raw_param
+ end
+
def row(base = nil, &block)
@row_class ||= base || define_generic_row_class
@row_class.include WiseGopher::Row
@@ -45,21 +56,31 @@
ensure_all_params_are_given(inputs)
new(inputs).execute
end
+ def ensure_all_params_are_given(inputs = {})
+ missing_params = required_params.keys - inputs.keys.map(&:to_s)
+
+ raise WiseGopher::ArgumentError, required_params.slice(*missing_params) if missing_params.any?
+ end
+
private
def define_generic_row_class
@row_class = const_set "Row", Class.new
end
- def ensure_all_params_are_given(inputs = {})
- missing_params = params.keys - inputs.keys.map(&:to_s)
+ def ensure_param_name_is_available(name)
+ return unless params[name] || raw_params[name]
- raise WiseGopher::ArgumentError, params.slice(*missing_params) if missing_params.any?
+ raise WiseGopher::ParamAlreadyDeclared, name
end
+
+ def required_params
+ params.merge(raw_params.reject { |_name, raw_param| raw_param.optional? })
+ end
end
# instance methods for WiseGopher::Base
module Methods
extend ::Forwardable
@@ -70,44 +91,54 @@
@inputs = inputs
@binds = []
@bind_symbol = WiseGopher.postgresql? ? +"$1" : "?"
@query_prepared = false
+ self.class.ensure_all_params_are_given(inputs)
+
prepare_query
end
def execute
ensure_row_class_is_declared
- result = connection.exec_query(@query.squish, query_class.to_s, @binds, prepare: true)
+ result = connection.exec_query(query.squish, query_class.to_s, @binds, prepare: true)
ensure_all_columns_are_declared(result)
result.entries.map { |entry| row_class.new(entry) }
end
def prepare_query
return if @query_prepared
- @query = query_class::QUERY.dup
+ prepare_raw_params
+ prepare_params
+
+ @query_prepared = true
+ end
+
+ private
+
+ def prepare_params
query_class.params.each do |name, param|
name = name.to_sym
value = @inputs[name]
bind_params(value, param)
end
-
- @query_prepared = true
end
- private
-
def query_class
self.class
end
+ def query
+ @query ||= query_class::QUERY.dup
+ end
+
def bind_params(value, param)
if value.is_a? Array
bind_collection_param(value, param)
else
bind_single_param(value, param)
@@ -115,23 +146,23 @@
end
def bind_collection_param(values, param)
bindings = values.map { use_bind_symbol }
- replace_binding_placeholder(param.name, bindings.join(", "))
+ replace_placeholder(param.name, bindings.join(", "))
values.each { |value| register_binding(value, param) }
end
def bind_single_param(value, param)
- replace_binding_placeholder(param.name, use_bind_symbol)
+ replace_placeholder(param.name, use_bind_symbol)
register_binding(value, param)
end
- def replace_binding_placeholder(name, binding_symbol)
- @query.gsub!(/{{ ?#{name} ?}}/, binding_symbol)
+ def replace_placeholder(name, value_to_insert)
+ query.gsub!(/{{ ?#{name} ?}}/, value_to_insert)
end
def register_binding(value, param)
@binds << param.build_bind(value)
end
@@ -158,9 +189,18 @@
raise UndeclaredColumns, undeclared_columns if undeclared_columns.any?
end
def connection
ActiveRecord::Base.connection
+ end
+
+ def prepare_raw_params
+ query_class.raw_params.each do |name, param|
+ name = name.to_sym
+ value = @inputs[name]
+
+ replace_placeholder(name, param.to_s(value))
+ end
end
end
end
end