lib/mini_sql/builder.rb in mini_sql-1.0.1 vs lib/mini_sql/builder.rb in mini_sql-1.1.0
- old
+ new
@@ -1,31 +1,75 @@
# frozen_string_literal: true
class MiniSql::Builder
def initialize(connection, template)
- @args = nil
+ @args = {}
@sql = template
@sections = {}
@connection = connection
+ @count_variables = 1
+ @is_prepared = false
end
- [:set, :where2, :where, :order_by, :limit, :left_join, :join, :offset, :select].each do |k|
- define_method k do |data, *args|
- if args && (args.length == 1) && (Hash === args[0])
- @args ||= {}
+ [:set, :where2, :where, :order_by, :left_join, :join, :select, :group_by].each do |k|
+ define_method k do |sql_part, *args|
+ if Hash === args[0]
@args.merge!(args[0])
- elsif args && args.length > 0
- data = @connection.param_encoder.encode(data, *args)
+ else # convert simple params to hash
+ args.each do |v|
+ param = "_m_#{@count_variables += 1}"
+ sql_part = sql_part.sub('?', ":#{param}")
+ @args[param] = v
+ end
end
+
@sections[k] ||= []
- @sections[k] << data
+ @sections[k] << sql_part
self
end
end
- def to_sql
+ [:limit, :offset].each do |k|
+ define_method k do |value|
+ @args["_m_#{k}"] = value
+ @sections[k] = true
+ self
+ end
+ end
+
+ [:query, :query_single, :query_hash, :query_array, :exec].each do |m|
+ class_eval <<~RUBY
+ def #{m}(hash_args = nil)
+ connection_switcher.#{m}(parametrized_sql, union_parameters(hash_args))
+ end
+ RUBY
+ end
+
+ def query_decorator(decorator, hash_args = nil)
+ connection_switcher.query_decorator(decorator, parametrized_sql, union_parameters(hash_args))
+ end
+
+ def prepared(condition = true)
+ @is_prepared = condition
+
+ self
+ end
+
+ def to_sql(hash_args = nil)
+ @connection.param_encoder.encode(parametrized_sql, union_parameters(hash_args))
+ end
+
+ private def connection_switcher
+ if @is_prepared
+ @connection.prepared
+ else
+ @connection
+ end
+ end
+
+ private def parametrized_sql
sql = @sql.dup
@sections.each do |k, v|
joined = nil
case k
@@ -36,44 +80,31 @@
when :join
joined = v.map { |item| (+"JOIN ") << item }.join("\n")
when :left_join
joined = v.map { |item| (+"LEFT JOIN ") << item }.join("\n")
when :limit
- joined = (+"LIMIT ") << v.last.to_i.to_s
+ joined = (+"LIMIT :_m_limit")
when :offset
- joined = (+"OFFSET ") << v.last.to_i.to_s
+ joined = (+"OFFSET :_m_offset")
when :order_by
joined = (+"ORDER BY ") << v.join(" , ")
+ when :group_by
+ joined = (+"GROUP BY ") << v.join(" , ")
when :set
joined = (+"SET ") << v.join(" , ")
end
sql.sub!("/*#{k}*/", joined)
end
+
sql
end
- [:query, :query_single, :query_hash, :exec].each do |m|
- class_eval <<~RUBY
- def #{m}(hash_args = nil)
- hash_args = @args.merge(hash_args) if hash_args && @args
- hash_args ||= @args
- if hash_args
- @connection.#{m}(to_sql, hash_args)
- else
- @connection.#{m}(to_sql)
- end
- end
- RUBY
- end
-
- def query_decorator(decorator, hash_args = nil)
- hash_args = @args.merge(hash_args) if hash_args && @args
- hash_args ||= @args
+ private def union_parameters(hash_args)
if hash_args
- @connection.query_decorator(decorator, to_sql, hash_args)
+ @args.merge(hash_args)
else
- @connection.query_decorator(decorator, to_sql)
+ @args
end
end
end