sql-maker 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/CHANGELOG.md +3 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +23 -0
  7. data/Rakefile +14 -0
  8. data/lib/sql-maker.rb +5 -0
  9. data/lib/sql/maker.rb +676 -0
  10. data/lib/sql/maker/condition.rb +378 -0
  11. data/lib/sql/maker/error.rb +3 -0
  12. data/lib/sql/maker/helper.rb +22 -0
  13. data/lib/sql/maker/quoting.rb +138 -0
  14. data/lib/sql/maker/select.rb +544 -0
  15. data/lib/sql/maker/select/oracle.rb +30 -0
  16. data/lib/sql/maker/select_set.rb +194 -0
  17. data/lib/sql/maker/util.rb +54 -0
  18. data/lib/sql/query_maker.rb +429 -0
  19. data/scripts/perl2ruby.rb +34 -0
  20. data/spec/maker/bind_param_spec.rb +62 -0
  21. data/spec/maker/condition/add_raw_spec.rb +29 -0
  22. data/spec/maker/condition/compose_empty_spec.rb +72 -0
  23. data/spec/maker/condition/empty_values_spec.rb +25 -0
  24. data/spec/maker/condition/make_term_spec.rb +38 -0
  25. data/spec/maker/condition/where_spec.rb +35 -0
  26. data/spec/maker/delete_spec.rb +116 -0
  27. data/spec/maker/insert_empty_spec.rb +23 -0
  28. data/spec/maker/insert_spec.rb +61 -0
  29. data/spec/maker/new_line_spec.rb +9 -0
  30. data/spec/maker/select/oracle/oracle_spec.rb +16 -0
  31. data/spec/maker/select/pod_select_spec.rb +34 -0
  32. data/spec/maker/select/statement_spec.rb +805 -0
  33. data/spec/maker/select_set_spec.rb +294 -0
  34. data/spec/maker/select_spec.rb +470 -0
  35. data/spec/maker/simple_spec.rb +54 -0
  36. data/spec/maker/strict_spec.rb +45 -0
  37. data/spec/maker/subquery_spec.rb +77 -0
  38. data/spec/maker/update_spec.rb +138 -0
  39. data/spec/maker/util_spec.rb +6 -0
  40. data/spec/maker/where_spec.rb +28 -0
  41. data/spec/query_maker/and_using_hash_spec.rb +13 -0
  42. data/spec/query_maker/cheatsheet_spec.rb +32 -0
  43. data/spec/query_maker/column_bind_spec.rb +55 -0
  44. data/spec/query_maker/refs_in_bind_spec.rb +19 -0
  45. data/spec/spec_helper.rb +15 -0
  46. data/sql-maker.gemspec +25 -0
  47. metadata +185 -0
