lib/mini_sql/builder.rb in mini_sql-1.4.0 vs lib/mini_sql/builder.rb in mini_sql-1.5.0
- old
+ new
@@ -9,12 +9,17 @@
@connection = connection
@count_variables = 1
@is_prepared = false
end
+ def initialize_copy(_original_builder)
+ @args = @args.transform_values { |v| v.dup }
+ @sections = @sections.transform_values { |v| v.dup }
+ end
+
literals1 =
- [:set, :where2, :where, :order_by, :left_join, :join, :select, :group_by].each do |k|
+ [:set, :where2, :where2_or, :where, :where_or, :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])
else # convert simple params to hash
args.each do |v|
@@ -46,11 +51,11 @@
def sql_literal(literals)
literals.each do |name, part_sql|
if PREDEFINED_SQL_LITERALS.include?(name)
raise "/*#{name}*/ is predefined, use method `.#{name}` instead `sql_literal`"
end
- @sections[name] = part_sql.is_a?(::MiniSql::Builder) ? part_sql.to_sql : part_sql
+ @sections[name] = part_sql.respond_to?(:to_sql) ? part_sql.to_sql : part_sql
end
self
end
[:query, :query_single, :query_hash, :query_array, :exec].each do |m|
@@ -73,46 +78,58 @@
def to_sql(hash_args = nil)
@connection.param_encoder.encode(parametrized_sql, union_parameters(hash_args))
end
+ def count(field = '*')
+ dup.select("count(#{field})").query_single.first
+ end
+
private def connection_switcher
if @is_prepared
@connection.prepared
else
@connection
end
end
+ WHERE_SECTIONS = [%i[where where_or], %i[where2 where2_or]]
private def parametrized_sql
sql = @sql.dup
- @sections.each do |k, v|
- joined = nil
- case k
- when :select
- joined = (+"SELECT ") << v.join(" , ")
- when :where, :where2
- joined = (+"WHERE ") << v.map { |c| (+"(") << c << ")" }.join(" AND ")
- 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 :mq_auto_limit")
- when :offset
- joined = (+"OFFSET :mq_auto_offset")
- when :order_by
- joined = (+"ORDER BY ") << v.join(" , ")
- when :group_by
- joined = (+"GROUP BY ") << v.join(" , ")
- when :set
- joined = (+"SET ") << v.join(" , ")
- else # for sql_literal
- joined = v
+ WHERE_SECTIONS.each do |section_and, section_or|
+ if (or_values = @sections.delete(section_or))
+ @sections[section_and] ||= []
+ @sections[section_and] << or_values.map { |c| "(#{c})" }.join(" OR ")
end
+ end
- unless sql.sub!("/*#{k}*/", joined)
+ @sections.each do |k, v|
+ joined =
+ case k
+ when :select
+ "SELECT #{v.join(" , ")}"
+ when :where, :where2
+ "WHERE #{v.map { |c| "(#{c})" }.join(" AND ")}"
+ when :join
+ v.map { |item| "JOIN #{item}" }.join("\n")
+ when :left_join
+ v.map { |item| "LEFT JOIN #{item}" }.join("\n")
+ when :limit
+ "LIMIT :mq_auto_limit"
+ when :offset
+ "OFFSET :mq_auto_offset"
+ when :order_by
+ "ORDER BY #{v.join(" , ")}"
+ when :group_by
+ "GROUP BY #{v.join(" , ")}"
+ when :set
+ "SET #{v.join(" , ")}"
+ else # for sql_literal
+ v
+ end
+
+ unless sql.gsub!("/*#{k}*/", joined)
raise "The section for the /*#{k}*/ clause was not found!"
end
end
sql