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,294 @@
1
+ require_relative '../spec_helper'
2
+ require 'sql/maker/select_set'
3
+ require 'sql/maker/select'
4
+ require 'sql/maker/helper'
5
+
6
+ describe SQL::Maker::SelectSet do
7
+ include SQL::Maker::Helper
8
+
9
+ def ns
10
+ SQL::Maker::Select.new( :quote_char => '', :name_sep => '.', :new_line => ' ' )
11
+ end
12
+
13
+ context 'basic' do
14
+ let(:s1) do
15
+ ns()
16
+ .add_from( 'table1' )
17
+ .add_select( 'id' )
18
+ .add_where( :foo => 100 )
19
+ end
20
+
21
+ let(:s2) do
22
+ ns()
23
+ .add_from( 'table2' )
24
+ .add_select( 'id' )
25
+ .add_where( :bar => 200 )
26
+ end
27
+
28
+ let(:s3) do
29
+ ns()
30
+ .add_from( 'table3' )
31
+ .add_select( 'id' )
32
+ .add_where( :baz => 300 )
33
+ end
34
+
35
+ it 'error' do
36
+ expect{ sql_union( s1, s2 ) }.not_to raise_error
37
+ expect { SQL::Maker::SelectSet.sql_union( s1, s2 ) }.not_to raise_error
38
+ expect { SQL::Maker::SelectSet.sql_union( s1 ) }.not_to raise_error
39
+ end
40
+
41
+ it 'sql_union' do
42
+ set = sql_union( s1, s2 )
43
+ expect(set.as_sql).to be == %q{SELECT id FROM table1 WHERE (foo = ?) UNION SELECT id FROM table2 WHERE (bar = ?)}
44
+ expect(set.bind.join(', ')).to be == '100, 200'
45
+
46
+ set = sql_union( set, s3 )
47
+ expect(set.as_sql).to be == %q{SELECT id FROM table1 WHERE (foo = ?) UNION SELECT id FROM table2 WHERE (bar = ?) UNION SELECT id FROM table3 WHERE (baz = ?)}
48
+ expect(set.bind.join(', ')).to be == '100, 200, 300'
49
+
50
+ set = sql_union( s3, sql_union( s1, s2 ) )
51
+ expect(set.as_sql).to be == %q{SELECT id FROM table3 WHERE (baz = ?) UNION SELECT id FROM table1 WHERE (foo = ?) UNION SELECT id FROM table2 WHERE (bar = ?)}
52
+ expect(set.bind.join(', ')).to be == '300, 100, 200'
53
+
54
+ set = sql_union_all( s1, s2 )
55
+ expect(set.as_sql).to be == %q{SELECT id FROM table1 WHERE (foo = ?) UNION ALL SELECT id FROM table2 WHERE (bar = ?)}
56
+ expect(set.bind.join(', ')).to be == '100, 200'
57
+
58
+ set.add_order_by( 'id' )
59
+ expect(set.as_sql).to be == %q{SELECT id FROM table1 WHERE (foo = ?) UNION ALL SELECT id FROM table2 WHERE (bar = ?) ORDER BY id}
60
+ expect(set.bind.join(', ')).to be == '100, 200'
61
+
62
+ set = sql_union( sql_union( s3, s1 ), s2 )
63
+ expect(set.as_sql).to be == %q{SELECT id FROM table3 WHERE (baz = ?) UNION SELECT id FROM table1 WHERE (foo = ?) UNION SELECT id FROM table2 WHERE (bar = ?)}
64
+ expect(set.bind.join(', ')).to be == '300, 100, 200'
65
+
66
+ set = sql_union( sql_union( s1, s2 ), sql_union( s2, s3) )
67
+ expect(set.as_sql).to be == %q{SELECT id FROM table1 WHERE (foo = ?) UNION SELECT id FROM table2 WHERE (bar = ?) UNION SELECT id FROM table2 WHERE (bar = ?) UNION SELECT id FROM table3 WHERE (baz = ?)}
68
+ expect(set.bind.join(', ')).to be == '100, 200, 200, 300'
69
+ end
70
+
71
+ it 'sql_intersect' do
72
+ set = sql_intersect( s1, s2 )
73
+ expect(set.as_sql).to be == %q{SELECT id FROM table1 WHERE (foo = ?) INTERSECT SELECT id FROM table2 WHERE (bar = ?)}
74
+ expect(set.bind.join(', ')).to be == '100, 200'
75
+
76
+ set = sql_intersect( set, s3)
77
+ expect(set.as_sql).to be == %q{SELECT id FROM table1 WHERE (foo = ?) INTERSECT SELECT id FROM table2 WHERE (bar = ?) INTERSECT SELECT id FROM table3 WHERE (baz = ?)}
78
+ expect(set.bind.join(', ')).to be == '100, 200, 300'
79
+
80
+ set = sql_intersect( s3, sql_intersect( s1, s2 ) )
81
+ expect(set.as_sql).to be == %q{SELECT id FROM table3 WHERE (baz = ?) INTERSECT SELECT id FROM table1 WHERE (foo = ?) INTERSECT SELECT id FROM table2 WHERE (bar = ?)}
82
+ expect(set.bind.join(', ')).to be == '300, 100, 200'
83
+
84
+ set = sql_intersect_all( s1, s2 )
85
+ expect(set.as_sql).to be == %q{SELECT id FROM table1 WHERE (foo = ?) INTERSECT ALL SELECT id FROM table2 WHERE (bar = ?)}
86
+ expect(set.bind.join(', ')).to be == '100, 200'
87
+
88
+ set.add_order_by( 'id' )
89
+ expect(set.as_sql).to be == %q{SELECT id FROM table1 WHERE (foo = ?) INTERSECT ALL SELECT id FROM table2 WHERE (bar = ?) ORDER BY id}
90
+ expect(set.bind.join(', ')).to be == '100, 200'
91
+ end
92
+
93
+ it 'sql_except' do
94
+ set = sql_except( s1, s2 )
95
+ expect(set.as_sql).to be == %q{SELECT id FROM table1 WHERE (foo = ?) EXCEPT SELECT id FROM table2 WHERE (bar = ?)}
96
+ expect(set.bind.join(', ')).to be == '100, 200'
97
+
98
+ set = sql_except( set, s3 )
99
+ expect(set.as_sql).to be == %q{SELECT id FROM table1 WHERE (foo = ?) EXCEPT SELECT id FROM table2 WHERE (bar = ?) EXCEPT SELECT id FROM table3 WHERE (baz = ?)}
100
+ expect(set.bind.join(', ')).to be == '100, 200, 300'
101
+
102
+ set = sql_except( s3, sql_except( s1, s2 ) )
103
+ expect(set.as_sql).to be == %q{SELECT id FROM table3 WHERE (baz = ?) EXCEPT SELECT id FROM table1 WHERE (foo = ?) EXCEPT SELECT id FROM table2 WHERE (bar = ?)}
104
+ expect(set.bind.join(', ')).to be == '300, 100, 200'
105
+
106
+ set = sql_except_all( s1, s2 )
107
+ expect(set.as_sql).to be == %q{SELECT id FROM table1 WHERE (foo = ?) EXCEPT ALL SELECT id FROM table2 WHERE (bar = ?)}
108
+ expect(set.bind.join(', ')).to be == '100, 200'
109
+
110
+ set.add_order_by( 'id' )
111
+ expect(set.as_sql).to be == %q{SELECT id FROM table1 WHERE (foo = ?) EXCEPT ALL SELECT id FROM table2 WHERE (bar = ?) ORDER BY id}
112
+ expect(set.bind.join(', ')).to be == '100, 200'
113
+ end
114
+
115
+ it 'multiple' do
116
+ set = sql_intersect( sql_except(s1, s2), s3 )
117
+ expect(set.as_sql).to be == %q{SELECT id FROM table1 WHERE (foo = ?) EXCEPT SELECT id FROM table2 WHERE (bar = ?) INTERSECT SELECT id FROM table3 WHERE (baz = ?)}
118
+ expect(set.bind.join(', ')).to be == '100, 200, 300'
119
+
120
+ set = sql_intersect_all( sql_except( s1, s2 ), s3 )
121
+ expect(set.as_sql).to be == %q{SELECT id FROM table1 WHERE (foo = ?) EXCEPT SELECT id FROM table2 WHERE (bar = ?) INTERSECT ALL SELECT id FROM table3 WHERE (baz = ?)}
122
+ expect(set.bind.join(', ')).to be == '100, 200, 300'
123
+
124
+ set = sql_union( sql_except( s1, s2), s3 )
125
+ expect(set.as_sql).to be == %q{SELECT id FROM table1 WHERE (foo = ?) EXCEPT SELECT id FROM table2 WHERE (bar = ?) UNION SELECT id FROM table3 WHERE (baz = ?)}
126
+ expect(set.bind.join(', ')).to be == '100, 200, 300'
127
+
128
+ set = sql_union( sql_except_all( s1, s2 ), s3 )
129
+ expect(set.as_sql).to be == %q{SELECT id FROM table1 WHERE (foo = ?) EXCEPT ALL SELECT id FROM table2 WHERE (bar = ?) UNION SELECT id FROM table3 WHERE (baz = ?)}
130
+ expect(set.bind.join(', ')).to be == '100, 200, 300'
131
+ end
132
+ end
133
+
134
+ def check_sql(arg)
135
+ lines = arg.split("\n")
136
+ sql = ''
137
+ lines.each do |line|
138
+ line.gsub!(/^\s+/, '')
139
+ line.gsub!(/^WHERE/, ' WHERE')
140
+ line.gsub!(/^FROM/, ' FROM')
141
+ line.gsub!(/^INNER/, ' INNER')
142
+ line.gsub!(/^EXCEPT/, ' EXCEPT')
143
+ line.gsub!(/^UNION/, ' UNION')
144
+ sql += line
145
+ end
146
+ sql
147
+ end
148
+
149
+ context 'complex' do
150
+ let(:s1) do
151
+ ns.add_from( 'member' )
152
+ .add_select('id')
153
+ .add_select('created_on')
154
+ .add_where( :is_deleted => 'f' )
155
+ end
156
+
157
+ let(:not_in) do
158
+ ns.add_from('group_member')
159
+ .add_select('member_id')
160
+ .add_where( 'is_beginner' => 'f' )
161
+ end
162
+
163
+ let(:s2) do
164
+ ns.add_from( s1, 'm1' )
165
+ .add_select('m1.id')
166
+ .add_select('m1.created_on')
167
+ .add_where( 'm1.id' => { 'NOT IN' => not_in })
168
+ end
169
+
170
+ let(:s3) do
171
+ ns.add_select('mi.id')
172
+ .add_select( 'false', 'is_group' )
173
+ .add_select('mi.created_on')
174
+ .add_join( [s2, 'm2'] => { :table => 'member_index', :alias => 'mi', :type => 'inner', :condition => 'mi.id = m2.id' } )
175
+ .add_where( 'mi.lang' => 'ja' )
176
+ end
177
+
178
+ it do
179
+ expect(s1.as_sql).to be == "SELECT id, created_on FROM member WHERE (is_deleted = ?)"
180
+
181
+ expect(not_in.as_sql).to be == "SELECT member_id FROM group_member WHERE (is_beginner = ?)"
182
+
183
+ expect(s2.as_sql).to be == check_sql(<<SQL)
184
+ SELECT m1.id, m1.created_on
185
+ FROM (SELECT id, created_on FROM member WHERE (is_deleted = ?)) m1
186
+ WHERE (m1.id NOT IN (SELECT member_id FROM group_member WHERE (is_beginner = ?)))
187
+ SQL
188
+
189
+ expect(s3.as_sql).to be == check_sql(<<SQL)
190
+ SELECT mi.id, false AS is_group, mi.created_on
191
+ FROM (
192
+ SELECT m1.id, m1.created_on FROM (
193
+ SELECT id, created_on FROM member WHERE (is_deleted = ?)
194
+ ) m1 WHERE (m1.id NOT IN (SELECT member_id FROM group_member WHERE (is_beginner = ?)))
195
+ ) m2 INNER JOIN member_index mi ON mi.id = m2.id WHERE (mi.lang = ?)
196
+ SQL
197
+ expect(s3.bind.join(', ')).to be == 'f, f, ja'
198
+
199
+ s4 = ns.add_join(
200
+ ['group', 'g1'] => {
201
+ :table => 'group_member', :alias => 'gm1',
202
+ :type => 'inner', :condition => 'gm1.member_id = g1.id'
203
+ }
204
+ ).add_join(
205
+ ['group', 'g1'] => {
206
+ :table => 'member', :alias => 'm3',
207
+ :type => 'inner', :condition => 'gm1.member_id = m3.id'
208
+ }
209
+ ).add_select( 'g1.id' )
210
+ .add_where( 'g1.type' => 'hoge' )
211
+
212
+ expect(s4.as_sql).to be == "SELECT g1.id FROM group g1 INNER JOIN group_member gm1 ON gm1.member_id = g1.id INNER JOIN member m3 ON gm1.member_id = m3.id WHERE (g1.type = ?)"
213
+
214
+ not_in2 = ns.add_select('id')
215
+ .add_from('member')
216
+ .add_where( 'is_monger' => 't' )
217
+
218
+ s5 = ns.add_select( 'g2.id' ).add_join(
219
+ ['group', 'g2'] => {
220
+ :table => 'group_member', :alias => 'gm2',
221
+ :type => 'inner', :condition => 'gm2.member_id = g2.id'
222
+ }
223
+ ).add_where( 'gm2.member_id' => { 'NOT IN' => not_in2 })
224
+ .add_where( 'g2.is_deleted' => 'f' )
225
+
226
+ expect(s5.as_sql).to be == "SELECT g2.id FROM group g2 INNER JOIN group_member gm2 ON gm2.member_id = g2.id WHERE (gm2.member_id NOT IN (SELECT id FROM member WHERE (is_monger = ?))) AND (g2.is_deleted = ?)"
227
+
228
+ set = sql_except( s4, s5 )
229
+
230
+ s6 = ns.add_join(
231
+ [set, 'g'] => {
232
+ :table => 'group_index', :alias => 'gi',
233
+ :type => 'inner', :condition => 'gi.id = g.id'
234
+ }
235
+ ).add_select( 'g.id' )
236
+ .add_select( 'true', 'is_group' )
237
+ .add_select( 'gsi.created_on' )
238
+ .add_where( 'gi.lang' => 'ja' )
239
+
240
+ expect(s6.as_sql).to be == check_sql(<<SQL)
241
+ SELECT g.id, true AS is_group, gsi.created_on
242
+ FROM (
243
+ SELECT g1.id FROM group g1
244
+ INNER JOIN group_member gm1 ON gm1.member_id = g1.id
245
+ INNER JOIN member m3 ON gm1.member_id = m3.id
246
+ WHERE (g1.type = ?)
247
+ EXCEPT
248
+ SELECT g2.id FROM group g2
249
+ INNER JOIN group_member gm2 ON gm2.member_id = g2.id
250
+ WHERE (gm2.member_id NOT IN (
251
+ SELECT id FROM member WHERE (is_monger = ?)
252
+ )) AND (g2.is_deleted = ?)
253
+ ) g INNER JOIN group_index gi ON gi.id = g.id WHERE (gi.lang = ?)
254
+ SQL
255
+
256
+ expect(s6.bind.join(', ')).to be == 'hoge, t, f, ja'
257
+
258
+ set = sql_union( s3, s6 )
259
+
260
+ s7 = ns.add_select( 'id' )
261
+ .add_select( 'is_group' )
262
+ .add_from( set, 'list_table' )
263
+ .add_order_by( 'created_on' )
264
+
265
+
266
+ expect(s7.as_sql).to be == check_sql(<<SQL)
267
+ SELECT id, is_group FROM (
268
+ SELECT mi.id, false AS is_group, mi.created_on
269
+ FROM (
270
+ SELECT m1.id, m1.created_on FROM (
271
+ SELECT id, created_on FROM member WHERE (is_deleted = ?)
272
+ ) m1 WHERE (m1.id NOT IN (SELECT member_id FROM group_member WHERE (is_beginner = ?)))
273
+ ) m2 INNER JOIN member_index mi ON mi.id = m2.id WHERE (mi.lang = ?)
274
+ UNION
275
+ SELECT g.id, true AS is_group, gsi.created_on
276
+ FROM (
277
+ SELECT g1.id FROM group g1
278
+ INNER JOIN group_member gm1 ON gm1.member_id = g1.id
279
+ INNER JOIN member m3 ON gm1.member_id = m3.id
280
+ WHERE (g1.type = ?)
281
+ EXCEPT
282
+ SELECT g2.id FROM group g2
283
+ INNER JOIN group_member gm2 ON gm2.member_id = g2.id
284
+ WHERE (gm2.member_id NOT IN (
285
+ SELECT id FROM member WHERE (is_monger = ?)
286
+ )) AND (g2.is_deleted = ?)
287
+ ) g INNER JOIN group_index gi ON gi.id = g.id WHERE (gi.lang = ?)
288
+ ) list_table ORDER BY created_on
289
+ SQL
290
+
291
+ expect(s7.bind.join(', ')).to be == 'f, f, ja, hoge, t, f, ja'
292
+ end
293
+ end
294
+ end
@@ -0,0 +1,470 @@
1
+ require_relative '../spec_helper'
2
+ require 'sql/maker'
3
+ require 'sql/maker/helper'
4
+
5
+ describe 'SQL::Maker#select' do
6
+ include SQL::Maker::Helper
7
+
8
+ context 'driver: sqlite' do
9
+ builder = SQL::Maker.new(:driver => 'sqlite')
10
+
11
+ it 'columns and tables' do
12
+ sql, bind = builder.select( 'foo', [ '*' ] )
13
+ expect(sql).to be == %Q{SELECT *\nFROM "foo"}
14
+ expect(bind.join(',')).to be == ''
15
+ end
16
+
17
+ it 'scalar ref columns and tables' do
18
+ sql, bind = builder.select( 'foo', [ sql_raw('bar'), sql_raw('baz') ] )
19
+ expect(sql).to be == %Q{SELECT bar, baz\nFROM "foo"}
20
+ expect(bind.join(',')).to be == ''
21
+ end
22
+
23
+ it 'columns with alias column and tables' do
24
+ sql, bind = builder.select( 'foo', [ 'foo', {:bar => 'barbar'} ] )
25
+ expect(sql).to be == %Q{SELECT "foo", "bar" AS "barbar"\nFROM "foo"}
26
+ expect(bind.join(',')).to be == ''
27
+ end
28
+
29
+ it 'columns and tables, where cause (hash ref)' do
30
+ sql, bind = builder.select( 'foo', [ 'foo', 'bar' ], { :bar => 'baz', :john => 'man' } )
31
+ expect(sql).to be == %Q{SELECT "foo", "bar"\nFROM "foo"\nWHERE ("bar" = ?) AND ("john" = ?)}
32
+ expect(bind.join(',')).to be == 'baz,man'
33
+ end
34
+
35
+ it 'columns and tables, where cause (array ref)' do
36
+ sql, bind = builder.select( 'foo', [ 'foo', 'bar' ], { :bar => 'baz', :john => 'man' } )
37
+ expect(sql).to be == %Q{SELECT "foo", "bar"\nFROM "foo"\nWHERE ("bar" = ?) AND ("john" = ?)}
38
+ expect(bind.join(',')).to be == 'baz,man'
39
+ end
40
+
41
+ it 'columns and tables, where cause (condition)' do
42
+ cond = builder.new_condition
43
+ cond.add(:bar => 'baz')
44
+ cond.add(:john => 'man')
45
+ sql, bind = builder.select( 'foo', [ 'foo', 'bar' ], cond )
46
+ expect(sql).to be == %Q{SELECT "foo", "bar"\nFROM "foo"\nWHERE ("bar" = ?) AND ("john" = ?)}
47
+ expect(bind.join(',')).to be == 'baz,man'
48
+ end
49
+
50
+ it 'columns and tables, where cause (hash ref), order by' do
51
+ sql, bind = builder.select( 'foo', ['foo', 'bar'], {:bar => 'baz', :john => 'man'}, {:order_by => sql_raw('yo')})
52
+ expect(sql).to be == %Q{SELECT "foo", "bar"\nFROM "foo"\nWHERE ("bar" = ?) AND ("john" = ?)\nORDER BY yo}
53
+ expect(bind.join(',')).to be == 'baz,man'
54
+ end
55
+
56
+ it 'columns and table, where cause (array ref), order by' do
57
+ sql, bind = builder.select( 'foo', ['foo', 'bar'], {:bar => 'baz', :john => 'man'}, {:order_by => 'yo'})
58
+ expect(sql).to be == %Q{SELECT "foo", "bar"\nFROM "foo"\nWHERE ("bar" = ?) AND ("john" = ?)\nORDER BY "yo"}
59
+ expect(bind.join(',')).to be == 'baz,man'
60
+ end
61
+
62
+ it 'columns and table, where cause (condition), order by' do
63
+ cond = builder.new_condition
64
+ cond.add(:bar => 'baz')
65
+ cond.add(:john => 'man')
66
+ sql, bind = builder.select( 'foo', ['foo', 'bar'], cond, {:order_by => 'yo'})
67
+ expect(sql).to be == %Q{SELECT "foo", "bar"\nFROM "foo"\nWHERE ("bar" = ?) AND ("john" = ?)\nORDER BY "yo"}
68
+ expect(bind.join(',')).to be == 'baz,man'
69
+ end
70
+
71
+ it 'columns and table, where cause (array ref), order by, limit, offset' do
72
+ sql, bind = builder.select( 'foo', ['foo', 'bar'], {:bar => 'baz', :john => 'man'}, {:order_by => 'yo', :limit => 1, :offset => 3})
73
+ expect(sql).to be == %Q{SELECT "foo", "bar"\nFROM "foo"\nWHERE ("bar" = ?) AND ("john" = ?)\nORDER BY "yo"\nLIMIT 1 OFFSET 3}
74
+ expect(bind.join(',')).to be == 'baz,man'
75
+ end
76
+
77
+ it 'modify prefix' do
78
+ sql, bind = builder.select( 'foo', ['foo', 'bar'], {}, { :prefix => 'SELECT SQL_CALC_FOUND_ROWS '} )
79
+ expect(sql).to be == %Q{SELECT SQL_CALC_FOUND_ROWS "foo", "bar"\nFROM "foo"}
80
+ expect(bind.join(',')).to be == ''
81
+ end
82
+
83
+ context 'order_by' do
84
+ it 'scalar' do
85
+ sql, bind = builder.select('foo', ['*'] , {}, {:order_by => sql_raw('yo')})
86
+ expect(sql).to be == %Q{SELECT *\nFROM "foo"\nORDER BY yo}
87
+ expect(bind.join(',')).to be == ''
88
+ end
89
+
90
+ it 'hash ref' do
91
+ sql, bind = builder.select('foo', ['*'], {}, {:order_by => {'yo' => 'DESC'}})
92
+ expect(sql).to be == %Q{SELECT *\nFROM "foo"\nORDER BY "yo" DESC}
93
+ expect(bind.join(',')).to be == ''
94
+ end
95
+
96
+ it 'array ref' do
97
+ sql, bind = builder.select('foo', ['*'], {}, {:order_by => [sql_raw('yo'), sql_raw('ya')]})
98
+ expect(sql).to be == %Q{SELECT *\nFROM "foo"\nORDER BY yo, ya}
99
+ expect(bind.join(',')).to be == ''
100
+ end
101
+
102
+ it 'mixed' do
103
+ sql, bind = builder.select('foo', ['*'], {}, {:order_by => [{'yo' => 'DESC'}, sql_raw('ya')]})
104
+ expect(sql).to be == %Q{SELECT *\nFROM "foo"\nORDER BY "yo" DESC, ya}
105
+ expect(bind.join(',')).to be == ''
106
+ end
107
+ end
108
+
109
+ context 'group_by' do
110
+ it 'scalar' do
111
+ sql, bind = builder.select('foo', ['*'], {}, {:group_by => sql_raw('yo')})
112
+ expect(sql).to be == %Q{SELECT *\nFROM "foo"\nGROUP BY yo}
113
+ expect(bind.join(',')).to be == ''
114
+ end
115
+
116
+ it 'hash ref' do
117
+ sql, bind = builder.select('foo', ['*'], {}, {:group_by => {'yo' => 'DESC'}})
118
+ expect(sql).to be == %Q{SELECT *\nFROM "foo"\nGROUP BY "yo" DESC}
119
+ expect(bind.join(',')).to be == ''
120
+ end
121
+
122
+ it 'array ref' do
123
+ sql, bind = builder.select('foo', ['*'], {}, {:group_by => [sql_raw('yo'), sql_raw('ya')]})
124
+ expect(sql).to be == %Q{SELECT *\nFROM "foo"\nGROUP BY yo, ya}
125
+ expect(bind.join(',')).to be == ''
126
+ end
127
+
128
+ it 'mixed' do
129
+ sql, bind = builder.select('foo', ['*'], {}, {:group_by => [{'yo' => 'DESC'}, sql_raw('ya')]})
130
+ expect(sql).to be == %Q{SELECT *\nFROM "foo"\nGROUP BY "yo" DESC, ya}
131
+ expect(bind.join(',')).to be == ''
132
+ end
133
+ end
134
+
135
+ context 'from' do
136
+ it 'multi from' do
137
+ sql, bind = builder.select( %w/foo bar/, ['*'], {} )
138
+ expect(sql).to be == %Q{SELECT *\nFROM "foo", "bar"}
139
+ expect(bind.join(',')).to be == ''
140
+ end
141
+
142
+ it 'multi from with alias' do
143
+ sql, bind = builder.select( [ { :foo => 'f' }, { :bar => 'b' } ], ['*'], {} )
144
+ expect(sql).to be == %Q{SELECT *\nFROM "foo" "f", "bar" "b"}
145
+ expect(bind.join(',')).to be == ''
146
+ end
147
+ end
148
+
149
+ it 'join' do
150
+ sql, bind = builder.select(nil, ['*'], {}, {:joins => {
151
+ :foo => {
152
+ :type => 'LEFT OUTER',
153
+ :table => 'bar',
154
+ :condition => 'foo.bar_id = bar.id',
155
+ }
156
+ }})
157
+ expect(sql).to be == %Q{SELECT *\nFROM "foo" LEFT OUTER JOIN "bar" ON foo.bar_id = bar.id}
158
+ expect(bind.join(',')).to be == ''
159
+ end
160
+ end
161
+
162
+ context 'driver: mysql' do
163
+ builder = SQL::Maker.new(:driver => 'mysql')
164
+
165
+ it 'columns and tables' do
166
+ sql, bind = builder.select( 'foo', [ '*' ])
167
+ expect(sql).to be == %Q{SELECT *\nFROM `foo`}
168
+ expect(bind.join(',')).to be == ''
169
+ end
170
+
171
+ it 'columns with alias column and tables' do
172
+ sql, bind = builder.select( 'foo', [ 'foo', {:bar => 'barbar'} ])
173
+ expect(sql).to be == %Q{SELECT `foo`, `bar` AS `barbar`\nFROM `foo`}
174
+ expect(bind.join(',')).to be == ''
175
+ end
176
+
177
+ it 'scalar ref columns and tables' do
178
+ sql, bind = builder.select( 'foo', [ sql_raw('bar'), sql_raw('baz') ])
179
+ expect(sql).to be == %Q{SELECT bar, baz\nFROM `foo`}
180
+ expect(bind.join(',')).to be == ''
181
+ end
182
+
183
+ it 'columns and tables, where cause (hash ref)' do
184
+ sql, bind = builder.select( 'foo', [ 'foo', 'bar' ], { :bar => 'baz', :john => 'man' } )
185
+ expect(sql).to be == %Q{SELECT `foo`, `bar`\nFROM `foo`\nWHERE (`bar` = ?) AND (`john` = ?)}
186
+ expect(bind.join(',')).to be == 'baz,man'
187
+ end
188
+
189
+ it 'columns and tables, where cause (array ref)' do
190
+ sql, bind = builder.select( 'foo', [ 'foo', 'bar' ], { :bar => 'baz', :john => 'man' } )
191
+ expect(sql).to be == %Q{SELECT `foo`, `bar`\nFROM `foo`\nWHERE (`bar` = ?) AND (`john` = ?)}
192
+ expect(bind.join(',')).to be == 'baz,man'
193
+ end
194
+
195
+ it 'columns and tables, where cause (condition)' do
196
+ cond = builder.new_condition
197
+ cond.add(:bar => 'baz')
198
+ cond.add(:john => 'man')
199
+ sql, bind = builder.select( 'foo', [ 'foo', 'bar' ], cond )
200
+ expect(sql).to be == %Q{SELECT `foo`, `bar`\nFROM `foo`\nWHERE (`bar` = ?) AND (`john` = ?)}
201
+ expect(bind.join(',')).to be == 'baz,man'
202
+ end
203
+
204
+ it 'columns and tables, where cause (hash ref), order by' do
205
+ sql, bind = builder.select( 'foo', ['foo', 'bar'], {:bar => 'baz', :john => 'man'}, {:order_by => 'yo'})
206
+ expect(sql).to be == %Q{SELECT `foo`, `bar`\nFROM `foo`\nWHERE (`bar` = ?) AND (`john` = ?)\nORDER BY `yo`}
207
+ expect(bind.join(',')).to be == 'baz,man'
208
+ end
209
+
210
+ it 'columns and table, where cause (array ref), order by' do
211
+ sql, bind = builder.select( 'foo', ['foo', 'bar'], {:bar => 'baz', :john => 'man'}, {:order_by => 'yo'})
212
+ expect(sql).to be == %Q{SELECT `foo`, `bar`\nFROM `foo`\nWHERE (`bar` = ?) AND (`john` = ?)\nORDER BY `yo`}
213
+ expect(bind.join(',')).to be == 'baz,man'
214
+ end
215
+
216
+ it 'columns and table, where cause (condition), order by' do
217
+ cond = builder.new_condition
218
+ cond.add(:bar => 'baz')
219
+ cond.add(:john => 'man')
220
+ sql, bind = builder.select( 'foo', ['foo', 'bar'], cond, {:order_by => 'yo'})
221
+ expect(sql).to be == %Q{SELECT `foo`, `bar`\nFROM `foo`\nWHERE (`bar` = ?) AND (`john` = ?)\nORDER BY `yo`}
222
+ expect(bind.join(',')).to be == 'baz,man'
223
+ end
224
+
225
+ it 'columns and table, where cause (array ref), order by, limit, offset' do
226
+ sql, bind = builder.select( 'foo', ['foo', 'bar'], {:bar => 'baz', :john => 'man'}, {:order_by => sql_raw('yo'), :limit => 1, :offset => 3})
227
+ expect(sql).to be == %Q{SELECT `foo`, `bar`\nFROM `foo`\nWHERE (`bar` = ?) AND (`john` = ?)\nORDER BY yo\nLIMIT 1 OFFSET 3}
228
+ expect(bind.join(',')).to be == 'baz,man'
229
+ end
230
+
231
+ it 'modify prefix' do
232
+ sql, bind = builder.select( 'foo', ['foo', 'bar'], {}, { :prefix => 'SELECT SQL_CALC_FOUND_ROWS '} )
233
+ expect(sql).to be == %Q{SELECT SQL_CALC_FOUND_ROWS `foo`, `bar`\nFROM `foo`}
234
+ expect(bind.join(',')).to be == ''
235
+ end
236
+
237
+ context 'order_by' do
238
+ it 'scalar' do
239
+ sql, bind = builder.select( 'foo', ['*'], {}, {:order_by => sql_raw('yo')})
240
+ expect(sql).to be == %Q{SELECT *\nFROM `foo`\nORDER BY yo}
241
+ expect(bind.join(',')).to be == ''
242
+ end
243
+
244
+ it 'hash ref' do
245
+ sql, bind = builder.select( 'foo', ['*'], {}, {:order_by => {'yo' => 'DESC'}})
246
+ expect(sql).to be == %Q{SELECT *\nFROM `foo`\nORDER BY `yo` DESC}
247
+ expect(bind.join(',')).to be == ''
248
+ end
249
+
250
+ it 'array ref' do
251
+ sql, bind = builder.select( 'foo', ['*'], {}, {:order_by => [sql_raw('yo'), sql_raw('ya')]})
252
+ expect(sql).to be == %Q{SELECT *\nFROM `foo`\nORDER BY yo, ya}
253
+ expect(bind.join(',')).to be == ''
254
+ end
255
+
256
+ it 'mixed' do
257
+ sql, bind = builder.select( 'foo', ['*'], {}, {:order_by => [{'yo' => 'DESC'}, sql_raw('ya')]})
258
+ expect(sql).to be == %Q{SELECT *\nFROM `foo`\nORDER BY `yo` DESC, ya}
259
+ expect(bind.join(',')).to be == ''
260
+ end
261
+ end
262
+
263
+ context 'group_by' do
264
+ it 'scalar' do
265
+ sql, bind = builder.select( 'foo', ['*'], {}, {:group_by => sql_raw('yo')})
266
+ expect(sql).to be == %Q{SELECT *\nFROM `foo`\nGROUP BY yo}
267
+ expect(bind.join(',')).to be == ''
268
+ end
269
+
270
+ it 'hash ref' do
271
+ sql, bind = builder.select( 'foo', ['*'], {}, {:group_by => {'yo' => 'DESC'}})
272
+ expect(sql).to be == %Q{SELECT *\nFROM `foo`\nGROUP BY `yo` DESC}
273
+ expect(bind.join(',')).to be == ''
274
+ end
275
+
276
+ it 'array ref' do
277
+ sql, bind = builder.select( 'foo', ['*'], {}, {:group_by => [sql_raw('yo'), sql_raw('ya')]})
278
+ expect(sql).to be == %Q{SELECT *\nFROM `foo`\nGROUP BY yo, ya}
279
+ expect(bind.join(',')).to be == ''
280
+ end
281
+
282
+ it 'mixed' do
283
+ sql, bind = builder.select( 'foo', ['*'], {}, {:group_by => [{'yo' => 'DESC'}, sql_raw('ya')]})
284
+ expect(sql).to be == %Q{SELECT *\nFROM `foo`\nGROUP BY `yo` DESC, ya}
285
+ expect(bind.join(',')).to be == ''
286
+ end
287
+ end
288
+
289
+ context 'from' do
290
+ it 'multi from' do
291
+ sql, bind = builder.select( %w/foo bar/, ['*'], {})
292
+ expect(sql).to be == %Q{SELECT *\nFROM `foo`, `bar`}
293
+ expect(bind.join(',')).to be == ''
294
+ end
295
+
296
+ it 'multi from with alias' do
297
+ sql, bind = builder.select( [{ :foo => 'f' }, { :bar => 'b' }], ['*'], {})
298
+ expect(sql).to be == %Q{SELECT *\nFROM `foo` `f`, `bar` `b`}
299
+ expect(bind.join(',')).to be == ''
300
+ end
301
+ end
302
+
303
+ it 'join' do
304
+ sql, bind = builder.select( nil, ['*'], {}, {:joins => {
305
+ :foo => {
306
+ :type => 'LEFT OUTER',
307
+ :table => 'bar',
308
+ :condition => 'foo.bar_id = bar.id',
309
+ }
310
+ }})
311
+ expect(sql).to be == %Q{SELECT *\nFROM `foo` LEFT OUTER JOIN `bar` ON foo.bar_id = bar.id}
312
+ expect(bind.join(',')).to be == ''
313
+ end
314
+ end
315
+
316
+ context 'driver: mysql, quote_char: "", new_line: " "' do
317
+ builder = SQL::Maker.new(:driver => 'mysql', :quote_char => '', :new_line => ' ')
318
+
319
+ it 'columns and tables' do
320
+ sql, bind = builder.select( 'foo', [ '*' ] )
321
+ expect(sql).to be == %Q{SELECT * FROM foo}
322
+ expect(bind.join(',')).to be == ''
323
+ end
324
+
325
+ it 'columns and tables, where cause (hash ref)' do
326
+ sql, bind = builder.select( 'foo', [ 'foo', 'bar' ], { :bar => 'baz', :john => 'man' } )
327
+ expect(sql).to be == %Q{SELECT foo, bar FROM foo WHERE (bar = ?) AND (john = ?)}
328
+ expect(bind.join(',')).to be == 'baz,man'
329
+ end
330
+
331
+ it 'columns and tables, where cause (array ref)' do
332
+ sql, bind = builder.select( 'foo', [ 'foo', 'bar' ], { :bar => 'baz', :john => 'man' } )
333
+ expect(sql).to be == %Q{SELECT foo, bar FROM foo WHERE (bar = ?) AND (john = ?)}
334
+ expect(bind.join(',')).to be == 'baz,man'
335
+ end
336
+
337
+ it 'columns and tables, where cause (condition)' do
338
+ cond = builder.new_condition
339
+ cond.add(:bar => 'baz')
340
+ cond.add(:john => 'man')
341
+ sql, bind = builder.select( 'foo', [ 'foo', 'bar' ], cond )
342
+ expect(sql).to be == %Q{SELECT foo, bar FROM foo WHERE (bar = ?) AND (john = ?)}
343
+ expect(bind.join(',')).to be == 'baz,man'
344
+ end
345
+
346
+ it 'columns and tables, where cause (hash ref), order by' do
347
+ sql, bind = builder.select('foo', ['foo', 'bar'], {:bar => 'baz', :john => 'man'}, {:order_by => 'yo'})
348
+ expect(sql).to be == %Q{SELECT foo, bar FROM foo WHERE (bar = ?) AND (john = ?) ORDER BY yo}
349
+ expect(bind.join(',')).to be == 'baz,man'
350
+ end
351
+
352
+ # it 'columns and table, where cause (array ref), order by' do
353
+
354
+ it 'columns and table, where cause (condition), order by' do
355
+ cond = builder.new_condition
356
+ cond.add(:bar => 'baz')
357
+ cond.add(:john => 'man')
358
+ sql, bind = builder.select('foo', ['foo', 'bar'], cond, {:order_by => 'yo'})
359
+ expect(sql).to be == %Q{SELECT foo, bar FROM foo WHERE (bar = ?) AND (john = ?) ORDER BY yo}
360
+ expect(bind.join(',')).to be == 'baz,man'
361
+ end
362
+
363
+ it 'columns and table, where cause (array ref), order by, limit, offset' do
364
+ sql, bind = builder.select('foo', ['foo', 'bar'], {:bar => 'baz', :john => 'man'}, {:order_by => 'yo', :limit => 1, :offset => 3})
365
+ expect(sql).to be == %Q{SELECT foo, bar FROM foo WHERE (bar = ?) AND (john = ?) ORDER BY yo LIMIT 1 OFFSET 3}
366
+ expect(bind.join(',')).to be == 'baz,man'
367
+ end
368
+
369
+ it 'modify prefix' do
370
+ sql, bind = builder.select('foo', ['foo', 'bar'], {}, {:prefix => 'SELECT SQL_CALC_FOUND_ROWS '})
371
+ expect(sql).to be == %Q{SELECT SQL_CALC_FOUND_ROWS foo, bar FROM foo}
372
+ expect(bind.join(',')).to be == ''
373
+ end
374
+
375
+ context 'order_by' do
376
+ it 'scalar' do
377
+ sql, bind = builder.select('foo', ['*'], {}, {:order_by => 'yo'})
378
+ expect(sql).to be == %Q{SELECT * FROM foo ORDER BY yo}
379
+ expect(bind.join(',')).to be == ''
380
+ end
381
+
382
+ it 'hash ref' do
383
+ sql, bind = builder.select('foo', ['*'], {}, {:order_by => {'yo' => 'DESC'}})
384
+ expect(sql).to be == %Q{SELECT * FROM foo ORDER BY yo DESC}
385
+ expect(bind.join(',')).to be == ''
386
+ end
387
+
388
+ it 'array ref' do
389
+ sql, bind = builder.select('foo', ['*'], {}, {:order_by => ['yo', 'ya']})
390
+ expect(sql).to be == %Q{SELECT * FROM foo ORDER BY yo, ya}
391
+ expect(bind.join(',')).to be == ''
392
+ end
393
+
394
+ it 'mixed' do
395
+ sql, bind = builder.select('foo', ['*'], {}, {:order_by => [{'yo' => 'DESC'}, 'ya']})
396
+ expect(sql).to be == %Q{SELECT * FROM foo ORDER BY yo DESC, ya}
397
+ expect(bind.join(',')).to be == ''
398
+ end
399
+ end
400
+
401
+ context 'group_by' do
402
+ it 'scalar' do
403
+ sql, bind = builder.select('foo', ['*'], {}, {:group_by => 'yo'})
404
+ expect(sql).to be == %Q{SELECT * FROM foo GROUP BY yo}
405
+ expect(bind.join(',')).to be == ''
406
+ end
407
+
408
+ it 'hash ref' do
409
+ sql, bind = builder.select('foo', ['*'], {}, {:group_by => {'yo' => 'DESC'}})
410
+ expect(sql).to be == %Q{SELECT * FROM foo GROUP BY yo DESC}
411
+ expect(bind.join(',')).to be == ''
412
+ end
413
+
414
+ it 'array ref' do
415
+ sql, bind = builder.select('foo', ['*'], {}, {:group_by => ['yo', 'ya']})
416
+ expect(sql).to be == %Q{SELECT * FROM foo GROUP BY yo, ya}
417
+ expect(bind.join(',')).to be == ''
418
+ end
419
+
420
+ it 'mixed' do
421
+ sql, bind = builder.select('foo', ['*'], {}, {:group_by => [{'yo' => 'DESC'}, 'ya']})
422
+ expect(sql).to be == %Q{SELECT * FROM foo GROUP BY yo DESC, ya}
423
+ expect(bind.join(',')).to be == ''
424
+ end
425
+ end
426
+
427
+ context 'index_hint' do
428
+ it 'scalar' do
429
+ sql, bind = builder.select('foo', ['*'], {}, {:index_hint => 'bar'})
430
+ expect(sql).to be == %Q{SELECT * FROM foo USE INDEX (bar)}
431
+ end
432
+
433
+ it 'array ref' do
434
+ sql, bind = builder.select('foo', ['*'], {}, {:index_hint => ['bar', 'baz']})
435
+ expect(sql).to be == %Q{SELECT * FROM foo USE INDEX (bar,baz)}
436
+ end
437
+
438
+ it 'hash ref' do
439
+ sql, bind = builder.select('foo', ['*'], {}, {:index_hint => {:type => 'FORCE', :list => ['bar']}})
440
+ expect(sql).to be == %Q{SELECT * FROM foo FORCE INDEX (bar)}
441
+ end
442
+ end
443
+
444
+ context 'from' do
445
+ it 'multi from' do
446
+ sql, bind = builder.select(%w/foo bar/, ['*'], {}, )
447
+ expect(sql).to be == %Q{SELECT * FROM foo, bar}
448
+ expect(bind.join(',')).to be == ''
449
+ end
450
+
451
+ it 'multi from with alias' do
452
+ sql, bind = builder.select([ { :foo => 'f' }, { :bar => 'b' } ], ['*'], {})
453
+ expect(sql).to be == %Q{SELECT * FROM foo f, bar b}
454
+ expect(bind.join(',')).to be == ''
455
+ end
456
+ end
457
+
458
+ it 'join' do
459
+ sql, bind = builder.select(nil, ['*'], {}, {:joins => {
460
+ :foo => {
461
+ :type => 'LEFT OUTER',
462
+ :table => 'bar',
463
+ :condition => 'foo.bar_id = bar.id',
464
+ }
465
+ }})
466
+ expect(sql).to be == %Q{SELECT * FROM foo LEFT OUTER JOIN bar ON foo.bar_id = bar.id}
467
+ expect(bind.join(',')).to be == ''
468
+ end
469
+ end
470
+ end