@@ -0,0 +1,61 @@
1
+ require_relative '../spec_helper'
2
+ require 'sql/maker'
3
+ require 'sql/maker/helper'
4
+
5
+ describe 'SQL::Maker#insert' do
6
+ include SQL::Maker::Helper
7
+
8
+ context 'driver sqlite' do
9
+ it 'hash column-value' do
10
+ builder = SQL::Maker.new(:driver => 'sqlite')
11
+ sql, bind = builder.insert('foo', {:bar => 'baz', :john => 'man', :created_on => ["datetime('now')"], :updated_on => ["datetime(?)", "now"]})
12
+ expect(sql).to be == %Q{INSERT INTO "foo"\n("bar", "john", "created_on", "updated_on")\nVALUES (?, ?, datetime('now'), datetime(?))}
13
+ expect(bind.join(',')).to be == 'baz,man,now'
14
+ end
15
+
16
+ # it 'array column-value' do
17
+
18
+ it 'insert ignore, hash column-value' do
19
+ builder = SQL::Maker.new(:driver => 'sqlite')
20
+ sql, bind = builder.insert('foo', { :bar => 'baz', :john => 'man', :created_on => ["datetime('now')"], :updated_on => ["datetime(?)", "now"]}, { :prefix => 'INSERT IGNORE' })
21
+ expect(sql).to be == %Q{INSERT IGNORE "foo"\n("bar", "john", "created_on", "updated_on")\nVALUES (?, ?, datetime('now'), datetime(?))}
22
+ expect(bind.join(',')).to be == 'baz,man,now'
23
+ end
24
+
25
+ # it 'insert ignore, array column-value' do
26
+
27
+ it 'term' do
28
+ builder = SQL::Maker.new(:driver => 'sqlite')
29
+ sql, bind = builder.insert('foo', {:bar => 'baz', :john => 'man', :created_on => sql_raw("datetime('now')"), :updated_on => sql_raw("datetime(?)", "now")})
30
+ expect(sql).to be == %Q{INSERT INTO "foo"\n("bar", "john", "created_on", "updated_on")\nVALUES (?, ?, datetime('now'), datetime(?))}
31
+ expect(bind.join(',')).to be == 'baz,man,now'
32
+ end
33
+ end
34
+
35
+ context 'driver mysql' do
36
+ it 'hash column-value' do
37
+ builder = SQL::Maker.new(:driver => 'mysql')
38
+ sql, bind = builder.insert('foo', {:bar => 'baz', :john => 'man', :created_on => ["NOW()"], :updated_on => ["FROM_UNIXTIME(?)", 1302536204 ] })
39
+ expect(sql).to be == %Q{INSERT INTO `foo`\n(`bar`, `john`, `created_on`, `updated_on`)\nVALUES (?, ?, NOW(), FROM_UNIXTIME(?))}
40
+ expect(bind.join(',')).to be == 'baz,man,1302536204'
41
+ end
42
+
43
+ # it 'array column-value' do
44
+
45
+ it 'insert ignore, hash column-value' do
46
+ builder = SQL::Maker.new(:driver => 'mysql')
47
+ sql, bind = builder.insert('foo', { :bar => 'baz', :john => 'man', :created_on => ["NOW()"], :updated_on => ["FROM_UNIXTIME(?)", 1302536204 ] }, { :prefix => 'INSERT IGNORE' })
48
+ expect(sql).to be == %Q{INSERT IGNORE `foo`\n(`bar`, `john`, `created_on`, `updated_on`)\nVALUES (?, ?, NOW(), FROM_UNIXTIME(?))}
49
+ expect(bind.join(',')).to be == 'baz,man,1302536204'
50
+ end
51
+
52
+ # it 'insert ignore, array column-value' do
53
+
54
+ it 'term' do
55
+ builder = SQL::Maker.new(:driver => 'mysql')
56
+ sql, bind = builder.insert('foo', {:bar => 'baz', :john => 'man', :created_on => sql_raw("NOW()"), :updated_on => sql_raw("FROM_UNIXTIME(?)", 1302536204)})
57
+ expect(sql).to be == %Q{INSERT INTO `foo`\n(`bar`, `john`, `created_on`, `updated_on`)\nVALUES (?, ?, NOW(), FROM_UNIXTIME(?))}
58
+ expect(bind.join(',')).to be == 'baz,man,1302536204'
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,9 @@
1
+ require_relative '../spec_helper'
2
+ require 'sql/maker'
3
+
4
+ describe 'SQL::Maker' do
5
+ it 'empty string' do
6
+ builder = SQL::Maker.new(:new_line => '', :driver => 'mysql')
7
+ expect(builder.new_line).to be == ''
8
+ end
9
+ end
@@ -0,0 +1,16 @@
1
+ require_relative '../../../spec_helper'
2
+ require 'sql/maker/select/oracle'
3
+
4
+ describe 'SQL::Maker::Select::Oracle' do
5
+ let(:sel) do
6
+ SQL::Maker::Select::Oracle.new( :new_line => %q{ } )
7
+ .add_select('foo')
8
+ .add_from('user')
9
+ .limit(10)
10
+ .offset(20)
11
+ end
12
+
13
+ it do
14
+ expect(sel.as_sql).to be == 'SELECT * FROM ( SELECT foo, ROW_NUMBER() OVER (ORDER BY 1) R FROM user LIMIT 10 OFFSET 20 ) WHERE R BETWEEN 20 + 1 AND 10 + 20'
15
+ end
16
+ end
@@ -0,0 +1,34 @@
1
+ require_relative '../../spec_helper'
2
+ require 'sql/maker/select'
3
+
4
+ begin
5
+ fname = "#{ROOT}/lib/sql/maker/select.rb"
6
+ file = File.open(fname)
7
+ lineno = 0
8
+ while line = file.gets
9
+ lineno += 1
10
+ break if line =~ /=head1/
11
+ end
12
+ code = ''
13
+ describe 'SQL::Maker::Select' do
14
+ it do
15
+ while line = file.gets
16
+ lineno += 1
17
+ next if line =~ /^#/
18
+ if line =~ /^[ ]{4,}.*# => (.+)/
19
+ # puts "----------------------"
20
+ # puts code
21
+ expected = eval($1, binding)
22
+ got = eval(code, binding, fname, lineno - 4)
23
+ got.gsub!(/\n/, ' ')
24
+ got.gsub!(/ +$/, '')
25
+ expect(got).to be == expected
26
+ elsif (/^[ ]{4,}(.+)/)
27
+ code += "#{$1}\n"
28
+ else
29
+ code = '' # clear
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,805 @@
1
+ require_relative '../../spec_helper'
2
+ require 'sql/maker/select'
3
+
4
+ describe 'SQL::Maker::Select' do
5
+ def ns(args)
6
+ SQL::Maker::Select.new(args)
7
+ end
8
+
9
+ context 'PREFIX' do
10
+ context 'quote_char: "`", name_sep: "."' do
11
+ it 'simple' do
12
+ stmt = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
13
+ stmt.add_select('*')
14
+ stmt.add_from('foo')
15
+ expect(stmt.as_sql).to be == "SELECT *\nFROM `foo`"
16
+ end
17
+
18
+ it 'SQL_CALC_FOUND_ROWS' do
19
+ stmt = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
20
+ stmt.prefix('SELECT SQL_CALC_FOUND_ROWS ')
21
+ stmt.add_select('*')
22
+ stmt.add_from('foo')
23
+ expect(stmt.as_sql).to be == "SELECT SQL_CALC_FOUND_ROWS *\nFROM `foo`"
24
+ end
25
+ end
26
+
27
+ context 'quote_char: "", name_sep: ".", new_line: " "' do
28
+ it 'simple' do
29
+ stmt = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ })
30
+ stmt.add_select('*')
31
+ stmt.add_from('foo')
32
+ expect(stmt.as_sql).to be == "SELECT * FROM foo"
33
+ end
34
+
35
+ it 'SQL_CALC_FOUND_ROWS' do
36
+ stmt = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ } )
37
+ stmt.prefix('SELECT SQL_CALC_FOUND_ROWS ')
38
+ stmt.add_select('*')
39
+ stmt.add_from('foo')
40
+ expect(stmt.as_sql).to be == "SELECT SQL_CALC_FOUND_ROWS * FROM foo"
41
+ end
42
+ end
43
+ end
44
+
45
+ context 'FROM' do
46
+ context 'quote_char: "`", name_sep: "."' do
47
+ it 'single' do
48
+ stmt = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
49
+ stmt.add_from('foo')
50
+ expect(stmt.as_sql).to be == "FROM `foo`"
51
+ end
52
+
53
+ it 'multi' do
54
+ stmt = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
55
+ stmt.add_from( 'foo' )
56
+ stmt.add_from( 'bar' )
57
+ expect(stmt.as_sql).to be == "FROM `foo`, `bar`"
58
+ end
59
+
60
+ it 'multi + alias' do
61
+ stmt = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
62
+ stmt.add_from( 'foo' => 'f' )
63
+ stmt.add_from( 'bar' => 'b' )
64
+ expect(stmt.as_sql).to be == "FROM `foo` `f`, `bar` `b`"
65
+ end
66
+ end
67
+
68
+ context 'quote_char: "", name_sep: ".", new_line: " "' do
69
+ it 'single' do
70
+ stmt = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ } )
71
+ stmt.add_from('foo')
72
+ expect(stmt.as_sql).to be == "FROM foo"
73
+ end
74
+
75
+ it 'multi' do
76
+ stmt = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ } )
77
+ stmt.add_from( 'foo' )
78
+ stmt.add_from( 'bar' )
79
+ expect(stmt.as_sql).to be == "FROM foo, bar"
80
+ end
81
+
82
+ it 'multi + alias' do
83
+ stmt = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ } )
84
+ stmt.add_from( 'foo' => 'f' )
85
+ stmt.add_from( 'bar' => 'b' )
86
+ expect(stmt.as_sql).to be == "FROM foo f, bar b"
87
+ end
88
+ end
89
+ end
90
+
91
+ context 'JOIN' do
92
+ context 'quote_char: "`", name_sep: "."' do
93
+ it 'inner join' do
94
+ stmt = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
95
+ stmt.add_join(
96
+ :foo => {
97
+ :type => 'inner',
98
+ :table => 'baz',
99
+ }
100
+ )
101
+ expect(stmt.as_sql).to be == "FROM `foo` INNER JOIN `baz`"
102
+ end
103
+
104
+ it 'inner join with condition' do
105
+ stmt = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
106
+ stmt.add_join(
107
+ :foo => {
108
+ :type => 'inner',
109
+ :table => 'baz',
110
+ :condition => 'foo.baz_id = baz.baz_id'
111
+ }
112
+ )
113
+ expect(stmt.as_sql).to be == "FROM `foo` INNER JOIN `baz` ON foo.baz_id = baz.baz_id"
114
+ end
115
+
116
+ it 'from and inner join with condition' do
117
+ stmt = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
118
+ stmt.add_from( 'bar' )
119
+ stmt.add_join(
120
+ :foo => {
121
+ :type => 'inner',
122
+ :table => 'baz',
123
+ :condition => 'foo.baz_id = baz.baz_id'
124
+ }
125
+ )
126
+ expect(stmt.as_sql).to be == "FROM `foo` INNER JOIN `baz` ON foo.baz_id = baz.baz_id, `bar`"
127
+ end
128
+
129
+ it 'inner join with hash condition' do
130
+ stmt = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
131
+ stmt.add_join(
132
+ :foo => {
133
+ :type => 'inner',
134
+ :table => 'baz',
135
+ :condition => {'foo.baz_id' => 'baz.baz_id'},
136
+ }
137
+ )
138
+ expect(stmt.as_sql).to be == "FROM `foo` INNER JOIN `baz` ON `foo`.`baz_id` = `baz`.`baz_id`"
139
+ end
140
+
141
+ it 'inner join with hash condition with multi keys' do
142
+ stmt = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
143
+ stmt.add_join(
144
+ :foo => {
145
+ :type => 'inner',
146
+ :table => 'baz',
147
+ :condition => {
148
+ 'foo.baz_id' => 'baz.baz_id',
149
+ 'foo.status' => 'baz.status',
150
+ },
151
+ }
152
+ )
153
+ expect(stmt.as_sql).to be == "FROM `foo` INNER JOIN `baz` ON `foo`.`baz_id` = `baz`.`baz_id` AND `foo`.`status` = `baz`.`status`"
154
+ end
155
+
156
+ it 'test case for bug found where add_join is called twice' do
157
+ stmt = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
158
+ stmt.add_join(
159
+ :foo => {
160
+ :type => 'inner',
161
+ :table => 'baz',
162
+ :alias => 'b1',
163
+ :condition => 'foo.baz_id = b1.baz_id AND b1.quux_id = 1'
164
+ },
165
+ )
166
+ stmt.add_join(
167
+ :foo => {
168
+ :type => 'left',
169
+ :table => 'baz',
170
+ :alias => 'b2',
171
+ :condition => 'foo.baz_id = b2.baz_id AND b2.quux_id = 2'
172
+ },
173
+ )
174
+ expect(stmt.as_sql).to be == "FROM `foo` INNER JOIN `baz` `b1` ON foo.baz_id = b1.baz_id AND b1.quux_id = 1 LEFT JOIN `baz` `b2` ON foo.baz_id = b2.baz_id AND b2.quux_id = 2"
175
+ end
176
+
177
+ it 'test case adding another table onto the whole mess' do
178
+ stmt = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
179
+ stmt.add_join(
180
+ :foo => {
181
+ :type => 'inner',
182
+ :table => 'baz',
183
+ :alias => 'b1',
184
+ :condition => 'foo.baz_id = b1.baz_id AND b1.quux_id = 1'
185
+ },
186
+ )
187
+ stmt.add_join(
188
+ :foo => {
189
+ :type => 'left',
190
+ :table => 'baz',
191
+ :alias => 'b2',
192
+ :condition => 'foo.baz_id = b2.baz_id AND b2.quux_id = 2'
193
+ },
194
+ )
195
+ stmt.add_join(
196
+ :quux => {
197
+ :type => 'inner',
198
+ :table => 'foo',
199
+ :alias => 'f1',
200
+ :condition => 'f1.quux_id = quux.q_id'
201
+ }
202
+ )
203
+
204
+ expect(stmt.as_sql).to be == "FROM `foo` INNER JOIN `baz` `b1` ON foo.baz_id = b1.baz_id AND b1.quux_id = 1 LEFT JOIN `baz` `b2` ON foo.baz_id = b2.baz_id AND b2.quux_id = 2 INNER JOIN `foo` `f1` ON f1.quux_id = quux.q_id"
205
+ end
206
+
207
+ context 'quote_char: "", name_sep: ".", new_line: " "' do
208
+ it 'inner join' do
209
+ stmt = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ } )
210
+ stmt.add_join(
211
+ :foo => {
212
+ :type => 'inner',
213
+ :table => 'baz',
214
+ }
215
+ )
216
+ expect(stmt.as_sql).to be == "FROM foo INNER JOIN baz"
217
+ end
218
+
219
+ it 'inner join with condition' do
220
+ stmt = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ } )
221
+ stmt.add_join(
222
+ :foo => {
223
+ :type => 'inner',
224
+ :table => 'baz',
225
+ :condition => 'foo.baz_id = baz.baz_id'
226
+ }
227
+ )
228
+ expect(stmt.as_sql).to be == "FROM foo INNER JOIN baz ON foo.baz_id = baz.baz_id"
229
+ end
230
+
231
+ it 'from and inner join with condition' do
232
+ stmt = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ } )
233
+ stmt.add_from( 'bar' )
234
+ stmt.add_join(
235
+ :foo => {
236
+ :type => 'inner',
237
+ :table => 'baz',
238
+ :condition => 'foo.baz_id = baz.baz_id'
239
+ }
240
+ )
241
+ expect(stmt.as_sql).to be == "FROM foo INNER JOIN baz ON foo.baz_id = baz.baz_id, bar"
242
+ end
243
+
244
+ it 'test case for bug found where add_join is called twice' do
245
+ stmt = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ } )
246
+ stmt.add_join(
247
+ :foo => {
248
+ :type => 'inner',
249
+ :table => 'baz',
250
+ :alias => 'b1',
251
+ :condition => 'foo.baz_id = b1.baz_id AND b1.quux_id = 1'
252
+ },
253
+ )
254
+ stmt.add_join(
255
+ :foo => {
256
+ :type => 'left',
257
+ :table => 'baz',
258
+ :alias => 'b2',
259
+ :condition => 'foo.baz_id = b2.baz_id AND b2.quux_id = 2'
260
+ },
261
+ )
262
+ expect(stmt.as_sql).to be == "FROM foo INNER JOIN baz b1 ON foo.baz_id = b1.baz_id AND b1.quux_id = 1 LEFT JOIN baz b2 ON foo.baz_id = b2.baz_id AND b2.quux_id = 2"
263
+ end
264
+
265
+ it 'test case adding another table onto the whole mess' do
266
+ stmt = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ } )
267
+ stmt.add_join(
268
+ :foo => {
269
+ :type => 'inner',
270
+ :table => 'baz',
271
+ :alias => 'b1',
272
+ :condition => 'foo.baz_id = b1.baz_id AND b1.quux_id = 1'
273
+ },
274
+ )
275
+ stmt.add_join(
276
+ :foo => {
277
+ :type => 'left',
278
+ :table => 'baz',
279
+ :alias => 'b2',
280
+ :condition => 'foo.baz_id = b2.baz_id AND b2.quux_id = 2'
281
+ },
282
+ )
283
+ stmt.add_join(
284
+ :quux => {
285
+ :type => 'inner',
286
+ :table => 'foo',
287
+ :alias => 'f1',
288
+ :condition => 'f1.quux_id = quux.q_id'
289
+ }
290
+ )
291
+ expect(stmt.as_sql).to be == "FROM foo INNER JOIN baz b1 ON foo.baz_id = b1.baz_id AND b1.quux_id = 1 LEFT JOIN baz b2 ON foo.baz_id = b2.baz_id AND b2.quux_id = 2 INNER JOIN foo f1 ON f1.quux_id = quux.q_id"
292
+ end
293
+ end
294
+ end
295
+ end
296
+
297
+ context 'GROUP BY' do
298
+ context 'quote_char: "`", name_sep: "."' do
299
+ it do
300
+ stmt = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
301
+ stmt.add_from( 'foo' )
302
+ stmt.add_group_by('baz')
303
+ expect(stmt.as_sql).to be == "FROM `foo`\nGROUP BY `baz`" # 'single bare group by'
304
+ end
305
+
306
+ it do
307
+ stmt = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
308
+ stmt.add_from( 'foo' )
309
+ stmt.add_group_by('baz' => 'DESC')
310
+ expect(stmt.as_sql).to be == "FROM `foo`\nGROUP BY `baz` DESC" # 'single group by with desc'
311
+ end
312
+
313
+ it do
314
+ stmt = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
315
+ stmt.add_from( 'foo' )
316
+ stmt.add_group_by('baz')
317
+ stmt.add_group_by('quux')
318
+ expect(stmt.as_sql).to be == "FROM `foo`\nGROUP BY `baz`, `quux`" # 'multiple group by'
319
+ end
320
+
321
+ it do
322
+ stmt = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
323
+ stmt.add_from( 'foo' )
324
+ stmt.add_group_by('baz', 'DESC')
325
+ stmt.add_group_by('quux', 'DESC')
326
+ expect(stmt.as_sql).to be == "FROM `foo`\nGROUP BY `baz` DESC, `quux` DESC" # 'multiple group by with desc'
327
+ end
328
+ end
329
+
330
+ context 'quote_char: "", name_sep: ".", new_line: " "' do
331
+ it do
332
+ stmt = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ } )
333
+ stmt.add_from( 'foo' )
334
+ stmt.add_group_by('baz')
335
+ expect(stmt.as_sql).to be == "FROM foo GROUP BY baz" # 'single bare group by'
336
+ end
337
+
338
+ it do
339
+ stmt = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ } )
340
+ stmt.add_from( 'foo' )
341
+ stmt.add_group_by('baz' => 'DESC')
342
+ expect(stmt.as_sql).to be == "FROM foo GROUP BY baz DESC" # 'single group by with desc'
343
+ end
344
+
345
+ it do
346
+ stmt = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ } )
347
+ stmt.add_from( 'foo' )
348
+ stmt.add_group_by('baz')
349
+ stmt.add_group_by('quux')
350
+ expect(stmt.as_sql).to be == "FROM foo GROUP BY baz, quux" # 'multiple group by'
351
+ end
352
+
353
+ it do
354
+ stmt = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ } )
355
+ stmt.add_from( 'foo' )
356
+ stmt.add_group_by('baz', 'DESC')
357
+ stmt.add_group_by('quux', 'DESC')
358
+ expect(stmt.as_sql).to be == "FROM foo GROUP BY baz DESC, quux DESC" # 'multiple group by with desc'
359
+ end
360
+ end
361
+
362
+ context 'ORDER BY' do
363
+ context 'quote_char: "`", name_sep: "."' do
364
+ it do
365
+ stmt = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
366
+ stmt.add_from( 'foo' )
367
+ stmt.add_order_by('baz' => 'DESC')
368
+ expect(stmt.as_sql).to be == "FROM `foo`\nORDER BY `baz` DESC" # 'single order by'
369
+ end
370
+
371
+ it do
372
+ stmt = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
373
+ stmt.add_from( 'foo' )
374
+ stmt.add_order_by( 'baz' => 'DESC' )
375
+ stmt.add_order_by( 'quux' => 'ASC' )
376
+ expect(stmt.as_sql).to be == "FROM `foo`\nORDER BY `baz` DESC, `quux` ASC" # 'multiple order by'
377
+ end
378
+
379
+ # it do
380
+ # stmt = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
381
+ # stmt.add_from( 'foo' )
382
+ # stmt.add_order_by( \'baz DESC' )
383
+ # expect(stmt.as_sql).to be == "FROM `foo`\nORDER BY baz DESC" # should not quote
384
+ # end
385
+ end
386
+
387
+ context 'quote_char: "", name_sep: ".", new_line: " "' do
388
+ it do
389
+ stmt = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ } )
390
+ stmt.add_from( 'foo' )
391
+ stmt.add_order_by('baz' => 'DESC')
392
+ expect(stmt.as_sql).to be == "FROM foo ORDER BY baz DESC" # 'single order by'
393
+ end
394
+
395
+ it do
396
+ stmt = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ })
397
+ stmt.add_from( 'foo' )
398
+ stmt.add_order_by( 'baz' => 'DESC' )
399
+ stmt.add_order_by( 'quux' => 'ASC' )
400
+ expect(stmt.as_sql).to be == "FROM foo ORDER BY baz DESC, quux ASC" # 'multiple order by'
401
+ end
402
+
403
+ # it 'scalarref' do
404
+ # stmt = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ })
405
+ # stmt.add_from( 'foo' )
406
+ # stmt.add_order_by( 'baz DESC' )
407
+ # expect(stmt.as_sql).to be == "FROM foo ORDER BY baz DESC" # should not quote
408
+ # end
409
+ end
410
+ end
411
+
412
+ context 'GROUP BY + ORDER BY' do
413
+ it 'quote_char: "`", name_sep: "."' do
414
+ stmt = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
415
+ stmt.add_from( 'foo' )
416
+ stmt.add_group_by('quux')
417
+ stmt.add_order_by('baz' => 'DESC')
418
+ expect(stmt.as_sql).to be == "FROM `foo`\nGROUP BY `quux`\nORDER BY `baz` DESC" # 'group by with order by'
419
+ end
420
+
421
+ it 'quote_char: "", name_sep: ".", new_line: " "' do
422
+ stmt = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ })
423
+ stmt.add_from( 'foo' )
424
+ stmt.add_group_by('quux')
425
+ stmt.add_order_by('baz' => 'DESC')
426
+ expect(stmt.as_sql).to be == "FROM foo GROUP BY quux ORDER BY baz DESC" # 'group by with order by'
427
+ end
428
+ end
429
+
430
+ context 'LIMIT OFFSET' do
431
+ it 'quote_char: "`", name_sep: "."' do
432
+ stmt = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
433
+ stmt.add_from( 'foo' )
434
+ stmt.limit(5)
435
+ expect(stmt.as_sql).to be == "FROM `foo`\nLIMIT 5"
436
+ stmt.offset(10)
437
+ expect(stmt.as_sql).to be == "FROM `foo`\nLIMIT 5 OFFSET 10"
438
+ stmt.limit(" 15g"); ## Non-numerics should cause an error
439
+ expect { stmt.as_sql }.to raise_error("Non-numerics in limit clause (n)") # "bogus limit causes as_sql assertion")
440
+ end
441
+
442
+ it 'quote_char: "", name_sep: ".", new_line: " "' do
443
+ stmt = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ } )
444
+ stmt.add_from( 'foo' )
445
+ stmt.limit(5)
446
+ expect(stmt.as_sql).to be == "FROM foo LIMIT 5"
447
+ stmt.offset(10)
448
+ expect(stmt.as_sql).to be == "FROM foo LIMIT 5 OFFSET 10"
449
+ stmt.limit(" 15g"); ## Non-numerics should cause an error
450
+ expect { stmt.as_sql }.to raise_error("Non-numerics in limit clause (n)") # bogus limit causes as_sql assertion")
451
+ end
452
+ end
453
+
454
+ context 'WHERE' do
455
+ context 'quote_char: "`", name_sep: "."' do
456
+ it 'single equals' do
457
+ stmt = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
458
+ stmt.add_where(:foo => 'bar')
459
+ expect(stmt.as_sql_where).to be == "WHERE (`foo` = ?)\n"
460
+ expect(stmt.bind.size).to be == 1
461
+ expect(stmt.bind[0]).to be == 'bar'
462
+ end
463
+
464
+ it 'single equals multi values is IN() statement' do
465
+ stmt = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
466
+ stmt.add_where(:foo => [ 'bar', 'baz' ])
467
+ expect(stmt.as_sql_where).to be == "WHERE (`foo` IN (?, ?))\n"
468
+ expect(stmt.bind.size).to be == 2
469
+ expect(stmt.bind[0]).to be == 'bar'
470
+ expect(stmt.bind[1]).to be == 'baz'
471
+ end
472
+
473
+ it 'new condition, single equals multi values is IN() statement' do
474
+ stmt = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
475
+ cond = stmt.new_condition()
476
+ cond.add(:foo => [ 'bar', 'baz' ])
477
+ stmt.set_where(cond)
478
+ expect(stmt.as_sql_where).to be == "WHERE (`foo` IN (?, ?))\n"
479
+ expect(stmt.bind.size).to be == 2
480
+ expect(stmt.bind[0]).to be == 'bar'
481
+ expect(stmt.bind[1]).to be == 'baz'
482
+ end
483
+ end
484
+
485
+ context 'quote_char: "", name_sep: ".", new_line: " "' do
486
+ it 'single equals' do
487
+ stmt = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ } )
488
+ stmt.add_where(:foo => 'bar')
489
+ expect(stmt.as_sql_where).to be == "WHERE (foo = ?) "
490
+ expect(stmt.bind.size).to be == 1
491
+ expect(stmt.bind[0]).to be == 'bar'
492
+ end
493
+
494
+ it 'single equals multi values is IN() statement' do
495
+ stmt = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ } )
496
+ stmt.add_where(:foo => [ 'bar', 'baz' ])
497
+ expect(stmt.as_sql_where).to be == "WHERE (foo IN (?, ?)) "
498
+ expect(stmt.bind.size).to be == 2
499
+ expect(stmt.bind[0]).to be == 'bar'
500
+ expect(stmt.bind[1]).to be == 'baz'
501
+ end
502
+
503
+ it 'new condition, single equals multi values is IN() statement' do
504
+ stmt = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ } )
505
+ cond = stmt.new_condition()
506
+ cond.add(:foo => [ 'bar', 'baz' ])
507
+ stmt.set_where(cond)
508
+ expect(stmt.as_sql_where).to be == "WHERE (foo IN (?, ?)) "
509
+ expect(stmt.bind.size).to be == 2
510
+ expect(stmt.bind[0]).to be == 'bar'
511
+ expect(stmt.bind[1]).to be == 'baz'
512
+ end
513
+ end
514
+ end
515
+
516
+ context 'add_select' do
517
+ context 'quote_char: "`", name_sep: "."' do
518
+ it 'simple' do
519
+ stmt = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
520
+ stmt.add_select(:foo => 'foo')
521
+ stmt.add_select('bar')
522
+ stmt.add_from( %w( baz ) )
523
+ expect(stmt.as_sql).to be == "SELECT `foo`, `bar`\nFROM `baz`"
524
+ end
525
+
526
+ #it 'with scalar ref' do
527
+ # stmt = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
528
+ # stmt.add_select('f.foo' => 'foo')
529
+ # stmt.add_select(\'COUNT(*)' => 'count')
530
+ # stmt.add_from( %w( baz ) )
531
+ # expect(stmt.as_sql).to be == "SELECT `f`.`foo`, COUNT(*) AS `count`\nFROM `baz`"
532
+ #end
533
+ end
534
+
535
+ context 'quote_char: "", name_sep: ".", new_line: " "' do
536
+ it 'simple' do
537
+ stmt = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ } )
538
+ stmt.add_select(:foo => 'foo')
539
+ stmt.add_select('bar')
540
+ stmt.add_from( %w( baz ) )
541
+ expect(stmt.as_sql).to be == "SELECT foo, bar FROM baz"
542
+ end
543
+
544
+ it 'with scalar ref' do
545
+ stmt = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ } )
546
+ stmt.add_select('f.foo' => 'foo')
547
+ stmt.add_select('COUNT(*)' => 'count')
548
+ stmt.add_from( %w( baz ) )
549
+ expect(stmt.as_sql).to be == "SELECT f.foo, COUNT(*) AS count FROM baz"
550
+ end
551
+ end
552
+ end
553
+
554
+ context 'HAVING' do
555
+ # it 'quote_char: "`", name_sep: "."' do
556
+ # stmt = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
557
+ # stmt.add_select(:foo => 'foo')
558
+ # stmt.add_select(\'COUNT(*)' => 'count')
559
+ # stmt.add_from( %w(baz) )
560
+ # stmt.add_where(:foo => 1)
561
+ # stmt.add_group_by('baz')
562
+ # stmt.add_order_by('foo' => 'DESC')
563
+ # stmt.limit(2)
564
+ # stmt.add_having(:count => 2)
565
+ # #expect(stmt.as_sql).to be == "SELECT `foo`, COUNT(*) AS `count`\nFROM `baz`\nWHERE (`foo` = ?)\nGROUP BY `baz`\nHAVING (COUNT(*) = ?)\nORDER BY `foo` DESC\nLIMIT 2"
566
+ # expect(stmt.as_sql).to be == "SELECT `foo`, COUNT(*) AS `count`\nFROM `baz`\nWHERE (`foo` = ?)\nGROUP BY `baz`\nHAVING (COUNT(*) = ?)\nORDER BY `foo` DESC\nLIMIT 2"
567
+ # end
568
+
569
+ it 'quote_char: "", name_sep: ".", new_line: " "' do
570
+ stmt = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ } )
571
+ stmt.add_select(:foo => 'foo')
572
+ stmt.add_select('COUNT(*)' => 'count')
573
+ stmt.add_from( %w(baz) )
574
+ stmt.add_where(:foo => 1)
575
+ stmt.add_group_by('baz')
576
+ stmt.add_order_by('foo' => 'DESC')
577
+ stmt.limit(2)
578
+ stmt.add_having(:count => 2)
579
+ expect(stmt.as_sql).to be == "SELECT foo, COUNT(*) AS count FROM baz WHERE (foo = ?) GROUP BY baz HAVING (COUNT(*) = ?) ORDER BY foo DESC LIMIT 2"
580
+ end
581
+ end
582
+
583
+ context 'DISTINCT' do
584
+ it 'quote_char: "`", name_sep: "."' do
585
+ stmt = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
586
+ stmt.add_select(:foo => 'foo')
587
+ stmt.add_from( %w(baz) )
588
+ expect(stmt.as_sql).to be == "SELECT `foo`\nFROM `baz`"
589
+ stmt.distinct(1)
590
+ expect(stmt.as_sql).to be == "SELECT DISTINCT `foo`\nFROM `baz`"
591
+ end
592
+
593
+ it 'quote_char: "", name_sep: ".", new_line: " "' do
594
+ stmt = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ } )
595
+ stmt.add_select(:foo => 'foo')
596
+ stmt.add_from( %w(baz) )
597
+ expect(stmt.as_sql).to be == "SELECT foo FROM baz" # "DISTINCT is absent by default"
598
+ stmt.distinct(1)
599
+ expect(stmt.as_sql).to be == "SELECT DISTINCT foo FROM baz" # "we can turn on DISTINCT"
600
+ end
601
+ end
602
+
603
+ context 'index hint' do
604
+ it 'quote_char: "`", name_sep: "."' do
605
+ stmt = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
606
+ stmt.add_select(:foo => 'foo')
607
+ stmt.add_from( %w(baz) )
608
+ expect(stmt.as_sql).to be == "SELECT `foo`\nFROM `baz`" # "index hint is absent by default"
609
+ stmt.add_index_hint('baz' => { :type => 'USE', :list => ['index_hint']})
610
+ expect(stmt.as_sql).to be == "SELECT `foo`\nFROM `baz` USE INDEX (`index_hint`)" # "we can turn on USE INDEX"
611
+ end
612
+
613
+ it 'quote_char: "", name_sep: ".", new_line: " "' do
614
+ stmt = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ } )
615
+ stmt.add_select(:foo => 'foo')
616
+ stmt.add_from( %w(baz) )
617
+ expect(stmt.as_sql).to be == "SELECT foo FROM baz" # "index hint is absent by default"
618
+ stmt.add_index_hint('baz' => { :type => 'USE', :list => ['index_hint']})
619
+ expect(stmt.as_sql).to be == "SELECT foo FROM baz USE INDEX (index_hint)" # "we can turn on USE INDEX"
620
+ end
621
+
622
+ it 'hint as scalar' do
623
+ stmt = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ } )
624
+ stmt.add_select(:foo => 'foo')
625
+ stmt.add_from( %w(baz) )
626
+ stmt.add_index_hint('baz' => 'index_hint')
627
+ expect(stmt.as_sql).to be == "SELECT foo FROM baz USE INDEX (index_hint)" # "we can turn on USE INDEX"
628
+ end
629
+
630
+ it 'hint as array ref' do
631
+ stmt = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ } )
632
+ stmt.add_select(:foo => 'foo')
633
+ stmt.add_from( %w(baz) )
634
+ stmt.add_index_hint('baz' => ['index_hint'])
635
+ expect(stmt.as_sql).to be == "SELECT foo FROM baz USE INDEX (index_hint)" # "we can turn on USE INDEX"
636
+ end
637
+ end
638
+
639
+ context 'index hint with joins' do
640
+ context 'quote_char: "`", name_sep: "."' do
641
+ it do
642
+ stmt = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
643
+ stmt.add_select(:foo => 'foo')
644
+ stmt.add_index_hint('baz' => { :type => 'USE', :list => ['index_hint']})
645
+ stmt.add_join(
646
+ :baz => {
647
+ :type => 'inner',
648
+ :table => 'baz',
649
+ :condition => 'baz.baz_id = foo.baz_id'
650
+ }
651
+ )
652
+ expect(stmt.as_sql).to be == "SELECT `foo`\nFROM `baz` USE INDEX (`index_hint`) INNER JOIN `baz` ON baz.baz_id = foo.baz_id" # 'USE INDEX with JOIN'
653
+ end
654
+
655
+ it do
656
+ stmt = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
657
+ stmt.add_select(:foo => 'foo')
658
+ stmt.add_index_hint('baz' => { :type => 'USE', :list => ['index_hint']})
659
+ stmt.add_join(
660
+ :baz => {
661
+ :type => 'inner',
662
+ :table => 'baz',
663
+ :alias => 'b1',
664
+ :condition => 'baz.baz_id = b1.baz_id AND b1.quux_id = 1'
665
+ },
666
+ )
667
+ stmt.add_join(
668
+ :baz => {
669
+ :type => 'left',
670
+ :table => 'baz',
671
+ :alias => 'b2',
672
+ :condition => 'baz.baz_id = b2.baz_id AND b2.quux_id = 2'
673
+ },
674
+ )
675
+ expect(stmt.as_sql).to be == "SELECT `foo`\nFROM `baz` USE INDEX (`index_hint`) INNER JOIN `baz` `b1` ON baz.baz_id = b1.baz_id AND b1.quux_id = 1 LEFT JOIN `baz` `b2` ON baz.baz_id = b2.baz_id AND b2.quux_id = 2" # 'USE INDEX with JOINs'
676
+ end
677
+ end
678
+
679
+ context 'quote_char: "", name_sep: ".", new_line: " "' do
680
+ it do
681
+ stmt = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ } )
682
+ stmt.add_select(:foo => 'foo')
683
+ stmt.add_index_hint('baz' => { :type => 'USE', :list => ['index_hint']})
684
+ stmt.add_join(
685
+ :baz => {
686
+ :type => 'inner',
687
+ :table => 'baz',
688
+ :condition => 'baz.baz_id = foo.baz_id'
689
+ }
690
+ )
691
+ expect(stmt.as_sql).to be == "SELECT foo FROM baz USE INDEX (index_hint) INNER JOIN baz ON baz.baz_id = foo.baz_id" # 'USE INDEX with JOIN'
692
+ end
693
+
694
+ it do
695
+ stmt = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ } )
696
+ stmt.add_select(:foo => 'foo')
697
+ stmt.add_index_hint('baz' => { :type => 'USE', :list => ['index_hint']})
698
+ stmt.add_join(
699
+ :baz => {
700
+ :type => 'inner',
701
+ :table => 'baz',
702
+ :alias => 'b1',
703
+ :condition => 'baz.baz_id = b1.baz_id AND b1.quux_id = 1'
704
+ },
705
+ )
706
+ stmt.add_join(
707
+ :baz => {
708
+ :type => 'left',
709
+ :table => 'baz',
710
+ :alias => 'b2',
711
+ :condition => 'baz.baz_id = b2.baz_id AND b2.quux_id = 2'
712
+ },
713
+ )
714
+ expect(stmt.as_sql).to be == "SELECT foo FROM baz USE INDEX (index_hint) INNER JOIN baz b1 ON baz.baz_id = b1.baz_id AND b1.quux_id = 1 LEFT JOIN baz b2 ON baz.baz_id = b2.baz_id AND b2.quux_id = 2" # 'USE INDEX with JOINs'
715
+ end
716
+ end
717
+ end
718
+
719
+ context 'select + from' do
720
+ it 'quote_char: "`", name_sep: "."' do
721
+ stmt = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
722
+ stmt.add_select(:foo => 'foo')
723
+ stmt.add_from(%w(baz))
724
+ expect(stmt.as_sql).to be == "SELECT `foo`\nFROM `baz`"
725
+ end
726
+
727
+ it 'quote_char: "", name_sep: ".", new_line: " "' do
728
+ stmt = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ } )
729
+ stmt.add_select(:foo => 'foo')
730
+ stmt.add_from(%w(baz))
731
+ expect(stmt.as_sql).to be == "SELECT foo FROM baz"
732
+ end
733
+ end
734
+
735
+ context 'join_with_using' do
736
+ it 'quote_char: "`", name_sep: "."' do
737
+ sql = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
738
+ sql.add_join(
739
+ :foo => {
740
+ :type => 'inner',
741
+ :table => 'baz',
742
+ :condition => %w/ hoge_id fuga_id /,
743
+ },
744
+ )
745
+ expect(sql.as_sql).to be == "FROM `foo` INNER JOIN `baz` USING (`hoge_id`, `fuga_id`)"
746
+ end
747
+
748
+ it 'quote_char: "", name_sep: ".", new_line: " "' do
749
+ sql = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ } )
750
+ sql.add_join(
751
+ :foo => {
752
+ :type => 'inner',
753
+ :table => 'baz',
754
+ :condition => %w/ hoge_id fuga_id /,
755
+ },
756
+ )
757
+ expect(sql.as_sql).to be == "FROM foo INNER JOIN baz USING (hoge_id, fuga_id)"
758
+ end
759
+ end
760
+
761
+ context 'add_where_raw' do
762
+ it 'quote_char: "`", name_sep: "."' do
763
+ sql = ns( :quote_char => %q{`}, :name_sep => %q{.}, )
764
+ sql.add_select( :foo => 'foo' )
765
+ sql.add_from( 'baz' )
766
+ sql.add_where_raw( 'MATCH(foo) AGAINST (?)' => 'hoge' )
767
+
768
+ expect(sql.as_sql).to be == "SELECT `foo`\nFROM `baz`\nWHERE (MATCH(foo) AGAINST (?))"
769
+ expect(sql.bind[0]).to be == 'hoge'
770
+ end
771
+
772
+ it 'quote_char: "", name_sep: ".", new_line: " "' do
773
+ sql = ns( :quote_char => %q{}, :name_sep => %q{.}, :new_line => %q{ } )
774
+ sql.add_select( :foo => 'foo' )
775
+ sql.add_from( 'baz' )
776
+ sql.add_where_raw( 'MATCH(foo) AGAINST (?)' => 'hoge' )
777
+
778
+ expect(sql.as_sql).to be == "SELECT foo FROM baz WHERE (MATCH(foo) AGAINST (?))"
779
+ expect(sql.bind[0]).to be == 'hoge'
780
+ end
781
+
782
+ it 'multi values' do
783
+ sql = ns( :quote_char => %q{}, :name_sep => %q{.} )
784
+ sql.add_select( :foo => 'foo' )
785
+ sql.add_from( 'baz' )
786
+ sql.add_where_raw( 'foo = IF(bar = ?, ?, ?)' => ['hoge', 'fuga', 'piyo'] )
787
+
788
+ expect(sql.as_sql).to be == "SELECT foo\nFROM baz\nWHERE (foo = IF(bar = ?, ?, ?))"
789
+ expect(sql.bind[0]).to be == 'hoge'
790
+ expect(sql.bind[1]).to be == 'fuga'
791
+ expect(sql.bind[2]).to be == 'piyo'
792
+ end
793
+
794
+ it 'without value' do
795
+ sql = ns( :quote_char => %q{}, :name_sep => %q{.} )
796
+ sql.add_select( :foo => 'foo' )
797
+ sql.add_from( 'baz' )
798
+ sql.add_where_raw( 'foo IS NOT NULL' )
799
+
800
+ expect(sql.as_sql).to be == "SELECT foo\nFROM baz\nWHERE (foo IS NOT NULL)"
801
+ expect(sql.bind.size).to be == 0
802
+ end
803
+ end
804
+ end
805
+ end