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