diff --git a/lib/rebel/sql.rb b/lib/rebel/sql.rb index b5216e8..b79d56d 100644 --- a/lib/rebel/sql.rb +++ b/lib/rebel/sql.rb @@ -183,59 +183,67 @@ module Rebel end def create_table(table_name, desc) - raw %[CREATE TABLE #{name(table_name)} (#{list(desc.map { |k, v| "#{name(k)} #{v}" })})] + raw <<-SQL + CREATE TABLE #{name(table_name)} ( + #{list(desc.map { |k, v| "#{name(k)} #{v}" })} + ) + SQL end def drop_table(table_name) - raw "DROP TABLE #{name(table_name)}" + raw <<-SQL + DROP TABLE #{name(table_name)} + SQL end def select(*fields, distinct: nil, from: nil, where: nil, inner: nil, left: nil, right: nil, group: nil, order: nil, limit: nil, offset: nil) - raw [ - "SELECT #{distinct ? "DISTINCT #{names(*distinct)}" : names(*fields)}", - from?(from), - inner?(inner), - left?(left), - right?(right), - where?(where), - group?(group), - order?(order), - limit?(limit, offset), - ].compact.join(' ') + raw <<-SQL + SELECT #{distinct ? "DISTINCT #{names(*distinct)}" : names(*fields)} + #{from?(from)} + #{inner?(inner)} + #{left?(left)} + #{right?(right)} + #{where?(where)} + #{group?(group)} + #{order?(order)} + #{limit?(limit, offset)} + SQL end def insert_into(table_name, *rows) - raw [ - "INSERT INTO #{name(table_name)} (#{names(*rows.first.keys)})", - "VALUES #{list(rows.map { |r| "(#{values(*r.values)})" })}", - ].join(' ') + raw <<-SQL + INSERT INTO #{name(table_name)} (#{names(*rows.first.keys)}) + VALUES #{list(rows.map { |r| "(#{values(*r.values)})" })} + SQL end def update(table_name, set: nil, where: nil, inner: nil, left: nil, right: nil) raise ArgumentError if set.nil? - raw [ - "UPDATE #{name(table_name)}", - "SET #{assign_clause(set)}", - inner?(inner), - left?(left), - right?(right), - where?(where), - ].compact.join(' ') + raw <<-SQL + UPDATE #{name(table_name)} + SET #{assign_clause(set)} + #{inner?(inner)} + #{left?(left)} + #{right?(right)} + #{where?(where)} + SQL end def delete_from(table_name, where: nil, inner: nil, left: nil, right: nil) - raw [ - "DELETE FROM #{name(table_name)}", - inner?(inner), - left?(left), - right?(right), - where?(where), - ].join(' ') + raw <<-SQL + DELETE FROM #{name(table_name)} + #{inner?(inner)} + #{left?(left)} + #{right?(right)} + #{where?(where)} + SQL end def truncate(table_name) - raw "TRUNCATE #{name(table_name)}" + raw <<-SQL + TRUNCATE #{name(table_name)} + SQL end ## Functions @@ -292,10 +300,7 @@ module Rebel end def escape_str(str) - str.dup.tap do |s| - s.gsub!('\\') { @escaped_string_backslash } if @escaped_string_backslash - s.gsub!(@string_quote) { @escaped_string_quote } - end + str.gsub(@string_quote, @escaped_string_quote) end def value(v) @@ -393,7 +398,6 @@ module Rebel @identifier_quote = options[:identifier_quote] || '"' @string_quote = options[:string_quote] || "'" @escaped_string_quote = options[:escaped_string_quote] || "''" - @escaped_string_backslash = options[:escaped_string_backslash] @true_literal = options[:true_literal] || 'TRUE' @false_literal = options[:false_literal] || 'FALSE' diff --git a/rebel.gemspec b/rebel.gemspec index 75a3680..eb211cb 100644 --- a/rebel.gemspec +++ b/rebel.gemspec @@ -1,11 +1,11 @@ Gem::Specification.new do |s| s.name = 'rebel' - s.version = '0.7.2' + s.version = '0.7.0' s.licenses = ['MIT'] s.summary = 'Fight against the Object tyranny' s.description = 'SQL-flavoured Ruby, or is it the other way around?' s.authors = ['Loic Nageleisen'] s.email = 'loic.nageleisen@gmail.com' s.files = Dir['lib/**/*.rb'] - s.homepage = 'https://gitlab.com/lloeki/rebel.git' + s.homepage = 'https://github.com/lloeki/rebel.git' end diff --git a/test/test_raw.rb b/test/test_raw.rb index e3cee69..185f84c 100644 --- a/test/test_raw.rb +++ b/test/test_raw.rb @@ -8,7 +8,7 @@ class TestRaw < Minitest::Test end def assert_mysql(expected, &actual) - assert_equal(expected.to_s, Rebel::SQL(identifier_quote: '`', escaped_string_quote: "\\'", escaped_string_backslash: '\\', &actual).to_s) + assert_equal(expected.to_s, Rebel::SQL(identifier_quote: '`', string_quote: '"', escaped_string_quote: '""', &actual).to_s) end def assert_sqlite(expected, &actual) @@ -137,43 +137,33 @@ class TestRaw < Minitest::Test def test_string assert_sql("'FOO'") { value('FOO') } - assert_mysql("'FOO'") { value('FOO') } + assert_mysql('"FOO"') { value('FOO') } assert_postgresql("'FOO'") { value('FOO') } assert_sqlite("'FOO'") { value('FOO') } end def test_escaped_string - assert_sql (%q('FOO''BAR')) { value(%q(FOO'BAR)) } - assert_postgresql (%q('FOO''BAR')) { value(%q(FOO'BAR)) } - assert_sqlite (%q('FOO''BAR')) { value(%q(FOO'BAR)) } - assert_mysql (%q('FOO\'BAR')) { value(%q(FOO'BAR)) } + assert_sql("'FOO''BAR'") { value("FOO'BAR") } + assert_mysql('"FOO\'BAR"') { value("FOO'BAR") } + assert_postgresql("'FOO''BAR'") { value("FOO'BAR") } + assert_sqlite("'FOO''BAR'") { value("FOO'BAR") } - assert_sql (%q('FOO"BAR')) { value(%q(FOO"BAR)) } - assert_postgresql (%q('FOO"BAR')) { value(%q(FOO"BAR)) } - assert_sqlite (%q('FOO"BAR')) { value(%q(FOO"BAR)) } - assert_mysql (%q('FOO"BAR')) { value(%q(FOO"BAR)) } - - assert_sql (%q('FOO\BAR')) { value(%q(FOO\BAR)) } - assert_postgresql (%q('FOO\BAR')) { value(%q(FOO\BAR)) } - assert_sqlite (%q('FOO\BAR')) { value(%q(FOO\BAR)) } - assert_mysql (%q('FOO\\BAR')) { value(%q(FOO\BAR)) } - - assert_sql (%q('FOO\\''BAR')) { value(%q(FOO\'BAR)) } - assert_postgresql (%q('FOO\\''BAR')) { value(%q(FOO\'BAR)) } - assert_sqlite (%q('FOO\\''BAR')) { value(%q(FOO\'BAR)) } - assert_mysql (%q('FOO\\\'BAR')) { value(%q(FOO\'BAR)) } + assert_sql("'FOO\"BAR'") { value('FOO"BAR') } + assert_mysql('"FOO""BAR"') { value('FOO"BAR') } + assert_postgresql("'FOO\"BAR'") { value('FOO"BAR') } + assert_sqlite("'FOO\"BAR'") { value('FOO"BAR') } end def test_boolean_literal - assert_sql('TRUE') { value(true) } - assert_mysql('TRUE') { value(true) } - assert_postgresql('TRUE') { value(true) } - assert_sqlite('1') { value(true) } + assert_sql("TRUE") { value(true) } + assert_mysql("TRUE") { value(true) } + assert_postgresql("TRUE") { value(true) } + assert_sqlite("1") { value(true) } - assert_sql('FALSE') { value(false) } - assert_mysql('FALSE') { value(false) } - assert_postgresql('FALSE') { value(false) } - assert_sqlite('0') { value(false) } + assert_sql("FALSE") { value(false) } + assert_mysql("FALSE") { value(false) } + assert_postgresql("FALSE") { value(false) } + assert_sqlite("0") { value(false) } end def test_value @@ -189,7 +179,7 @@ class TestRaw < Minitest::Test end def test_select - assert_sql('SELECT * FROM "foo"') { select(raw('*'), from: name(:foo)) } + assert_sql('SELECT * FROM "foo"') { select(raw('*'), from: name(:foo)).gsub(/\s+/, ' ').strip } end def test_select_without_from @@ -197,50 +187,50 @@ class TestRaw < Minitest::Test end def test_select_distinct - assert_sql('SELECT DISTINCT "bar" FROM "foo"') { select(distinct: :bar, from: :foo) } + assert_sql('SELECT DISTINCT "bar" FROM "foo"') { select(distinct: :bar, from: :foo).gsub(/\s+/, ' ').strip } end def test_select_distinct_multiple - assert_sql('SELECT DISTINCT "bar", "baz" FROM "foo"') { select(distinct: [:bar, :baz], from: :foo) } + assert_sql('SELECT DISTINCT "bar", "baz" FROM "foo"') { select(distinct: [:bar, :baz], from: :foo).gsub(/\s+/, ' ').strip } end def test_select_group_by - assert_sql('SELECT "bar" FROM "foo" GROUP BY "baz"') { select(:bar, from: :foo, group: by(:baz)) } + assert_sql('SELECT "bar" FROM "foo" GROUP BY "baz"') { select(:bar, from: :foo, group: by(:baz)).gsub(/\s+/, ' ').strip } end def test_select_group_by_having - assert_sql('SELECT "bar" FROM "foo" GROUP BY "baz" HAVING COUNT("qux") > 5') { select(:bar, from: :foo, group: by(:baz).having(count(:qux).gt(5))) } + assert_sql('SELECT "bar" FROM "foo" GROUP BY "baz" HAVING COUNT("qux") > 5') { select(:bar, from: :foo, group: by(:baz).having(count(:qux).gt(5))).gsub(/\s+/, ' ').strip } end def test_select_order_by - assert_sql('SELECT "bar" FROM "foo" ORDER BY "baz"') { select(:bar, from: :foo, order: by(:baz)) } + assert_sql('SELECT "bar" FROM "foo" ORDER BY "baz"') { select(:bar, from: :foo, order: by(:baz)).gsub(/\s+/, ' ').strip } end def test_select_order_by_asc - assert_sql('SELECT "bar" FROM "foo" ORDER BY "baz" ASC') { select(:bar, from: :foo, order: by(:baz).asc) } + assert_sql('SELECT "bar" FROM "foo" ORDER BY "baz" ASC') { select(:bar, from: :foo, order: by(:baz).asc).gsub(/\s+/, ' ').strip } end def test_select_order_by_desc - assert_sql('SELECT "bar" FROM "foo" ORDER BY "baz" DESC') { select(:bar, from: :foo, order: by(:baz).desc) } + assert_sql('SELECT "bar" FROM "foo" ORDER BY "baz" DESC') { select(:bar, from: :foo, order: by(:baz).desc).gsub(/\s+/, ' ').strip } end def test_select_multiple_order_by - assert_sql('SELECT "bar" FROM "foo" ORDER BY "baz", "qux"') { select(:bar, from: :foo, order: by(:baz, :qux)) } + assert_sql('SELECT "bar" FROM "foo" ORDER BY "baz", "qux"') { select(:bar, from: :foo, order: by(:baz, :qux)).gsub(/\s+/, ' ').strip } end def test_select_multiple_order_by_opposing - assert_sql('SELECT "bar" FROM "foo" ORDER BY "baz" ASC, "qux" DESC') { select(:bar, from: :foo, order: by(name(:baz).asc, name(:qux).desc)) } + assert_sql('SELECT "bar" FROM "foo" ORDER BY "baz" ASC, "qux" DESC') { select(:bar, from: :foo, order: by(name(:baz).asc, name(:qux).desc)).gsub(/\s+/, ' ').strip } end def test_select_limit - assert_sql('SELECT "bar" FROM "foo" LIMIT 10') { select(:bar, from: :foo, limit: 10) } + assert_sql('SELECT "bar" FROM "foo" LIMIT 10') { select(:bar, from: :foo, limit: 10).gsub(/\s+/, ' ').strip } end def test_select_offset - assert_sql('SELECT "bar" FROM "foo" LIMIT 10 OFFSET 20') { select(:bar, from: :foo, limit: 10, offset: 20) } + assert_sql('SELECT "bar" FROM "foo" LIMIT 10 OFFSET 20') { select(:bar, from: :foo, limit: 10, offset: 20).gsub(/\s+/, ' ').strip } end def test_nested_select - assert_sql('SELECT * FROM "foo" WHERE "bar" IN (SELECT "bar" FROM "foo")') { select(raw('*'), from: name(:foo), where: name(:bar).in(select(name(:bar), from: name(:foo)))) } + assert_sql('SELECT * FROM "foo" WHERE "bar" IN ( SELECT "bar" FROM "foo" )') { select(raw('*'), from: name(:foo), where: name(:bar).in(select(name(:bar), from: name(:foo)))).gsub(/\s+/, ' ').strip } end end