sequel_core 1.0.0.1 → 1.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.
- data/CHANGELOG +14 -0
- data/COPYING +1 -1
- data/Rakefile +4 -1
- data/lib/sequel_core/adapters/mysql.rb +9 -2
- data/lib/sequel_core/adapters/oracle.rb +103 -4
- data/lib/sequel_core/adapters/postgres.rb +2 -0
- data/lib/sequel_core/database.rb +9 -3
- data/lib/sequel_core/dataset/sequelizer.rb +20 -9
- data/lib/sequel_core/dataset/sql.rb +9 -12
- data/lib/sequel_core/model.rb +1 -1
- data/spec/adapters/mysql_spec.rb +17 -0
- data/spec/adapters/oracle_spec.rb +157 -11
- data/spec/adapters/postgres_spec.rb +58 -0
- data/spec/adapters/sqlite_spec.rb +17 -3
- data/spec/database_spec.rb +26 -0
- data/spec/dataset_spec.rb +11 -1
- data/spec/sequelizer_spec.rb +153 -113
- metadata +3 -2
@@ -80,6 +80,64 @@ context "A PostgreSQL dataset" do
|
|
80
80
|
proc {@d.literal(false)}.should_not raise_error
|
81
81
|
end
|
82
82
|
|
83
|
+
specify "should quote columns using double quotes" do
|
84
|
+
@d.select(:name).sql.should == \
|
85
|
+
'SELECT "name" FROM test'
|
86
|
+
|
87
|
+
@d.select('COUNT(*)'.lit).sql.should == \
|
88
|
+
'SELECT COUNT(*) FROM test'
|
89
|
+
|
90
|
+
@d.select(:value.MAX).sql.should == \
|
91
|
+
'SELECT max("value") FROM test'
|
92
|
+
|
93
|
+
@d.select(:NOW[]).sql.should == \
|
94
|
+
'SELECT NOW() FROM test'
|
95
|
+
|
96
|
+
@d.select(:items__value.MAX).sql.should == \
|
97
|
+
'SELECT max(items."value") FROM test'
|
98
|
+
|
99
|
+
@d.order(:name.DESC).sql.should == \
|
100
|
+
'SELECT * FROM test ORDER BY "name" DESC'
|
101
|
+
|
102
|
+
@d.select('test.name AS item_name'.lit).sql.should == \
|
103
|
+
'SELECT test.name AS item_name FROM test'
|
104
|
+
|
105
|
+
@d.select('"name"'.lit).sql.should == \
|
106
|
+
'SELECT "name" FROM test'
|
107
|
+
|
108
|
+
@d.select('max(test."name") AS "max_name"'.lit).sql.should == \
|
109
|
+
'SELECT max(test."name") AS "max_name" FROM test'
|
110
|
+
|
111
|
+
@d.select(:test[:abc, 'hello']).sql.should == \
|
112
|
+
"SELECT test(\"abc\", 'hello') FROM test"
|
113
|
+
|
114
|
+
@d.select(:test[:abc__def, 'hello']).sql.should == \
|
115
|
+
"SELECT test(abc.\"def\", 'hello') FROM test"
|
116
|
+
|
117
|
+
@d.select(:test[:abc__def, 'hello'].as(:x2)).sql.should == \
|
118
|
+
"SELECT test(abc.\"def\", 'hello') AS \"x2\" FROM test"
|
119
|
+
|
120
|
+
@d.insert_sql(:value => 333).should == \
|
121
|
+
'INSERT INTO test ("value") VALUES (333)'
|
122
|
+
|
123
|
+
@d.insert_sql(:x => :y).should == \
|
124
|
+
'INSERT INTO test ("x") VALUES ("y")'
|
125
|
+
end
|
126
|
+
|
127
|
+
specify "should quote fields correctly when reversing the order" do
|
128
|
+
@d.reverse_order(:name).sql.should == \
|
129
|
+
'SELECT * FROM test ORDER BY "name" DESC'
|
130
|
+
|
131
|
+
@d.reverse_order(:name.DESC).sql.should == \
|
132
|
+
'SELECT * FROM test ORDER BY "name"'
|
133
|
+
|
134
|
+
@d.reverse_order(:name, :test.DESC).sql.should == \
|
135
|
+
'SELECT * FROM test ORDER BY "name" DESC, "test"'
|
136
|
+
|
137
|
+
@d.reverse_order(:name.DESC, :test).sql.should == \
|
138
|
+
'SELECT * FROM test ORDER BY "name", "test" DESC'
|
139
|
+
end
|
140
|
+
|
83
141
|
specify "should support transactions" do
|
84
142
|
PGSQL_DB.transaction do
|
85
143
|
@d << {:name => 'abc', :value => 1}
|
@@ -132,6 +132,18 @@ context "An SQLite database" do
|
|
132
132
|
SQLITE_DB[:time] << {:t => t1}
|
133
133
|
SQLITE_DB[:time].first[:t].should == t1
|
134
134
|
end
|
135
|
+
|
136
|
+
specify "should support sequential primary keys" do
|
137
|
+
@db.create_table!(:with_pk) {primary_key :id; text :name}
|
138
|
+
@db[:with_pk] << {:name => 'abc'}
|
139
|
+
@db[:with_pk] << {:name => 'def'}
|
140
|
+
@db[:with_pk] << {:name => 'ghi'}
|
141
|
+
@db[:with_pk].order(:name).all.should == [
|
142
|
+
{:id => 1, :name => 'abc'},
|
143
|
+
{:id => 2, :name => 'def'},
|
144
|
+
{:id => 3, :name => 'ghi'}
|
145
|
+
]
|
146
|
+
end
|
135
147
|
end
|
136
148
|
|
137
149
|
context "An SQLite dataset" do
|
@@ -310,6 +322,8 @@ context "SQLite dataset" do
|
|
310
322
|
end
|
311
323
|
end
|
312
324
|
|
325
|
+
__END__
|
326
|
+
|
313
327
|
context "A SQLite database" do
|
314
328
|
setup do
|
315
329
|
@db = SQLITE_DB
|
@@ -324,7 +338,7 @@ context "A SQLite database" do
|
|
324
338
|
end
|
325
339
|
|
326
340
|
specify "should not support drop_column operations" do
|
327
|
-
proc {@db.drop_column :test2, :xyz}.should raise_error(
|
341
|
+
proc {@db.drop_column :test2, :xyz}.should raise_error(Sequel::Error)
|
328
342
|
end
|
329
343
|
|
330
344
|
specify "should not support rename_column operations" do
|
@@ -333,13 +347,13 @@ context "A SQLite database" do
|
|
333
347
|
@db[:test2] << {:name => 'mmm', :value => 111, :xyz => 'qqqq'}
|
334
348
|
|
335
349
|
@db[:test2].columns.should == [:name, :value, :xyz]
|
336
|
-
proc {@db.rename_column :test2, :xyz, :zyx}.should raise_error(
|
350
|
+
proc {@db.rename_column :test2, :xyz, :zyx}.should raise_error(Sequel::Error)
|
337
351
|
end
|
338
352
|
|
339
353
|
specify "should not support set_column_type operations" do
|
340
354
|
@db.add_column :test2, :xyz, :float
|
341
355
|
@db[:test2].delete
|
342
356
|
@db[:test2] << {:name => 'mmm', :value => 111, :xyz => 56.78}
|
343
|
-
proc {@db.set_column_type :test2, :xyz, :integer}.should raise_error(
|
357
|
+
proc {@db.set_column_type :test2, :xyz, :integer}.should raise_error(Sequel::Error)
|
344
358
|
end
|
345
359
|
end
|
data/spec/database_spec.rb
CHANGED
@@ -810,3 +810,29 @@ context "Database#alter_table_sql" do
|
|
810
810
|
proc {@db.alter_table_sql(:mau, :op => :blah)}.should raise_error(Sequel::Error)
|
811
811
|
end
|
812
812
|
end
|
813
|
+
|
814
|
+
context "Database.connect" do
|
815
|
+
EEE_YAML = "development:\r\n adapter: eee\r\n username: mau\r\n password: tau\r\n host: alfonso\r\n database: mydb\r\n"
|
816
|
+
|
817
|
+
setup do
|
818
|
+
class EEE < Sequel::Database
|
819
|
+
set_adapter_scheme :eee
|
820
|
+
end
|
821
|
+
|
822
|
+
@fn = File.join(File.dirname(__FILE__), 'eee.yaml')
|
823
|
+
File.open(@fn, 'w') {|f| f << EEE_YAML}
|
824
|
+
end
|
825
|
+
|
826
|
+
teardown do
|
827
|
+
FileUtils.rm(@fn)
|
828
|
+
end
|
829
|
+
|
830
|
+
specify "should accept hashes loaded from YAML files" do
|
831
|
+
db = Sequel(YAML.load_file(@fn)['development'])
|
832
|
+
db.class.should == EEE
|
833
|
+
db.opts[:database].should == 'mydb'
|
834
|
+
db.opts[:user].should == 'mau'
|
835
|
+
db.opts[:password].should == 'tau'
|
836
|
+
db.opts[:host].should == 'alfonso'
|
837
|
+
end
|
838
|
+
end
|
data/spec/dataset_spec.rb
CHANGED
@@ -276,7 +276,9 @@ context "Dataset#where" do
|
|
276
276
|
end
|
277
277
|
|
278
278
|
specify "should raise if the dataset is grouped" do
|
279
|
-
proc {@dataset.group(:t).where(:a => 1)}.
|
279
|
+
proc {@dataset.group(:t).where(:a => 1)}.should_not raise_error
|
280
|
+
@dataset.group(:t).where(:a => 1).sql.should ==
|
281
|
+
"SELECT * FROM test WHERE (a = 1) GROUP BY t"
|
280
282
|
end
|
281
283
|
|
282
284
|
specify "should accept ranges" do
|
@@ -405,6 +407,9 @@ context "Dataset#and" do
|
|
405
407
|
|
406
408
|
specify "should raise if no filter exists" do
|
407
409
|
proc {@dataset.and(:a => 1)}.should raise_error(Sequel::Error)
|
410
|
+
proc {@dataset.where(:a => 1).group(:t).and(:b => 2)}.should_not raise_error(Sequel::Error)
|
411
|
+
@dataset.where(:a => 1).group(:t).and(:b => 2).sql ==
|
412
|
+
"SELECT * FROM test WHERE (a = 1) AND (b = 2) GROUP BY t"
|
408
413
|
end
|
409
414
|
|
410
415
|
specify "should add an alternative expression to the where clause" do
|
@@ -489,6 +494,11 @@ context "Dataset#having" do
|
|
489
494
|
@grouped.having {:sum[:population] > 10}.sql.should ==
|
490
495
|
"SELECT #{@columns} FROM test GROUP BY region HAVING (sum(population) > 10)"
|
491
496
|
end
|
497
|
+
|
498
|
+
specify "should work with and on the having clause" do
|
499
|
+
@grouped.having{ :a > 1 }.and{ :b < 2 }.sql.should ==
|
500
|
+
"SELECT #{@columns} FROM test GROUP BY region HAVING (a > 1) AND (b < 2)"
|
501
|
+
end
|
492
502
|
end
|
493
503
|
|
494
504
|
context "a grouped dataset" do
|
data/spec/sequelizer_spec.rb
CHANGED
@@ -25,7 +25,7 @@ context "Sequelizer without ParseTree" do
|
|
25
25
|
end
|
26
26
|
|
27
27
|
specify "should raise error when converting proc to SQL" do
|
28
|
-
proc {
|
28
|
+
proc {proc {:x > 1}.to_sql(@ds)}.should raise_error(Sequel::Error)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -54,8 +54,48 @@ context "Sequelizer without Ruby2Ruby" do
|
|
54
54
|
end
|
55
55
|
|
56
56
|
specify "should raise error only when using external expressions" do
|
57
|
-
proc {
|
58
|
-
proc {
|
57
|
+
proc {proc {:x > 1}.to_sql(@ds)}.should_not raise_error(Sequel::Error)
|
58
|
+
proc {proc {1 + 1}.to_sql(@ds)}.should raise_error(Sequel::Error)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "Proc without #to_sexp method (Ruby2Ruby missing)" do
|
63
|
+
setup do
|
64
|
+
class Proc
|
65
|
+
alias_method :orig_to_sexp, :to_sexp
|
66
|
+
remove_method :to_sexp
|
67
|
+
end
|
68
|
+
|
69
|
+
module Kernel
|
70
|
+
alias_method :orig_sq_require, :require
|
71
|
+
def require(name); raise LoadError if name == 'ruby2ruby'; end
|
72
|
+
end
|
73
|
+
old_verbose = $VERBOSE
|
74
|
+
$VERBOSE = nil
|
75
|
+
load(File.join(File.dirname(__FILE__), '../lib/sequel_core/dataset/sequelizer.rb'))
|
76
|
+
$VERBOSE = old_verbose
|
77
|
+
@db = Sequel::Database.new
|
78
|
+
@ds = @db[:items]
|
79
|
+
end
|
80
|
+
|
81
|
+
teardown do
|
82
|
+
module Kernel
|
83
|
+
alias_method :require, :orig_sq_require
|
84
|
+
end
|
85
|
+
old_verbose = $VERBOSE
|
86
|
+
$VERBOSE = nil
|
87
|
+
load(File.join(File.dirname(__FILE__), '../lib/sequel_core/dataset/sequelizer.rb'))
|
88
|
+
$VERBOSE = old_verbose
|
89
|
+
|
90
|
+
class Proc
|
91
|
+
alias_method :to_sexp, :orig_to_sexp
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
specify "should define a replacement Proc#to_sexp implementation" do
|
96
|
+
pr = proc {1 + 1}
|
97
|
+
proc {pr.to_sexp}.should_not raise_error
|
98
|
+
pr.to_sexp.should == [:bmethod, nil, [:call, [:lit, 1], :+, [:array, [:lit, 1]]]]
|
59
99
|
end
|
60
100
|
end
|
61
101
|
|
@@ -64,12 +104,12 @@ context "Proc#to_sql" do
|
|
64
104
|
DS = DB[:items]
|
65
105
|
|
66
106
|
class ::Proc
|
67
|
-
def
|
68
|
-
DS
|
107
|
+
def sql
|
108
|
+
to_sql(DS)
|
69
109
|
end
|
70
110
|
|
71
|
-
def
|
72
|
-
DS
|
111
|
+
def sql_comma_separated
|
112
|
+
to_sql(DS, :comma_separated => true)
|
73
113
|
end
|
74
114
|
end
|
75
115
|
|
@@ -85,253 +125,253 @@ context "Proc#to_sql" do
|
|
85
125
|
end
|
86
126
|
|
87
127
|
specify "should support <sym> <op> <lit>" do
|
88
|
-
proc {:x > 100}.
|
89
|
-
proc {:x < 100}.
|
90
|
-
proc {:x >= 100}.
|
91
|
-
proc {:x <= 100}.
|
92
|
-
proc {:x == 100}.
|
128
|
+
proc {:x > 100}.sql.should == '(x > 100)'
|
129
|
+
proc {:x < 100}.sql.should == '(x < 100)'
|
130
|
+
proc {:x >= 100}.sql.should == '(x >= 100)'
|
131
|
+
proc {:x <= 100}.sql.should == '(x <= 100)'
|
132
|
+
proc {:x == 100}.sql.should == '(x = 100)'
|
93
133
|
end
|
94
134
|
|
95
135
|
specify "should support number literals" do
|
96
|
-
proc {:x > 123.45}.
|
97
|
-
proc {:x > -30_000}.
|
136
|
+
proc {:x > 123.45}.sql.should == '(x > 123.45)'
|
137
|
+
proc {:x > -30_000}.sql.should == '(x > -30000)'
|
98
138
|
end
|
99
139
|
|
100
140
|
specify "should support string literals" do
|
101
|
-
proc {:x == 'abc'}.
|
102
|
-
proc {:y == "ab'cd"}.
|
141
|
+
proc {:x == 'abc'}.sql.should == "(x = 'abc')"
|
142
|
+
proc {:y == "ab'cd"}.sql.should == "(y = 'ab''cd')"
|
103
143
|
end
|
104
144
|
|
105
145
|
specify "should support boolean literals" do
|
106
|
-
proc {:x == false}.
|
107
|
-
proc {:x == true}.
|
146
|
+
proc {:x == false}.sql.should == "(x = 'f')"
|
147
|
+
proc {:x == true}.sql.should == "(x = 't')"
|
108
148
|
end
|
109
149
|
|
110
150
|
specify "should support nil literal and nil?" do
|
111
|
-
proc {:x == nil}.
|
112
|
-
proc {:x.nil?}.
|
151
|
+
proc {:x == nil}.sql.should == "(x IS NULL)"
|
152
|
+
proc {:x.nil?}.sql.should == "(x IS NULL)"
|
113
153
|
end
|
114
154
|
|
115
155
|
specify "should support local vars or method references" do
|
116
|
-
proc {proc {:x == a}.
|
156
|
+
proc {proc {:x == a}.sql}.should raise_error(NameError)
|
117
157
|
b = 123
|
118
|
-
proc {:x == b}.
|
158
|
+
proc {:x == b}.sql.should == "(x = 123)"
|
119
159
|
def xyz; 321; end
|
120
|
-
proc {:x == xyz}.
|
121
|
-
proc {:x == xyz.to_s}.
|
160
|
+
proc {:x == xyz}.sql.should == "(x = 321)"
|
161
|
+
proc {:x == xyz.to_s}.sql.should == "(x = '321')"
|
122
162
|
|
123
163
|
def y1(x); x; end
|
124
164
|
def y2; 111; end
|
125
165
|
|
126
|
-
proc {:x == y1(222)}.
|
127
|
-
proc {:x == y2}.
|
166
|
+
proc {:x == y1(222)}.sql.should == "(x = 222)"
|
167
|
+
proc {:x == y2}.sql.should == "(x = 111)"
|
128
168
|
end
|
129
169
|
|
130
170
|
specify "sould support subscript access on symbols" do
|
131
|
-
proc {:x|1 > 0}.
|
132
|
-
proc {:x|2|3 > 0}.
|
133
|
-
proc {:x|[4, 5] > 0}.
|
171
|
+
proc {:x|1 > 0}.sql.should == "(x[1] > 0)"
|
172
|
+
proc {:x|2|3 > 0}.sql.should == "(x[2, 3] > 0)"
|
173
|
+
proc {:x|[4, 5] > 0}.sql.should == "(x[4, 5] > 0)"
|
134
174
|
end
|
135
175
|
|
136
176
|
specify "should support constants" do
|
137
177
|
ZZZ = 444
|
138
|
-
proc {:x == ZZZ}.
|
178
|
+
proc {:x == ZZZ}.sql.should == "(x = 444)"
|
139
179
|
|
140
180
|
CCCD = Module.new
|
141
181
|
CCCD::DDD = 'hi'
|
142
|
-
proc {:x == CCCD::DDD}.
|
182
|
+
proc {:x == CCCD::DDD}.sql.should == "(x = 'hi')"
|
143
183
|
end
|
144
184
|
|
145
185
|
specify "should support instance attributes" do
|
146
186
|
@abc = 123
|
147
|
-
proc {:x == @abc}.
|
187
|
+
proc {:x == @abc}.sql.should == "(x = 123)"
|
148
188
|
end
|
149
189
|
|
150
190
|
specify "should support class attributes" do
|
151
191
|
@@abc = 321
|
152
|
-
proc {:x == @@abc}.
|
192
|
+
proc {:x == @@abc}.sql.should == "(x = 321)"
|
153
193
|
end
|
154
194
|
|
155
195
|
specify "should support like? pattern" do
|
156
|
-
proc {:x.like? '%abc'}.
|
196
|
+
proc {:x.like? '%abc'}.sql.should == "(x LIKE '%abc')"
|
157
197
|
end
|
158
198
|
|
159
199
|
specify "should support =~ operator" do
|
160
200
|
# stock SQL version does not know about regexps
|
161
|
-
proc {:x =~ '123'}.
|
201
|
+
proc {:x =~ '123'}.sql.should == "(x LIKE '123')"
|
162
202
|
|
163
|
-
proc {:x =~ /^123/}.
|
203
|
+
proc {:x =~ /^123/}.sql.should == "(x ~ '^123')"
|
164
204
|
end
|
165
205
|
|
166
206
|
specify "should raise on =~ operator for unsupported types" do
|
167
|
-
proc {proc {:x =~ 123}.
|
207
|
+
proc {proc {:x =~ 123}.sql}.should raise_error(Sequel::Error)
|
168
208
|
end
|
169
209
|
|
170
210
|
specify "should support != operator" do
|
171
|
-
proc {:x != 100}.
|
211
|
+
proc {:x != 100}.sql.should == "(NOT (x = 100))"
|
172
212
|
end
|
173
213
|
|
174
214
|
specify "should support !~ operator" do
|
175
|
-
proc {:x !~ '123'}.
|
215
|
+
proc {:x !~ '123'}.sql.should == "(NOT (x LIKE '123'))"
|
176
216
|
end
|
177
217
|
|
178
218
|
specify "should support ! operator" do
|
179
|
-
proc {!:x}.
|
180
|
-
proc {!(:x > 100)}.
|
219
|
+
proc {!:x}.sql.should == "(x = 'f')"
|
220
|
+
proc {!(:x > 100)}.sql.should == "(NOT (x > 100))"
|
181
221
|
end
|
182
222
|
|
183
223
|
specify "should support && operator" do
|
184
|
-
proc {1 && 2}.
|
185
|
-
proc {:x > 100 && :y < 100}.
|
186
|
-
proc {:x && :y && :z}.
|
224
|
+
proc {1 && 2}.sql.should == "(1 AND 2)"
|
225
|
+
proc {:x > 100 && :y < 100}.sql.should == "((x > 100) AND (y < 100))"
|
226
|
+
proc {:x && :y && :z}.sql.should == "(x AND (y AND z))"
|
187
227
|
end
|
188
228
|
|
189
229
|
specify "should support << operator for assignment" do
|
190
|
-
proc {:x << 1}.
|
230
|
+
proc {:x << 1}.sql.should == "x = 1"
|
191
231
|
end
|
192
232
|
|
193
233
|
specify "should concatenate separate statements using AND" do
|
194
|
-
proc {:x == 20; :y == 30}.
|
195
|
-
proc {:x != 1; :y != 2; :z != 3}.
|
234
|
+
proc {:x == 20; :y == 30}.sql.should == "((x = 20) AND (y = 30))"
|
235
|
+
proc {:x != 1; :y != 2; :z != 3}.sql.should == \
|
196
236
|
"((NOT (x = 1)) AND (NOT (y = 2)) AND (NOT (z = 3)))"
|
197
237
|
end
|
198
238
|
|
199
239
|
specify "should concatenate separate statements using custom join argument" do
|
200
|
-
proc {:x << 20; :y << 30}.
|
240
|
+
proc {:x << 20; :y << 30}.sql_comma_separated.should == "x = 20, y = 30"
|
201
241
|
z = 333
|
202
|
-
proc {:x << :x + 1; :y << z}.
|
242
|
+
proc {:x << :x + 1; :y << z}.sql_comma_separated.should == "x = (x + 1), y = 333"
|
203
243
|
end
|
204
244
|
|
205
245
|
specify "should support || operator" do
|
206
|
-
proc {1 || 2}.
|
207
|
-
proc {:x > 100 || :y < 100}.
|
208
|
-
proc {:x || :y || :z}.
|
246
|
+
proc {1 || 2}.sql.should == "(1 OR 2)"
|
247
|
+
proc {:x > 100 || :y < 100}.sql.should == "((x > 100) OR (y < 100))"
|
248
|
+
proc {:x || :y || :z}.sql.should == "(x OR (y OR z))"
|
209
249
|
end
|
210
250
|
|
211
251
|
specify "should support operator combinations" do
|
212
|
-
proc {(:x > 1 || :y > 2) && (:z > 3)}.
|
213
|
-
proc {(1 && 2) || (3 || 4)}.
|
214
|
-
proc {(:x != 2) || (:y == 3) || !(:z == 4)}.
|
252
|
+
proc {(:x > 1 || :y > 2) && (:z > 3)}.sql.should == "(((x > 1) OR (y > 2)) AND (z > 3))"
|
253
|
+
proc {(1 && 2) || (3 || 4)}.sql.should == "((1 AND 2) OR (3 OR 4))"
|
254
|
+
proc {(:x != 2) || (:y == 3) || !(:z == 4)}.sql.should == \
|
215
255
|
"((NOT (x = 2)) OR ((y = 3) OR (NOT (z = 4))))"
|
216
256
|
end
|
217
257
|
|
218
258
|
specify "should support late bound column references" do
|
219
259
|
def abc; :tttt; end
|
220
|
-
proc {abc > 2}.
|
260
|
+
proc {abc > 2}.sql.should == "(tttt > 2)"
|
221
261
|
end
|
222
262
|
|
223
263
|
specify "should support qualified column references" do
|
224
|
-
proc {:x__y > 3}.
|
264
|
+
proc {:x__y > 3}.sql.should == "(x.y > 3)"
|
225
265
|
end
|
226
266
|
|
227
267
|
specify "should support functions on columns" do
|
228
|
-
proc {:x.MAX > 100}.
|
229
|
-
proc {:x.COUNT > 100}.
|
268
|
+
proc {:x.MAX > 100}.sql.should == "(max(x) > 100)"
|
269
|
+
proc {:x.COUNT > 100}.sql.should == "(count(x) > 100)"
|
230
270
|
end
|
231
271
|
|
232
272
|
specify "should support SQL functions" do
|
233
|
-
proc {:MAX[:x] > 100}.
|
273
|
+
proc {:MAX[:x] > 100}.sql.should == "(MAX(x) > 100)"
|
234
274
|
|
235
|
-
proc {:MAX[:x__y] > 100}.
|
275
|
+
proc {:MAX[:x__y] > 100}.sql.should == "(MAX(x.y) > 100)"
|
236
276
|
end
|
237
277
|
|
238
278
|
specify "should support SQL functions with multiple arguments" do
|
239
|
-
proc {:sum[1, 2, 3] > 100}.
|
279
|
+
proc {:sum[1, 2, 3] > 100}.sql.should == "(sum(1, 2, 3) > 100)"
|
240
280
|
|
241
|
-
proc {:x[1, DB[:y].select(:z), "a'b"] > 100}.
|
281
|
+
proc {:x[1, DB[:y].select(:z), "a'b"] > 100}.sql.should == \
|
242
282
|
"(x(1, (SELECT z FROM y), 'a''b') > 100)"
|
243
283
|
end
|
244
284
|
|
245
285
|
specify "should support SQL functions without arguments" do
|
246
|
-
proc {:abc[] > 100}.
|
286
|
+
proc {:abc[] > 100}.sql.should == "(abc() > 100)"
|
247
287
|
|
248
|
-
proc {:now[] - :last_stamp > 100}.
|
288
|
+
proc {:now[] - :last_stamp > 100}.sql.should == \
|
249
289
|
"((now() - last_stamp) > 100)"
|
250
290
|
end
|
251
291
|
|
252
292
|
specify "should do stuff like..." do
|
253
|
-
proc {:price < 100 || :category != 'ruby'}.
|
293
|
+
proc {:price < 100 || :category != 'ruby'}.sql.should == \
|
254
294
|
"((price < 100) OR (NOT (category = 'ruby')))"
|
255
295
|
t = Time.now
|
256
|
-
proc {:node_id == 1 && :stamp < t}.
|
296
|
+
proc {:node_id == 1 && :stamp < t}.sql.should == \
|
257
297
|
"((node_id = 1) AND (stamp < #{DS.literal(t)}))"
|
258
298
|
|
259
|
-
proc {1 < :x}.
|
299
|
+
proc {1 < :x}.sql.should == "(1 < x)"
|
260
300
|
end
|
261
301
|
|
262
302
|
specify "should complain if someone is crazy" do
|
263
|
-
proc {proc {def x; 1; end}.
|
303
|
+
proc {proc {def x; 1; end}.sql}.should raise_error(Sequel::Error::InvalidExpression)
|
264
304
|
a = 1
|
265
|
-
proc {proc {a = 1}.
|
305
|
+
proc {proc {a = 1}.sql}.should raise_error(Sequel::Error::InvalidExpression)
|
266
306
|
end
|
267
307
|
|
268
308
|
specify "should support comparison to Range objects" do
|
269
|
-
proc {:x == (1..10)}.
|
309
|
+
proc {:x == (1..10)}.sql.should == \
|
270
310
|
"(x >= 1 AND x <= 10)"
|
271
311
|
|
272
|
-
proc {:x == (1...10)}.
|
312
|
+
proc {:x == (1...10)}.sql.should == \
|
273
313
|
"(x >= 1 AND x < 10)"
|
274
314
|
|
275
315
|
a, b = 3, 5
|
276
|
-
proc {:x == (a..b)}.
|
316
|
+
proc {:x == (a..b)}.sql.should == \
|
277
317
|
"(x >= 3 AND x <= 5)"
|
278
318
|
|
279
|
-
proc {:x == (a...b)}.
|
319
|
+
proc {:x == (a...b)}.sql.should == \
|
280
320
|
"(x >= 3 AND x < 5)"
|
281
321
|
|
282
322
|
t1 = Time.now - 4000
|
283
323
|
t2 = Time.now - 2000
|
284
324
|
|
285
|
-
proc {:stamp == (t1..t2)}.
|
325
|
+
proc {:stamp == (t1..t2)}.sql.should == \
|
286
326
|
"(stamp >= #{DS.literal(t1)} AND stamp <= #{DS.literal(t2)})"
|
287
327
|
end
|
288
328
|
|
289
329
|
specify "should support comparison to sub-queries" do
|
290
330
|
@ds2 = DB[:test].select(:node_id)
|
291
331
|
|
292
|
-
proc {:id == @ds2}.
|
332
|
+
proc {:id == @ds2}.sql.should == \
|
293
333
|
"(id IN (SELECT node_id FROM test))"
|
294
334
|
|
295
|
-
proc {:id == DB[:test].select(:node_id)}.
|
335
|
+
proc {:id == DB[:test].select(:node_id)}.sql.should == \
|
296
336
|
"(id IN (SELECT node_id FROM test))"
|
297
337
|
|
298
|
-
proc {:id == DB[:test].select(:node_id).filter {:active == true}}.
|
338
|
+
proc {:id == DB[:test].select(:node_id).filter {:active == true}}.sql.should == \
|
299
339
|
"(id IN (SELECT node_id FROM test WHERE (active = 't')))"
|
300
340
|
|
301
|
-
proc {:price >= DB[:items].select(:price)}.
|
341
|
+
proc {:price >= DB[:items].select(:price)}.sql.should == \
|
302
342
|
"(price >= (SELECT price FROM items))"
|
303
343
|
end
|
304
344
|
|
305
345
|
specify "should support comparison to arrays" do
|
306
|
-
proc {:id == [1, 3, 7, 15]}.
|
346
|
+
proc {:id == [1, 3, 7, 15]}.sql.should == \
|
307
347
|
"(id IN (1, 3, 7, 15))"
|
308
348
|
end
|
309
349
|
|
310
350
|
specify "should not literalize String#expr and String#lit" do
|
311
|
-
proc {'x'.lit == 1}.
|
312
|
-
proc {'x.y'.expr == 1}.
|
351
|
+
proc {'x'.lit == 1}.sql.should == "(x = 1)"
|
352
|
+
proc {'x.y'.expr == 1}.sql.should == "(x.y = 1)"
|
313
353
|
end
|
314
354
|
|
315
355
|
specify "should support in/in? operator" do
|
316
|
-
proc {:x.in [3, 4, 5]}.
|
317
|
-
proc {:x.in?(3, 4, 5)}.
|
356
|
+
proc {:x.in [3, 4, 5]}.sql.should == "(x IN (3, 4, 5))"
|
357
|
+
proc {:x.in?(3, 4, 5)}.sql.should == "(x IN (3, 4, 5))"
|
318
358
|
|
319
|
-
proc {:x.in(1..10)}.
|
320
|
-
proc {:x.in?(1..10)}.
|
359
|
+
proc {:x.in(1..10)}.sql.should == "(x >= 1 AND x <= 10)"
|
360
|
+
proc {:x.in?(1..10)}.sql.should == "(x >= 1 AND x <= 10)"
|
321
361
|
|
322
362
|
@ds2 = DB[:test].select(:node_id)
|
323
|
-
proc {:x.in @ds2}.
|
363
|
+
proc {:x.in @ds2}.sql.should == "(x IN (SELECT node_id FROM test))"
|
324
364
|
end
|
325
365
|
|
326
366
|
specify "should support nested procs" do
|
327
|
-
proc {:x > 10 || proc{:y > 20}}.
|
367
|
+
proc {:x > 10 || proc{:y > 20}}.sql.should == \
|
328
368
|
"((x > 10) OR (y > 20))"
|
329
369
|
|
330
370
|
def pr(&block)
|
331
371
|
proc {:x > 10 || block}
|
332
372
|
end
|
333
373
|
|
334
|
-
pr {:y > 20}.
|
374
|
+
pr {:y > 20}.sql.should == \
|
335
375
|
"((x > 10) OR (y > 20))"
|
336
376
|
end
|
337
377
|
|
@@ -345,7 +385,7 @@ context "Proc#to_sql" do
|
|
345
385
|
(p|idx) << (p|idx) + v
|
346
386
|
end
|
347
387
|
end
|
348
|
-
pr.
|
388
|
+
pr.sql_comma_separated.should == \
|
349
389
|
"day[1] = (day[1] + 2), week[1] = (week[1] + 2), month[1] = (month[1] + 2), year[1] = (year[1] + 2), alltime[1] = (alltime[1] + 2)"
|
350
390
|
end
|
351
391
|
|
@@ -357,12 +397,12 @@ context "Proc#to_sql" do
|
|
357
397
|
k << k + v
|
358
398
|
end
|
359
399
|
end
|
360
|
-
pr.
|
400
|
+
pr.sql_comma_separated.should == "month = (month + 3)"
|
361
401
|
end
|
362
402
|
|
363
403
|
specify "should support local arguments" do
|
364
404
|
def t(x)
|
365
|
-
proc {x > 10}.
|
405
|
+
proc {x > 10}.sql
|
366
406
|
end
|
367
407
|
t(:y).should == "(y > 10)"
|
368
408
|
end
|
@@ -370,69 +410,69 @@ context "Proc#to_sql" do
|
|
370
410
|
specify "should support binary operators on local context" do
|
371
411
|
XXX = 1
|
372
412
|
YYY = 2
|
373
|
-
proc {XXX || YYY}.
|
413
|
+
proc {XXX || YYY}.sql.should == "(1 OR 2)"
|
374
414
|
|
375
415
|
xxx = 1
|
376
416
|
yyy = 2
|
377
|
-
proc {xxx && yyy}.
|
417
|
+
proc {xxx && yyy}.sql.should == "(1 AND 2)"
|
378
418
|
end
|
379
419
|
|
380
420
|
specify "should support arithmetics" do
|
381
421
|
zzz = 300
|
382
|
-
proc {(:x + 100) > zzz}.
|
422
|
+
proc {(:x + 100) > zzz}.sql.should == "((x + 100) > 300)"
|
383
423
|
|
384
|
-
proc {(:x + :y * 100) > zzz}.
|
424
|
+
proc {(:x + :y * 100) > zzz}.sql.should == "((x + (y * 100)) > 300)"
|
385
425
|
|
386
|
-
proc {:units * :price}.
|
426
|
+
proc {:units * :price}.sql.should == "(units * price)"
|
387
427
|
end
|
388
428
|
|
389
429
|
specify "should support | operator" do
|
390
|
-
proc {(:x | 1) > 0}.
|
391
|
-
proc {10 | 1}.
|
430
|
+
proc {(:x | 1) > 0}.sql.should == "(x[1] > 0)"
|
431
|
+
proc {10 | 1}.sql.should == 11
|
392
432
|
end
|
393
433
|
|
394
434
|
specify "should support globals" do
|
395
435
|
$aaaa_zzzz = 400
|
396
|
-
proc {:x > $aaaa_zzzz}.
|
436
|
+
proc {:x > $aaaa_zzzz}.sql.should == "(x > 400)"
|
397
437
|
end
|
398
438
|
|
399
439
|
specify "should support Regexp macros" do
|
400
440
|
"abc" =~ /(ab)/
|
401
|
-
proc {:x == $1}.
|
441
|
+
proc {:x == $1}.sql.should == "(x = 'ab')"
|
402
442
|
end
|
403
443
|
|
404
444
|
specify "should evaluate expression not referring to symbols or literal strings." do
|
405
|
-
proc {:x > 2 * 3}.
|
445
|
+
proc {:x > 2 * 3}.sql.should == "(x > 6)"
|
406
446
|
y = 3
|
407
|
-
proc {:x > y * 4}.
|
447
|
+
proc {:x > y * 4}.sql.should == "(x > 12)"
|
408
448
|
|
409
|
-
proc {:AVG[:x] > 4}.
|
449
|
+
proc {:AVG[:x] > 4}.sql.should == "(AVG(x) > 4)"
|
410
450
|
|
411
|
-
proc {:AVG[:x] > 4}.
|
451
|
+
proc {:AVG[:x] > 4}.sql.should == "(AVG(x) > 4)"
|
412
452
|
|
413
|
-
proc {:y == (1 > 2)}.
|
453
|
+
proc {:y == (1 > 2)}.sql.should == "(y = 'f')"
|
414
454
|
end
|
415
455
|
|
416
456
|
specify "should support ternary operator" do
|
417
457
|
y = true
|
418
|
-
proc {:x > (y ? 1 : 2)}.
|
458
|
+
proc {:x > (y ? 1 : 2)}.sql.should == "(x > 1)"
|
419
459
|
|
420
|
-
proc {((1 > 2) ? :x : :y) > 3}.
|
460
|
+
proc {((1 > 2) ? :x : :y) > 3}.sql.should == "(y > 3)"
|
421
461
|
end
|
422
462
|
|
423
463
|
specify "should support strings with embedded Ruby code in them and literalize them" do
|
424
|
-
proc {:n == "#{1+2}"}.
|
464
|
+
proc {:n == "#{1+2}"}.sql.should == "(n = '3')"
|
425
465
|
|
426
466
|
y = "12'34"
|
427
467
|
|
428
|
-
proc {:x > "#{y}"}.
|
468
|
+
proc {:x > "#{y}"}.sql.should == "(x > '12''34')"
|
429
469
|
end
|
430
470
|
|
431
471
|
specify "should support format strings and literalize the result" do
|
432
472
|
prod = 1
|
433
|
-
proc {:x == "abc%d" % prod}.
|
473
|
+
proc {:x == "abc%d" % prod}.sql.should == "(x = 'abc1')"
|
434
474
|
|
435
|
-
proc {:x == ("%d" % prod).lit}.
|
475
|
+
proc {:x == ("%d" % prod).lit}.sql.should == "(x = 1)"
|
436
476
|
end
|
437
477
|
end
|
438
478
|
|
@@ -442,7 +482,7 @@ context "Proc#to_sql stock" do
|
|
442
482
|
ds = db[:items]
|
443
483
|
|
444
484
|
p = proc {:x =~ /abc/}
|
445
|
-
proc {
|
485
|
+
proc {p.to_sql(ds)}.should raise_error(Sequel::Error)
|
446
486
|
end
|
447
487
|
end
|
448
488
|
|