twowaysql 0.2.0
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.
- data/History.txt +3 -0
- data/License.txt +13 -0
- data/Manifest.txt +38 -0
- data/README.txt +382 -0
- data/Rakefile +4 -0
- data/config/hoe.rb +73 -0
- data/config/requirements.rb +15 -0
- data/issues/issue-25efcfc383f3b0f6c0e2730ae7c2975bb2b3de26.yaml +18 -0
- data/issues/issue-39023ea09e17e2d64bcef03aa59cdfe38b78ad5b.yaml +26 -0
- data/issues/issue-4bc308d55ae91f266e656162a4147d356de1166c.yaml +24 -0
- data/issues/issue-897995fa10377eabdf597e8e7692f17087c76923.yaml +26 -0
- data/issues/issue-bd38c1cdc965d73dd629a81db2de1bcdcf4b10b8.yaml +26 -0
- data/issues/issue-f2b773020b54f839c03d899b38b5113c8fd991df.yaml +18 -0
- data/issues/issue-f39b907d01d7fa93df8c7a9de2e1b5e27727ee0a.yaml +18 -0
- data/issues/issue-f64d73ed4f9854f1ded77e6496dbf59cfb3770a7.yaml +18 -0
- data/issues/project.yaml +16 -0
- data/lib/twowaysql/node.rb +239 -0
- data/lib/twowaysql/parser.rb +489 -0
- data/lib/twowaysql/parser.y +226 -0
- data/lib/twowaysql/template.rb +75 -0
- data/lib/twowaysql/version.rb +9 -0
- data/lib/twowaysql.rb +6 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +82 -0
- data/setup.rb +1585 -0
- data/spec/large_sql_spec.rb +142 -0
- data/spec/learning_regex_spec.rb +234 -0
- data/spec/spec.opts +0 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/twowaysql_spec.rb +736 -0
- data/tasks/deployment.rake +53 -0
- data/tasks/ditz.rake +8 -0
- data/tasks/environment.rake +7 -0
- data/tasks/racc.rake +23 -0
- data/tasks/rspec.rake +21 -0
- data/tasks/website.rake +17 -0
- metadata +104 -0
@@ -0,0 +1,736 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
|
3
|
+
|
4
|
+
describe TwoWaySQL::Template do
|
5
|
+
|
6
|
+
before do
|
7
|
+
@ctx = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
describe "when parse SQL without comment nodes, e.g. 'SELECT * FROM emp'" do
|
13
|
+
before do
|
14
|
+
sql = "SELECT * FROM emp"
|
15
|
+
@template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
16
|
+
@result = @template.merge(@ctx)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should not change original sql" do
|
20
|
+
@result.sql.should == "SELECT * FROM emp"
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should have empty bound valiables" do
|
24
|
+
@result.bound_variables.should be_empty
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
describe "when parsed from 'SELECT * FROM emp WHERE job = /*ctx[:job]*/'CLERK' AND deptno = /*ctx[:deptno]*/20'" do
|
31
|
+
before do
|
32
|
+
sql = "SELECT * FROM emp WHERE job = /*ctx[:job]*/'CLERK' AND deptno = /*ctx[:deptno]*/20"
|
33
|
+
@template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "pass Context with Symbol keys like ctx[:job] = 'HOGE' and ctx[:deptno] = 30" do
|
37
|
+
before do
|
38
|
+
@ctx[:job] = "HOGE"
|
39
|
+
@ctx[:deptno] = 30
|
40
|
+
@result = @template.merge(@ctx)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should parse '/*' as comment start and '*/' as comment end, then replace them with question mark. so SQL will 'SELECT * FROM emp WHERE job = ? AND deptno = ?'" do
|
44
|
+
@result.sql.should == "SELECT * FROM emp WHERE job = ? AND deptno = ?"
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should have two bound variables in Array ['HOGE', 30]" do
|
48
|
+
@result.bound_variables.should == ["HOGE", 30]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
|
55
|
+
describe "when parsed from 'SELECT * FROM emp WHERE job = /*ctx['job']*/'CLERK' AND deptno = /*ctx['deptno']*/20'" do
|
56
|
+
before do
|
57
|
+
sql = "SELECT * FROM emp WHERE job = /*ctx['job']*/'CLERK' AND deptno = /*ctx['deptno']*/20"
|
58
|
+
@template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "pass Context with String keys like ctx['job'] = 'HOGE' and ctx['deptno'] = 30" do
|
62
|
+
before do
|
63
|
+
@ctx['job'] = "HOGE"
|
64
|
+
@ctx['deptno'] = 30
|
65
|
+
@result = @template.merge(@ctx)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should parse '/*' as comment start and '*/' as comment end, then replace them with question mark. so SQL will 'SELECT * FROM emp WHERE job = ? AND deptno = ?'" do
|
69
|
+
@result.sql.should == "SELECT * FROM emp WHERE job = ? AND deptno = ?"
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should have two bound variables in Array ['HOGE', 30]" do
|
73
|
+
@result.bound_variables.should == ["HOGE", 30]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
|
80
|
+
describe "when parsed from 'SELECT * FROM emp WHERE job = #*ctx[:job]*#'CLERK' AND deptno = #*ctx[:deptno]*#20'" do
|
81
|
+
before do
|
82
|
+
sql = "SELECT * FROM emp WHERE job = #*ctx[:job]*#'CLERK' AND deptno = #*ctx[:deptno]*#20"
|
83
|
+
@template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
84
|
+
|
85
|
+
@ctx[:job] = "HOGE"
|
86
|
+
@ctx[:deptno] = 30
|
87
|
+
@result = @template.merge(@ctx)
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should parse '#*' as comment start and '*#' as comment end, then replace them with question mark. so SQL will 'SELECT * FROM emp WHERE job = ? AND deptno = ?'" do
|
91
|
+
@result.sql.should == 'SELECT * FROM emp WHERE job = ? AND deptno = ?'
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should have two variables" do
|
95
|
+
@result.bound_variables.size.should == 2
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should have two bound variables in Array" do
|
99
|
+
@result.bound_variables.should == ["HOGE", 30]
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
|
104
|
+
|
105
|
+
describe "when parsed from SQL file with one or more white speces in comment, like 'SELECT * FROM emp WHERE job = /* ctx[:job]*/'CLERK''" do
|
106
|
+
before do
|
107
|
+
sql = "SELECT * FROM emp WHERE job = /* ctx[:job]*/'CLERK'"
|
108
|
+
@template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
109
|
+
|
110
|
+
@ctx[:job] = "HOGE"
|
111
|
+
@result = @template.merge(@ctx)
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should treat comment node which starts with one or more speces like /* ctx[:job]*/'CLERK' as real comment node, therefore it does *NOT* replace comment node with question mark. so SQL will 'SELECT * FROM emp WHERE job = 'CLERK''" do
|
115
|
+
@result.sql.should == "SELECT * FROM emp WHERE job = 'CLERK'"
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should have no variable nodes, so return empty Array as bound variables" do
|
119
|
+
@result.bound_variables.should be_empty
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
|
125
|
+
describe "when parsed from 'SELECT * FROM emp WHERE empno = /*ctx[:empno]*/1 AND 1 = 1'" do
|
126
|
+
before do
|
127
|
+
sql = "SELECT * FROM emp WHERE empno = /*ctx[:empno]*/1 AND 1 = 1"
|
128
|
+
@template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
129
|
+
|
130
|
+
@ctx[:empno] = 7788
|
131
|
+
@result = @template.merge(@ctx)
|
132
|
+
end
|
133
|
+
|
134
|
+
it "parsed SQL should 'SELECT * FROM emp WHERE empno = ? AND 1 = 1'" do
|
135
|
+
@result.sql.should == 'SELECT * FROM emp WHERE empno = ? AND 1 = 1'
|
136
|
+
end
|
137
|
+
|
138
|
+
it "should have bound variables in Array [7788]" do
|
139
|
+
@result.bound_variables.should == [7788]
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
|
144
|
+
|
145
|
+
describe "when parsed from 'SELECT * FROM emp/*IF ctx[:job] */ WHERE job = /*ctx[:job]*/'CLERK'/*END*/'" do
|
146
|
+
before do
|
147
|
+
sql = "SELECT * FROM emp/*IF ctx[:job] */ WHERE job = /*ctx[:job]*/'CLERK'/*END*/"
|
148
|
+
@template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
149
|
+
end
|
150
|
+
|
151
|
+
describe "and when :job param exists" do
|
152
|
+
before do
|
153
|
+
@ctx[:job] = "HOGE"
|
154
|
+
@result = @template.merge(@ctx)
|
155
|
+
end
|
156
|
+
it "parsed SQL should 'SELECT * FROM emp WHERE job = ?'" do
|
157
|
+
@result.sql.should == 'SELECT * FROM emp WHERE job = ?'
|
158
|
+
end
|
159
|
+
it "should have bound variables in Array ['HOGE']" do
|
160
|
+
@result.bound_variables.should == ['HOGE']
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
describe "and when :job param does not exist" do
|
165
|
+
before do
|
166
|
+
@result = @template.merge(@ctx)
|
167
|
+
end
|
168
|
+
it "parsed SQL should 'SELECT * FROM emp'" do
|
169
|
+
@result.sql.should == 'SELECT * FROM emp'
|
170
|
+
end
|
171
|
+
it "bound variables should be empty" do
|
172
|
+
@result.bound_variables.should be_empty
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
|
178
|
+
|
179
|
+
describe "when parsed from SQL with 'nested if' like '/*IF ctx[:aaa]*/aaa/*IF ctx[:bbb]*/bbb/*END*//*END*/'" do
|
180
|
+
before do
|
181
|
+
sql = "/*IF ctx[:aaa]*/aaa/*IF ctx[:bbb]*/bbb/*END*//*END*/"
|
182
|
+
@template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
183
|
+
end
|
184
|
+
|
185
|
+
describe "and when inner is true but outer is false" do
|
186
|
+
before do
|
187
|
+
@ctx[:bbb] = "hoge"
|
188
|
+
@result = @template.merge(@ctx)
|
189
|
+
end
|
190
|
+
it "parsed SQL should be empty'" do
|
191
|
+
@result.sql.should be_empty
|
192
|
+
end
|
193
|
+
it "bound variables is empty too" do
|
194
|
+
@result.bound_variables.should be_empty
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
describe "and when outer is true and inner is false" do
|
199
|
+
before do
|
200
|
+
@ctx[:aaa] = "hoge"
|
201
|
+
@result = @template.merge(@ctx)
|
202
|
+
end
|
203
|
+
it "parsed SQL should be 'aaa'" do
|
204
|
+
@result.sql.should == 'aaa'
|
205
|
+
end
|
206
|
+
it "should have no bound variables because there is no assignments" do
|
207
|
+
@result.bound_variables.should be_empty
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
describe "and when both outer and inner is true" do
|
212
|
+
before do
|
213
|
+
@ctx[:aaa] = "hoge"
|
214
|
+
@ctx[:bbb] = "foo"
|
215
|
+
@result = @template.merge(@ctx)
|
216
|
+
end
|
217
|
+
it "parsed SQL should be 'aaabbb'" do
|
218
|
+
@result.sql.should == 'aaabbb'
|
219
|
+
end
|
220
|
+
it "should have no bound variables because there is no assignments" do
|
221
|
+
@result.bound_variables.should be_empty
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
end
|
226
|
+
|
227
|
+
|
228
|
+
|
229
|
+
describe "when parsed from 'SELECT * FROM emp WHERE /*IF ctx[:job]*/job = /*ctx[:job]*/'CLERK'-- ELSE job is null/*END*/'" do
|
230
|
+
before do
|
231
|
+
sql = "SELECT * FROM emp WHERE /*IF ctx[:job]*/job = /*ctx[:job]*/'CLERK'-- ELSE job is null/*END*/"
|
232
|
+
@template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
233
|
+
end
|
234
|
+
|
235
|
+
describe "and when :job param exists" do
|
236
|
+
before do
|
237
|
+
@ctx[:job] = "HOGE"
|
238
|
+
@result = @template.merge(@ctx)
|
239
|
+
end
|
240
|
+
it "parsed SQL should 'SELECT * FROM emp WHERE job = ?'" do
|
241
|
+
@result.sql.should == 'SELECT * FROM emp WHERE job = ?'
|
242
|
+
end
|
243
|
+
it "should have bound variables in Array ['HOGE']" do
|
244
|
+
@result.bound_variables.should == ['HOGE']
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
describe "and when :job param does not exist" do
|
249
|
+
before do
|
250
|
+
@result = @template.merge(@ctx)
|
251
|
+
end
|
252
|
+
it "parsed SQL should 'SELECT * FROM emp WHERE job is null'" do
|
253
|
+
@result.sql.should == 'SELECT * FROM emp WHERE job is null'
|
254
|
+
end
|
255
|
+
it "bound variables should be empty" do
|
256
|
+
@result.bound_variables.should be_empty
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
|
262
|
+
|
263
|
+
describe "when parsed from '/*IF false*/aaa--ELSE bbb = /*ctx[:bbb]*/123/*END*/'" do
|
264
|
+
before do
|
265
|
+
sql = "/*IF false*/aaa--ELSE bbb = /*ctx[:bbb]*/123/*END*/"
|
266
|
+
@template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
267
|
+
end
|
268
|
+
|
269
|
+
describe "and when :bbb param exists" do
|
270
|
+
before do
|
271
|
+
@ctx[:bbb] = 123
|
272
|
+
@result = @template.merge(@ctx)
|
273
|
+
end
|
274
|
+
it "parsed SQL should 'bbb = ?'" do
|
275
|
+
@result.sql.should == 'bbb = ?'
|
276
|
+
end
|
277
|
+
it "should have bound variables in Array [123]" do
|
278
|
+
@result.bound_variables.should == [123]
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
describe "and when :bbb param does not exist" do
|
283
|
+
before do
|
284
|
+
@result = @template.merge(@ctx)
|
285
|
+
end
|
286
|
+
it "parsed SQL should also 'bbb = ?'" do
|
287
|
+
@result.sql.should == 'bbb = ?'
|
288
|
+
end
|
289
|
+
it "should have bound variables in Array, accidentally [nil]" do
|
290
|
+
@result.bound_variables.should == [nil]
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
|
296
|
+
|
297
|
+
describe "when parsed from '/*IF false*/aaa--ELSE bbb/*IF false*/ccc--ELSE ddd/*END*//*END*/'" do
|
298
|
+
before do
|
299
|
+
sql = "/*IF false*/aaa--ELSE bbb/*IF false*/ccc--ELSE ddd/*END*//*END*/"
|
300
|
+
@template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
301
|
+
@result = @template.merge(@ctx)
|
302
|
+
end
|
303
|
+
|
304
|
+
it "parsed SQL should 'bbbddd'" do
|
305
|
+
@result.sql.should == "bbbddd"
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
|
310
|
+
|
311
|
+
describe "when parsed from 'SELECT * FROM emp/*BEGIN*/ WHERE /*IF false*/aaa-- ELSE AND deptno = 10/*END*//*END*/'" do
|
312
|
+
before do
|
313
|
+
sql = "SELECT * FROM emp/*BEGIN*/ WHERE /*IF false*/aaa-- ELSE AND deptno = 10/*END*//*END*/"
|
314
|
+
@template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
315
|
+
@result = @template.merge(@ctx)
|
316
|
+
end
|
317
|
+
|
318
|
+
it "parsed SQL should 'SELECT * FROM emp WHERE deptno = 10'" do
|
319
|
+
@result.sql.should == "SELECT * FROM emp WHERE deptno = 10"
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
describe "when parsed from 'SELECT * FROM emp/*BEGIN*/ WHERE /*IF false*/aaa--- ELSE AND deptno = 10/*END*//*END*/'" do
|
324
|
+
before do
|
325
|
+
sql = "SELECT * FROM emp/*BEGIN*/ WHERE /*IF false*/aaa--- ELSE AND deptno = 10/*END*//*END*/"
|
326
|
+
@template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
327
|
+
@result = @template.merge(@ctx)
|
328
|
+
end
|
329
|
+
|
330
|
+
it "parsed SQL should 'SELECT * FROM emp WHERE deptno = 10'" do
|
331
|
+
@result.sql.should == "SELECT * FROM emp WHERE deptno = 10"
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
|
336
|
+
|
337
|
+
describe "when parsed from 'SELECT * FROM emp/*BEGIN*/ WHERE /*IF ctx[:job]*/job = /*ctx[:job]*/'CLERK'/*END*//*IF ctx[:deptno]*/ AND deptno = /*ctx[:deptno]*/20/*END*//*END*/'" do
|
338
|
+
before do
|
339
|
+
sql = "SELECT * FROM emp/*BEGIN*/ WHERE /*IF ctx[:job]*/job = /*ctx[:job]*/'CLERK'/*END*//*IF ctx[:deptno]*/ AND deptno = /*ctx[:deptno]*/20/*END*//*END*/"
|
340
|
+
@template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
341
|
+
end
|
342
|
+
|
343
|
+
describe "and when context is empty (no param exists)" do
|
344
|
+
before do
|
345
|
+
@result = @template.merge(@ctx)
|
346
|
+
end
|
347
|
+
it "parsed SQL should 'SELECT * FROM emp'" do
|
348
|
+
@result.sql.should == 'SELECT * FROM emp'
|
349
|
+
end
|
350
|
+
it "bound variables should be empty" do
|
351
|
+
@result.bound_variables.should be_empty
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
describe "and when :job param exists" do
|
356
|
+
before do
|
357
|
+
@ctx[:job] = "HOGE"
|
358
|
+
@result = @template.merge(@ctx)
|
359
|
+
end
|
360
|
+
it "parsed SQL should 'SELECT * FROM emp WHERE job = ?'" do
|
361
|
+
@result.sql.should == 'SELECT * FROM emp WHERE job = ?'
|
362
|
+
end
|
363
|
+
it "should have bound variables in Array ['HOGE']" do
|
364
|
+
@result.bound_variables.should == ['HOGE']
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
describe "and when :job and :deptno param exists" do
|
369
|
+
before do
|
370
|
+
@ctx[:job] = "HOGE"
|
371
|
+
@ctx[:deptno] = 20
|
372
|
+
@result = @template.merge(@ctx)
|
373
|
+
end
|
374
|
+
it "parsed SQL should 'SELECT * FROM emp WHERE job = ? AND deptno = ?'" do
|
375
|
+
@result.sql.should == 'SELECT * FROM emp WHERE job = ? AND deptno = ?'
|
376
|
+
end
|
377
|
+
it "should have bound variables in Array ['HOGE',20]" do
|
378
|
+
@result.bound_variables.should == ['HOGE',20]
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
describe "and when :job param does not exist and :deptno param exists" do
|
383
|
+
before do
|
384
|
+
@ctx[:deptno] = 20
|
385
|
+
@result = @template.merge(@ctx)
|
386
|
+
end
|
387
|
+
it "parsed SQL should 'SELECT * FROM emp WHERE deptno = ?'" do
|
388
|
+
@result.sql.should == 'SELECT * FROM emp WHERE deptno = ?'
|
389
|
+
end
|
390
|
+
it "should have bound variables in Array [20]" do
|
391
|
+
@result.bound_variables.should == [20]
|
392
|
+
end
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
|
397
|
+
|
398
|
+
describe "when parsed from '/*BEGIN*/WHERE /*IF true*/aaa BETWEEN /*ctx[:bbb]*/111 AND /*ctx[:ccc]*/123/*END*//*END*/'" do
|
399
|
+
before do
|
400
|
+
sql = "/*BEGIN*/WHERE /*IF true*/aaa BETWEEN /*ctx[:bbb]*/111 AND /*ctx[:ccc]*/123/*END*//*END*/"
|
401
|
+
@template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
402
|
+
end
|
403
|
+
|
404
|
+
describe "and when :job and :deptno param exists" do
|
405
|
+
before do
|
406
|
+
@ctx[:bbb] = 300
|
407
|
+
@ctx[:ccc] = 400
|
408
|
+
@result = @template.merge(@ctx)
|
409
|
+
end
|
410
|
+
it "parsed SQL should 'WHERE aaa BETWEEN ? AND ?'" do
|
411
|
+
@result.sql.should == "WHERE aaa BETWEEN ? AND ?"
|
412
|
+
end
|
413
|
+
it "should have bound variables in Array [300,400]" do
|
414
|
+
@result.bound_variables.should == [300,400]
|
415
|
+
end
|
416
|
+
end
|
417
|
+
|
418
|
+
describe "and when :job and :deptno param does not exist" do
|
419
|
+
before do
|
420
|
+
@result = @template.merge(@ctx)
|
421
|
+
end
|
422
|
+
it "parsed SQL should 'WHERE aaa BETWEEN ? AND ?'" do
|
423
|
+
@result.sql.should == "WHERE aaa BETWEEN ? AND ?"
|
424
|
+
end
|
425
|
+
it "should have bound variables in Array, accidentally [nil,nil]" do
|
426
|
+
@result.bound_variables.should == [nil,nil]
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
430
|
+
end
|
431
|
+
|
432
|
+
|
433
|
+
|
434
|
+
describe "when parsed from 'SELECT * FROM emp WHERE deptno IN /*ctx[:deptnoList]*/(10, 20) ORDER BY ename'" do
|
435
|
+
before do
|
436
|
+
sql = "SELECT * FROM emp WHERE deptno IN /*ctx[:deptnoList]*/(10, 20) ORDER BY ename"
|
437
|
+
@template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
438
|
+
end
|
439
|
+
|
440
|
+
describe "and when :deptnoList param is [30,40,50]" do
|
441
|
+
before do
|
442
|
+
@ctx[:deptnoList] = [30,40,50]
|
443
|
+
@result = @template.merge(@ctx)
|
444
|
+
end
|
445
|
+
it "parsed SQL should 'SELECT * FROM emp WHERE deptno IN (?, ?, ?) ORDER BY ename'" do
|
446
|
+
@result.sql.should == "SELECT * FROM emp WHERE deptno IN (?, ?, ?) ORDER BY ename"
|
447
|
+
end
|
448
|
+
it "should have bound variables in Array [30,40,50]" do
|
449
|
+
@result.bound_variables.should == [30,40,50]
|
450
|
+
end
|
451
|
+
end
|
452
|
+
|
453
|
+
describe "and when :deptnoList param is [30]" do
|
454
|
+
before do
|
455
|
+
@ctx[:deptnoList] = [30]
|
456
|
+
@result = @template.merge(@ctx)
|
457
|
+
end
|
458
|
+
it "parsed SQL should 'SELECT * FROM emp WHERE deptno IN (?) ORDER BY ename'" do
|
459
|
+
@result.sql.should == "SELECT * FROM emp WHERE deptno IN (?) ORDER BY ename"
|
460
|
+
end
|
461
|
+
it "should have bound variables in Array [30]" do
|
462
|
+
@result.bound_variables.should == [30]
|
463
|
+
end
|
464
|
+
end
|
465
|
+
|
466
|
+
describe "and when :deptnoList param is empty" do
|
467
|
+
before do
|
468
|
+
@ctx[:deptnoList] = []
|
469
|
+
@result = @template.merge(@ctx)
|
470
|
+
end
|
471
|
+
it "parsed SQL should 'SELECT * FROM emp WHERE deptno IN ORDER BY ename' and *CAUSES SYNTAX ERROR* (use IF comment to avoid this)" do
|
472
|
+
@result.sql.should == "SELECT * FROM emp WHERE deptno IN ORDER BY ename"
|
473
|
+
end
|
474
|
+
it "bound variables should be empty" do
|
475
|
+
@result.bound_variables.should be_empty
|
476
|
+
end
|
477
|
+
end
|
478
|
+
|
479
|
+
describe "and when :deptnoList param does not exist" do
|
480
|
+
before do
|
481
|
+
@result = @template.merge(@ctx)
|
482
|
+
end
|
483
|
+
it "parsed SQL should 'SELECT * FROM emp WHERE deptno IN ORDER BY ename' and *CAUSES SYNTAX ERROR* (use IF comment to avoid this)" do
|
484
|
+
@result.sql.should == "SELECT * FROM emp WHERE deptno IN ORDER BY ename"
|
485
|
+
end
|
486
|
+
it "bound variables should be empty" do
|
487
|
+
@result.bound_variables.should be_empty
|
488
|
+
end
|
489
|
+
end
|
490
|
+
|
491
|
+
end
|
492
|
+
|
493
|
+
|
494
|
+
|
495
|
+
describe "when parsed from 'SELECT * FROM emp WHERE ename IN /*ctx[:enames]*/('SCOTT','MARY') AND job IN /*ctx[:jobs]*/('ANALYST', 'FREE')'" do
|
496
|
+
before do
|
497
|
+
sql = "SELECT * FROM emp WHERE ename IN /*ctx[:enames]*/('SCOTT','MARY') AND job IN /*ctx[:jobs]*/('ANALYST', 'FREE')"
|
498
|
+
@template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
499
|
+
end
|
500
|
+
|
501
|
+
describe "and when :enames param is ['DAVE', 'MARY', 'SCOTT'] and :jobs param is ['MANAGER', 'ANALYST']" do
|
502
|
+
before do
|
503
|
+
@ctx[:enames] = ['DAVE', 'MARY', 'SCOTT']
|
504
|
+
@ctx[:jobs] = ['MANAGER', 'ANALYST']
|
505
|
+
@result = @template.merge(@ctx)
|
506
|
+
end
|
507
|
+
it "parsed SQL should 'SELECT * FROM emp WHERE ename IN (?, ?, ?) AND job IN (?, ?)'" do
|
508
|
+
@result.sql.should == "SELECT * FROM emp WHERE ename IN (?, ?, ?) AND job IN (?, ?)"
|
509
|
+
end
|
510
|
+
it "should have bound variables in Array ['DAVE', 'MARY', 'SCOTT', 'MANAGER', 'ANALYST']" do
|
511
|
+
@result.bound_variables.should == ['DAVE', 'MARY', 'SCOTT', 'MANAGER', 'ANALYST']
|
512
|
+
end
|
513
|
+
end
|
514
|
+
end
|
515
|
+
|
516
|
+
|
517
|
+
|
518
|
+
describe "when parsed from 'INSERT INTO ITEM (ID, NUM) VALUES (/*ctx[:id]*/1, /*ctx[:num]*/20)'" do
|
519
|
+
before do
|
520
|
+
sql = "INSERT INTO ITEM (ID, NUM) VALUES (/*ctx[:id]*/1, /*ctx[:num]*/20)"
|
521
|
+
@template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
522
|
+
end
|
523
|
+
|
524
|
+
describe "and when :id param is 0 and :num param is 1" do
|
525
|
+
before do
|
526
|
+
@ctx[:id] = 0
|
527
|
+
@ctx[:num] = 1
|
528
|
+
@result = @template.merge(@ctx)
|
529
|
+
end
|
530
|
+
it "parsed SQL should 'INSERT INTO ITEM (ID, NUM) VALUES (?, ?)'" do
|
531
|
+
@result.sql.should == "INSERT INTO ITEM (ID, NUM) VALUES (?, ?)"
|
532
|
+
end
|
533
|
+
it "should have bound variables in Array [0, 1]" do
|
534
|
+
@result.bound_variables.should == [0, 1]
|
535
|
+
end
|
536
|
+
end
|
537
|
+
end
|
538
|
+
|
539
|
+
|
540
|
+
|
541
|
+
describe "when parsed from SQL with embedded variable comment '/*$ctx[:aaa]*/foo'" do
|
542
|
+
before do
|
543
|
+
sql = "/*$ctx[:aaa]*/foo"
|
544
|
+
@template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
545
|
+
end
|
546
|
+
|
547
|
+
describe "and :aaa param is 'hoge'" do
|
548
|
+
before do
|
549
|
+
@ctx[:aaa] = 'hoge'
|
550
|
+
@result = @template.merge(@ctx)
|
551
|
+
end
|
552
|
+
it "parsed SQL should 'hoge'" do
|
553
|
+
@result.sql.should == "hoge"
|
554
|
+
end
|
555
|
+
end
|
556
|
+
end
|
557
|
+
|
558
|
+
|
559
|
+
|
560
|
+
describe "when parsed from SQL with embedded variable comment 'BETWEEN sal ? AND ?'" do
|
561
|
+
before do
|
562
|
+
sql = "BETWEEN sal ? AND ?"
|
563
|
+
@template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
564
|
+
end
|
565
|
+
|
566
|
+
describe "and ctx[1] = 0 and ctx[2] = 1000 (note: key starts with 1, not 0.)" do
|
567
|
+
before do
|
568
|
+
@ctx[1] = 0
|
569
|
+
@ctx[2] = 1000
|
570
|
+
@result = @template.merge(@ctx)
|
571
|
+
end
|
572
|
+
it "parsed SQL should 'BETWEEN sal ? AND ?'" do
|
573
|
+
@result.sql.should == "BETWEEN sal ? AND ?"
|
574
|
+
end
|
575
|
+
it "should have bound variables in Array [0, 1000]" do
|
576
|
+
@result.bound_variables.should == [0, 1000]
|
577
|
+
end
|
578
|
+
end
|
579
|
+
end
|
580
|
+
|
581
|
+
|
582
|
+
|
583
|
+
describe "when parsed from 'SELECT * FROM emp/*hoge'" do
|
584
|
+
it "should cause parse error" do
|
585
|
+
lambda {
|
586
|
+
TwoWaySQL::Template.parse("SELECT * FROM emp/*hoge")
|
587
|
+
}.should raise_error(Racc::ParseError)
|
588
|
+
end
|
589
|
+
end
|
590
|
+
|
591
|
+
|
592
|
+
|
593
|
+
describe "when parsed from '/*BEGIN*/'" do
|
594
|
+
it "should cause parse error" do
|
595
|
+
lambda {
|
596
|
+
TwoWaySQL::Template.parse("/*BEGIN*/")
|
597
|
+
}.should raise_error(Racc::ParseError)
|
598
|
+
end
|
599
|
+
end
|
600
|
+
|
601
|
+
|
602
|
+
|
603
|
+
describe "when parse SQL with semicolon, " do
|
604
|
+
describe "that ends with semicolon like 'SELECT * FROM emp;'" do
|
605
|
+
before do
|
606
|
+
sql = "SELECT * FROM emp;"
|
607
|
+
@template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
608
|
+
@result = @template.merge(@ctx)
|
609
|
+
end
|
610
|
+
it "should strip semicolon at input end" do
|
611
|
+
@result.sql.should == "SELECT * FROM emp"
|
612
|
+
end
|
613
|
+
end
|
614
|
+
|
615
|
+
describe "that ends with semicolon and tab like 'SELECT * FROM emp;\t'" do
|
616
|
+
before do
|
617
|
+
sql = "SELECT * FROM emp;\t"
|
618
|
+
@template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
619
|
+
@result = @template.merge(@ctx)
|
620
|
+
end
|
621
|
+
it "should strip semicolon and tab at input end" do
|
622
|
+
@result.sql.should == "SELECT * FROM emp"
|
623
|
+
end
|
624
|
+
end
|
625
|
+
|
626
|
+
describe "that ends with semicolon and spaces like 'SELECT * FROM emp; '" do
|
627
|
+
before do
|
628
|
+
sql = "SELECT * FROM emp; "
|
629
|
+
@template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
630
|
+
@result = @template.merge(@ctx)
|
631
|
+
end
|
632
|
+
it "should strip semicolon and spaces at input end" do
|
633
|
+
@result.sql.should == "SELECT * FROM emp"
|
634
|
+
end
|
635
|
+
end
|
636
|
+
end
|
637
|
+
|
638
|
+
|
639
|
+
|
640
|
+
describe "various characters" do
|
641
|
+
describe " '<>' " do
|
642
|
+
before do
|
643
|
+
sql = "SELECT * FROM emp WHERE job <> /*ctx[:job]*/'CLERK'"
|
644
|
+
@template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
645
|
+
@ctx[:job] = "HOGE"
|
646
|
+
@result = @template.merge(@ctx)
|
647
|
+
end
|
648
|
+
|
649
|
+
it "SQL will 'SELECT * FROM emp WHERE job <> ?'" do
|
650
|
+
@result.sql.should == "SELECT * FROM emp WHERE job <> ?"
|
651
|
+
end
|
652
|
+
|
653
|
+
it "should have two bound variables in Array ['HOGE']" do
|
654
|
+
@result.bound_variables.should == ["HOGE"]
|
655
|
+
end
|
656
|
+
end
|
657
|
+
|
658
|
+
|
659
|
+
describe "minus, such as -5 " do
|
660
|
+
before do
|
661
|
+
sql = "SELECT * FROM statistics WHERE degree = /*ctx[:degree]*/-5"
|
662
|
+
@template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
663
|
+
@ctx[:degree] = -10
|
664
|
+
@result = @template.merge(@ctx)
|
665
|
+
end
|
666
|
+
|
667
|
+
it "SQL will 'SELECT * FROM statistics WHERE degree = ?'" do
|
668
|
+
@result.sql.should == "SELECT * FROM statistics WHERE degree = ?"
|
669
|
+
end
|
670
|
+
|
671
|
+
it "should have two bound variables in Array [-10]" do
|
672
|
+
@result.bound_variables.should == [-10]
|
673
|
+
end
|
674
|
+
end
|
675
|
+
|
676
|
+
|
677
|
+
describe "quote escape, such as 'Let''s' " do
|
678
|
+
before do
|
679
|
+
sql = "SELECT * FROM comments WHERE message = /*ctx[:message]*/'Let''s GO'"
|
680
|
+
@template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
681
|
+
@ctx[:message] = "Hang'in there"
|
682
|
+
@result = @template.merge(@ctx)
|
683
|
+
end
|
684
|
+
|
685
|
+
it "SQL will 'SELECT * FROM comments WHERE message = ?'" do
|
686
|
+
@result.sql.should == "SELECT * FROM comments WHERE message = ?"
|
687
|
+
end
|
688
|
+
|
689
|
+
it "should have two bound variables in Array ['Hang'in there']" do
|
690
|
+
@result.bound_variables.should == ["Hang'in there"]
|
691
|
+
end
|
692
|
+
end
|
693
|
+
|
694
|
+
end
|
695
|
+
|
696
|
+
|
697
|
+
|
698
|
+
describe "when parsed from 'SELECT * FROM emp -- comments here'" do
|
699
|
+
before do
|
700
|
+
sql = "SELECT * FROM emp -- comments here"
|
701
|
+
@template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
702
|
+
end
|
703
|
+
|
704
|
+
describe "and when 'job' param does not exist" do
|
705
|
+
before do
|
706
|
+
@result = @template.merge(@ctx)
|
707
|
+
end
|
708
|
+
it "parsed SQL should 'SELECT * FROM emp -- comments here'" do
|
709
|
+
@result.sql.should == 'SELECT * FROM emp -- comments here'
|
710
|
+
end
|
711
|
+
it "bound variables should be empty" do
|
712
|
+
@result.bound_variables.should be_empty
|
713
|
+
end
|
714
|
+
end
|
715
|
+
end
|
716
|
+
|
717
|
+
|
718
|
+
describe "when parsed from 'SELECT * FROM emp WHERE empno = /*ctx[:empno]*/5.0 AND 1 = 1'" do
|
719
|
+
before do
|
720
|
+
sql = "SELECT * FROM emp WHERE empno = /*ctx[:empno]*/5.0 AND 1 = 1"
|
721
|
+
@template = TwoWaySQL::Template.parse(sql, :preserve_eol => false)
|
722
|
+
|
723
|
+
@ctx[:empno] = 7788
|
724
|
+
@result = @template.merge(@ctx)
|
725
|
+
end
|
726
|
+
|
727
|
+
it "parsed SQL should 'SELECT * FROM emp WHERE empno = ? AND 1 = 1'" do
|
728
|
+
@result.sql.should == 'SELECT * FROM emp WHERE empno = ? AND 1 = 1'
|
729
|
+
end
|
730
|
+
|
731
|
+
it "should have bound variables in Array [7788]" do
|
732
|
+
@result.bound_variables.should == [7788]
|
733
|
+
end
|
734
|
+
end
|
735
|
+
|
736
|
+
end
|