sequel_core 1.4.0 → 1.5.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/CHANGELOG +74 -0
- data/COPYING +1 -0
- data/README +17 -6
- data/Rakefile +16 -21
- data/lib/sequel_core.rb +18 -28
- data/lib/sequel_core/adapters/ado.rb +3 -15
- data/lib/sequel_core/adapters/dbi.rb +1 -14
- data/lib/sequel_core/adapters/informix.rb +3 -3
- data/lib/sequel_core/adapters/jdbc.rb +2 -2
- data/lib/sequel_core/adapters/mysql.rb +39 -59
- data/lib/sequel_core/adapters/odbc.rb +18 -38
- data/lib/sequel_core/adapters/openbase.rb +1 -17
- data/lib/sequel_core/adapters/oracle.rb +1 -19
- data/lib/sequel_core/adapters/postgres.rb +20 -60
- data/lib/sequel_core/adapters/sqlite.rb +4 -8
- data/lib/sequel_core/connection_pool.rb +150 -0
- data/lib/sequel_core/core_ext.rb +41 -0
- data/lib/sequel_core/core_sql.rb +35 -38
- data/lib/sequel_core/database.rb +20 -17
- data/lib/sequel_core/dataset.rb +49 -80
- data/lib/sequel_core/dataset/callback.rb +11 -13
- data/lib/sequel_core/dataset/convenience.rb +18 -136
- data/lib/sequel_core/dataset/pagination.rb +81 -0
- data/lib/sequel_core/dataset/sequelizer.rb +5 -4
- data/lib/sequel_core/dataset/sql.rb +43 -33
- data/lib/sequel_core/deprecated.rb +200 -0
- data/lib/sequel_core/exceptions.rb +0 -14
- data/lib/sequel_core/object_graph.rb +199 -0
- data/lib/sequel_core/pretty_table.rb +27 -24
- data/lib/sequel_core/schema/generator.rb +16 -4
- data/lib/sequel_core/schema/sql.rb +5 -3
- data/lib/sequel_core/worker.rb +1 -1
- data/spec/adapters/informix_spec.rb +1 -47
- data/spec/adapters/mysql_spec.rb +85 -54
- data/spec/adapters/oracle_spec.rb +1 -57
- data/spec/adapters/postgres_spec.rb +66 -49
- data/spec/adapters/sqlite_spec.rb +4 -29
- data/spec/connection_pool_spec.rb +358 -0
- data/spec/core_sql_spec.rb +24 -19
- data/spec/database_spec.rb +13 -9
- data/spec/dataset_spec.rb +59 -78
- data/spec/object_graph_spec.rb +202 -0
- data/spec/pretty_table_spec.rb +1 -9
- data/spec/schema_generator_spec.rb +7 -1
- data/spec/schema_spec.rb +27 -0
- data/spec/sequelizer_spec.rb +2 -2
- data/spec/spec_helper.rb +4 -2
- metadata +16 -57
- data/lib/sequel_core/array_keys.rb +0 -322
- data/lib/sequel_core/model.rb +0 -8
- data/spec/array_keys_spec.rb +0 -682
@@ -2,7 +2,7 @@ require File.join(File.dirname(__FILE__), '../../lib/sequel_core')
|
|
2
2
|
require File.join(File.dirname(__FILE__), '../spec_helper.rb')
|
3
3
|
|
4
4
|
unless defined?(SQLITE_DB)
|
5
|
-
SQLITE_DB = Sequel('sqlite:/')
|
5
|
+
SQLITE_DB = Sequel.connect('sqlite:/')
|
6
6
|
end
|
7
7
|
|
8
8
|
SQLITE_DB.create_table :items do
|
@@ -18,7 +18,7 @@ SQLITE_DB.create_table(:time) {timestamp :t}
|
|
18
18
|
|
19
19
|
context "An SQLite database" do
|
20
20
|
setup do
|
21
|
-
@db = Sequel('sqlite:/')
|
21
|
+
@db = Sequel.connect('sqlite:/')
|
22
22
|
end
|
23
23
|
|
24
24
|
specify "should provide a list of existing tables" do
|
@@ -98,7 +98,7 @@ context "An SQLite database" do
|
|
98
98
|
|
99
99
|
proc {@db.transaction do
|
100
100
|
@db.create_table(:v) {text :name}
|
101
|
-
|
101
|
+
raise Sequel::Error::Rollback
|
102
102
|
end}.should_not raise_error
|
103
103
|
# no commit
|
104
104
|
@db.tables.should == [:t]
|
@@ -116,7 +116,7 @@ context "An SQLite database" do
|
|
116
116
|
proc {@db.transaction do
|
117
117
|
@db.create_table(:v) {text :name}
|
118
118
|
@db.transaction do
|
119
|
-
|
119
|
+
raise Sequel::Error::Rollback # should roll back the top-level transaction
|
120
120
|
end
|
121
121
|
end}.should_not raise_error
|
122
122
|
# no commit
|
@@ -288,31 +288,6 @@ context "SQLite::Dataset#update" do
|
|
288
288
|
end
|
289
289
|
end
|
290
290
|
|
291
|
-
context "An SQLite dataset in array tuples mode" do
|
292
|
-
setup do
|
293
|
-
@d = SQLITE_DB[:items]
|
294
|
-
@d.delete # remove all records
|
295
|
-
|
296
|
-
Sequel.use_array_tuples
|
297
|
-
end
|
298
|
-
|
299
|
-
teardown do
|
300
|
-
Sequel.use_hash_tuples
|
301
|
-
end
|
302
|
-
|
303
|
-
specify "should return the correct records" do
|
304
|
-
@d.to_a.should == []
|
305
|
-
@d << {:name => 'abc', :value => 1.23}
|
306
|
-
@d << {:name => 'abc', :value => 4.56}
|
307
|
-
@d << {:name => 'def', :value => 7.89}
|
308
|
-
@d.select(:name, :value).to_a.sort_by {|h| h[:value]}.should == [
|
309
|
-
['abc', 1.23],
|
310
|
-
['abc', 4.56],
|
311
|
-
['def', 7.89]
|
312
|
-
]
|
313
|
-
end
|
314
|
-
end
|
315
|
-
|
316
291
|
context "SQLite dataset" do
|
317
292
|
setup do
|
318
293
|
SQLITE_DB.create_table :test do
|
@@ -0,0 +1,358 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
context "An empty ConnectionPool" do
|
4
|
+
setup do
|
5
|
+
@cpool = ConnectionPool.new
|
6
|
+
end
|
7
|
+
|
8
|
+
specify "should have no available connections" do
|
9
|
+
@cpool.available_connections.should == []
|
10
|
+
end
|
11
|
+
|
12
|
+
specify "should have no allocated connections" do
|
13
|
+
@cpool.allocated.should == {}
|
14
|
+
end
|
15
|
+
|
16
|
+
specify "should have a created_count of zero" do
|
17
|
+
@cpool.created_count.should == 0
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "A connection pool handling connections" do
|
22
|
+
setup do
|
23
|
+
@max_size = 2
|
24
|
+
@cpool = ConnectionPool.new(@max_size) {:got_connection}
|
25
|
+
end
|
26
|
+
|
27
|
+
specify "#hold should increment #created_count" do
|
28
|
+
@cpool.hold do
|
29
|
+
@cpool.created_count.should == 1
|
30
|
+
@cpool.hold {@cpool.created_count.should == 1}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
specify "#hold should add the connection to the #allocated hash" do
|
35
|
+
@cpool.hold do
|
36
|
+
@cpool.allocated.size.should == 1
|
37
|
+
|
38
|
+
@cpool.allocated.values.should == [:got_connection]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
specify "#hold should yield a new connection" do
|
43
|
+
@cpool.hold {|conn| conn.should == :got_connection}
|
44
|
+
end
|
45
|
+
|
46
|
+
specify "a connection should be de-allocated after it has been used in #hold" do
|
47
|
+
@cpool.hold {}
|
48
|
+
@cpool.allocated.size.should == 0
|
49
|
+
end
|
50
|
+
|
51
|
+
specify "#hold should return the value of its block" do
|
52
|
+
@cpool.hold {:block_return}.should == :block_return
|
53
|
+
end
|
54
|
+
|
55
|
+
specify "#make_new should not make more than max_size connections" do
|
56
|
+
@cpool.send(:make_new).should == :got_connection
|
57
|
+
@cpool.send(:make_new).should == :got_connection
|
58
|
+
@cpool.send(:make_new).should == nil
|
59
|
+
@cpool.created_count.should == 2
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class DummyConnection
|
64
|
+
@@value = 0
|
65
|
+
def initialize
|
66
|
+
@@value += 1
|
67
|
+
end
|
68
|
+
|
69
|
+
def value
|
70
|
+
@@value
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context "ConnectionPool#hold" do
|
75
|
+
setup do
|
76
|
+
@pool = ConnectionPool.new {DummyConnection.new}
|
77
|
+
end
|
78
|
+
|
79
|
+
specify "should pass the result of the connection maker proc to the supplied block" do
|
80
|
+
res = nil
|
81
|
+
@pool.hold {|c| res = c}
|
82
|
+
res.should be_a_kind_of(DummyConnection)
|
83
|
+
res.value.should == 1
|
84
|
+
@pool.hold {|c| res = c}
|
85
|
+
res.should be_a_kind_of(DummyConnection)
|
86
|
+
res.value.should == 1 # the connection maker is invoked only once
|
87
|
+
end
|
88
|
+
|
89
|
+
specify "should be re-entrant by the same thread" do
|
90
|
+
cc = nil
|
91
|
+
@pool.hold {|c| @pool.hold {|c| @pool.hold {|c| cc = c}}}
|
92
|
+
cc.should be_a_kind_of(DummyConnection)
|
93
|
+
end
|
94
|
+
|
95
|
+
specify "should catch exceptions and reraise them" do
|
96
|
+
proc {@pool.hold {|c| c.foobar}}.should raise_error(NoMethodError)
|
97
|
+
end
|
98
|
+
|
99
|
+
specify "should handle Exception errors (normally not caught by rescue)" do
|
100
|
+
err = nil
|
101
|
+
begin
|
102
|
+
@pool.hold {raise Exception}
|
103
|
+
rescue => e
|
104
|
+
err = e
|
105
|
+
end
|
106
|
+
err.should be_a_kind_of(RuntimeError)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context "ConnectionPool#connection_proc" do
|
111
|
+
setup do
|
112
|
+
@pool = ConnectionPool.new
|
113
|
+
end
|
114
|
+
|
115
|
+
specify "should be nil if no block is supplied to the pool" do
|
116
|
+
@pool.connection_proc.should be_nil
|
117
|
+
proc {@pool.hold {}}.should raise_error
|
118
|
+
end
|
119
|
+
|
120
|
+
specify "should be mutable" do
|
121
|
+
@pool.connection_proc = proc {'herro'}
|
122
|
+
res = nil
|
123
|
+
proc {@pool.hold {|c| res = c}}.should_not raise_error
|
124
|
+
res.should == 'herro'
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
context "A connection pool with a max size of 1" do
|
129
|
+
setup do
|
130
|
+
@invoked_count = 0
|
131
|
+
@pool = ConnectionPool.new(1) {@invoked_count += 1; 'herro'}
|
132
|
+
end
|
133
|
+
|
134
|
+
specify "should let only one thread access the connection at any time" do
|
135
|
+
cc,c1, c2 = nil
|
136
|
+
|
137
|
+
t1 = Thread.new {@pool.hold {|c| cc = c; c1 = c.dup; while c == 'herro';sleep 0.1;end}}
|
138
|
+
sleep 0.2
|
139
|
+
cc.should == 'herro'
|
140
|
+
c1.should == 'herro'
|
141
|
+
|
142
|
+
t2 = Thread.new {@pool.hold {|c| c2 = c.dup; while c == 'hello';sleep 0.1;end}}
|
143
|
+
sleep 0.2
|
144
|
+
|
145
|
+
# connection held by t1
|
146
|
+
t1.should be_alive
|
147
|
+
t2.should be_alive
|
148
|
+
|
149
|
+
cc.should == 'herro'
|
150
|
+
c1.should == 'herro'
|
151
|
+
c2.should be_nil
|
152
|
+
|
153
|
+
@pool.available_connections.should be_empty
|
154
|
+
@pool.allocated.should == {t1 => cc}
|
155
|
+
|
156
|
+
cc.gsub!('rr', 'll')
|
157
|
+
sleep 0.5
|
158
|
+
|
159
|
+
# connection held by t2
|
160
|
+
t1.should_not be_alive
|
161
|
+
t2.should be_alive
|
162
|
+
|
163
|
+
c2.should == 'hello'
|
164
|
+
|
165
|
+
@pool.available_connections.should be_empty
|
166
|
+
@pool.allocated.should == {t2 => cc}
|
167
|
+
|
168
|
+
cc.gsub!('ll', 'rr')
|
169
|
+
sleep 0.5
|
170
|
+
|
171
|
+
#connection released
|
172
|
+
t2.should_not be_alive
|
173
|
+
|
174
|
+
cc.should == 'herro'
|
175
|
+
|
176
|
+
@invoked_count.should == 1
|
177
|
+
@pool.size.should == 1
|
178
|
+
@pool.available_connections.should == [cc]
|
179
|
+
@pool.allocated.should be_empty
|
180
|
+
end
|
181
|
+
|
182
|
+
specify "should let the same thread reenter #hold" do
|
183
|
+
c1, c2, c3 = nil
|
184
|
+
@pool.hold do |c|
|
185
|
+
c1 = c
|
186
|
+
@pool.hold do |c|
|
187
|
+
c2 = c
|
188
|
+
@pool.hold do |c|
|
189
|
+
c3 = c
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
c1.should == 'herro'
|
194
|
+
c2.should == 'herro'
|
195
|
+
c3.should == 'herro'
|
196
|
+
|
197
|
+
@invoked_count.should == 1
|
198
|
+
@pool.size.should == 1
|
199
|
+
@pool.available_connections.size.should == 1
|
200
|
+
@pool.allocated.should be_empty
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
context "A connection pool with a max size of 5" do
|
205
|
+
setup do
|
206
|
+
@invoked_count = 0
|
207
|
+
@pool = ConnectionPool.new(5) {@invoked_count += 1}
|
208
|
+
end
|
209
|
+
|
210
|
+
specify "should let five threads simultaneously access separate connections" do
|
211
|
+
cc = {}
|
212
|
+
threads = []
|
213
|
+
stop = nil
|
214
|
+
|
215
|
+
5.times {|i| threads << Thread.new {@pool.hold {|c| cc[i] = c; while !stop;sleep 0.1;end}}; sleep 0.1}
|
216
|
+
sleep 0.2
|
217
|
+
threads.each {|t| t.should be_alive}
|
218
|
+
cc.size.should == 5
|
219
|
+
@invoked_count.should == 5
|
220
|
+
@pool.size.should == 5
|
221
|
+
@pool.available_connections.should be_empty
|
222
|
+
@pool.allocated.should == {threads[0] => 1, threads[1] => 2, threads[2] => 3,
|
223
|
+
threads[3] => 4, threads[4] => 5}
|
224
|
+
|
225
|
+
threads[0].raise "your'e dead"
|
226
|
+
sleep 0.1
|
227
|
+
threads[3].raise "your'e dead too"
|
228
|
+
|
229
|
+
sleep 0.1
|
230
|
+
|
231
|
+
@pool.available_connections.should == [1, 4]
|
232
|
+
@pool.allocated.should == {threads[1] => 2, threads[2] => 3, threads[4] => 5}
|
233
|
+
|
234
|
+
stop = true
|
235
|
+
sleep 0.2
|
236
|
+
|
237
|
+
@pool.available_connections.size.should == 5
|
238
|
+
@pool.allocated.should be_empty
|
239
|
+
end
|
240
|
+
|
241
|
+
specify "should block threads until a connection becomes available" do
|
242
|
+
cc = {}
|
243
|
+
threads = []
|
244
|
+
stop = nil
|
245
|
+
|
246
|
+
5.times {|i| threads << Thread.new {@pool.hold {|c| cc[i] = c; while !stop;sleep 0.1;end}}; sleep 0.1}
|
247
|
+
sleep 0.2
|
248
|
+
threads.each {|t| t.should be_alive}
|
249
|
+
@pool.available_connections.should be_empty
|
250
|
+
|
251
|
+
3.times {|i| threads << Thread.new {@pool.hold {|c| cc[i + 5] = c}}}
|
252
|
+
|
253
|
+
sleep 0.2
|
254
|
+
threads[5].should be_alive
|
255
|
+
threads[6].should be_alive
|
256
|
+
threads[7].should be_alive
|
257
|
+
cc.size.should == 5
|
258
|
+
cc[5].should be_nil
|
259
|
+
cc[6].should be_nil
|
260
|
+
cc[7].should be_nil
|
261
|
+
|
262
|
+
stop = true
|
263
|
+
sleep 0.3
|
264
|
+
|
265
|
+
threads.each {|t| t.should_not be_alive}
|
266
|
+
|
267
|
+
@pool.size.should == 5
|
268
|
+
@invoked_count.should == 5
|
269
|
+
@pool.available_connections.size.should == 5
|
270
|
+
@pool.allocated.should be_empty
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
context "ConnectionPool#disconnect" do
|
275
|
+
setup do
|
276
|
+
@count = 0
|
277
|
+
@pool = ConnectionPool.new(5) {{:id => @count += 1}}
|
278
|
+
end
|
279
|
+
|
280
|
+
specify "should invoke the given block for each available connection" do
|
281
|
+
threads = []
|
282
|
+
stop = nil
|
283
|
+
5.times {|i| threads << Thread.new {@pool.hold {|c| while !stop;sleep 0.1;end}}; sleep 0.1}
|
284
|
+
while @pool.size < 5
|
285
|
+
sleep 0.2
|
286
|
+
end
|
287
|
+
stop = true
|
288
|
+
sleep 1
|
289
|
+
threads.each {|t| t.join}
|
290
|
+
|
291
|
+
@pool.size.should == 5
|
292
|
+
@pool.available_connections.size.should == 5
|
293
|
+
@pool.available_connections.each {|c| c[:id].should_not be_nil}
|
294
|
+
conns = []
|
295
|
+
@pool.disconnect {|c| conns << c}
|
296
|
+
conns.size.should == 5
|
297
|
+
end
|
298
|
+
|
299
|
+
specify "should remove all available connections" do
|
300
|
+
threads = []
|
301
|
+
stop = nil
|
302
|
+
5.times {|i| threads << Thread.new {@pool.hold {|c| while !stop;sleep 0.1;end}}; sleep 0.1}
|
303
|
+
while @pool.size < 5
|
304
|
+
sleep 0.2
|
305
|
+
end
|
306
|
+
stop = true
|
307
|
+
sleep 1
|
308
|
+
threads.each {|t| t.join}
|
309
|
+
|
310
|
+
@pool.size.should == 5
|
311
|
+
@pool.disconnect
|
312
|
+
@pool.size.should == 0
|
313
|
+
end
|
314
|
+
|
315
|
+
specify "should not touch connections in use" do
|
316
|
+
threads = []
|
317
|
+
stop = nil
|
318
|
+
5.times {|i| threads << Thread.new {@pool.hold {|c| while !stop;sleep 0.1;end}}; sleep 0.1}
|
319
|
+
while @pool.size < 5
|
320
|
+
sleep 0.2
|
321
|
+
end
|
322
|
+
stop = true
|
323
|
+
sleep 1
|
324
|
+
threads.each {|t| t.join}
|
325
|
+
|
326
|
+
@pool.size.should == 5
|
327
|
+
|
328
|
+
@pool.hold do |conn|
|
329
|
+
@pool.available_connections.size.should == 4
|
330
|
+
@pool.available_connections.each {|c| c.should_not be(conn)}
|
331
|
+
conns = []
|
332
|
+
@pool.disconnect {|c| conns << c}
|
333
|
+
conns.size.should == 4
|
334
|
+
end
|
335
|
+
@pool.size.should == 1
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
context "SingleThreadedPool" do
|
340
|
+
setup do
|
341
|
+
@pool = SingleThreadedPool.new {1234}
|
342
|
+
end
|
343
|
+
|
344
|
+
specify "should provide a #hold method" do
|
345
|
+
conn = nil
|
346
|
+
@pool.hold {|c| conn = c}
|
347
|
+
conn.should == 1234
|
348
|
+
end
|
349
|
+
|
350
|
+
specify "should provide a #disconnect method" do
|
351
|
+
@pool.hold {|c|}
|
352
|
+
@pool.conn.should == 1234
|
353
|
+
conn = nil
|
354
|
+
@pool.disconnect {|c| conn = c}
|
355
|
+
conn.should == 1234
|
356
|
+
@pool.conn.should be_nil
|
357
|
+
end
|
358
|
+
end
|
data/spec/core_sql_spec.rb
CHANGED
@@ -86,74 +86,62 @@ context "String#split_sql" do
|
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
89
|
-
context "#
|
89
|
+
context "#desc" do
|
90
90
|
setup do
|
91
91
|
@ds = Sequel::Dataset.new(nil)
|
92
92
|
end
|
93
93
|
|
94
94
|
specify "should format a DESC clause for a column ref" do
|
95
|
-
:test.DESC.to_s(@ds).should == 'test DESC'
|
96
95
|
:test.desc.to_s(@ds).should == 'test DESC'
|
97
96
|
|
98
|
-
:items__price.DESC.to_s(@ds).should == 'items.price DESC'
|
99
97
|
:items__price.desc.to_s(@ds).should == 'items.price DESC'
|
100
98
|
end
|
101
99
|
|
102
100
|
specify "should format a DESC clause for a function" do
|
103
|
-
:avg[:test].DESC.to_s(@ds).should == 'avg(test) DESC'
|
104
101
|
:avg[:test].desc.to_s(@ds).should == 'avg(test) DESC'
|
105
102
|
end
|
106
103
|
|
107
104
|
specify "should format a DESC clause for a literal value" do
|
108
|
-
1.DESC.to_s(@ds).should == '1 DESC'
|
109
105
|
'abc'.desc.to_s(@ds).should == "'abc' DESC"
|
110
106
|
end
|
111
107
|
end
|
112
108
|
|
113
|
-
context "#
|
109
|
+
context "#asc" do
|
114
110
|
setup do
|
115
111
|
@ds = Sequel::Dataset.new(nil)
|
116
112
|
end
|
117
113
|
|
118
114
|
specify "should format a ASC clause for a column ref" do
|
119
|
-
:test.ASC.to_s(@ds).should == 'test ASC'
|
120
115
|
:test.asc.to_s(@ds).should == 'test ASC'
|
121
116
|
|
122
|
-
:items__price.ASC.to_s(@ds).should == 'items.price ASC'
|
123
117
|
:items__price.asc.to_s(@ds).should == 'items.price ASC'
|
124
118
|
end
|
125
119
|
|
126
120
|
specify "should format a ASC clause for a function" do
|
127
|
-
:avg[:test].ASC.to_s(@ds).should == 'avg(test) ASC'
|
128
121
|
:avg[:test].asc.to_s(@ds).should == 'avg(test) ASC'
|
129
122
|
end
|
130
123
|
|
131
124
|
specify "should format a ASC clause for a literal value" do
|
132
|
-
1.ASC.to_s(@ds).should == '1 ASC'
|
133
125
|
'abc'.asc.to_s(@ds).should == "'abc' ASC"
|
134
126
|
end
|
135
127
|
end
|
136
128
|
|
137
|
-
context "#
|
129
|
+
context "#as" do
|
138
130
|
setup do
|
139
131
|
@ds = Sequel::Dataset.new(nil)
|
140
132
|
end
|
141
133
|
|
142
134
|
specify "should format a AS clause for a column ref" do
|
143
|
-
:test.AS(:t).to_s(@ds).should == 'test AS t'
|
144
135
|
:test.as(:t).to_s(@ds).should == 'test AS t'
|
145
136
|
|
146
|
-
:items__price.AS(:p).to_s(@ds).should == 'items.price AS p'
|
147
137
|
:items__price.as(:p).to_s(@ds).should == 'items.price AS p'
|
148
138
|
end
|
149
139
|
|
150
140
|
specify "should format a AS clause for a function" do
|
151
|
-
:avg[:test].AS(:avg).to_s(@ds).should == 'avg(test) AS avg'
|
152
141
|
:avg[:test].as(:avg).to_s(@ds).should == 'avg(test) AS avg'
|
153
142
|
end
|
154
143
|
|
155
144
|
specify "should format a AS clause for a literal value" do
|
156
|
-
1.AS(:one).to_s(@ds).should == '1 AS one'
|
157
145
|
'abc'.as(:abc).to_s(@ds).should == "'abc' AS abc"
|
158
146
|
end
|
159
147
|
end
|
@@ -184,7 +172,7 @@ context "Column references" do
|
|
184
172
|
end
|
185
173
|
|
186
174
|
specify "should be quoted properly in ASC/DESC clauses" do
|
187
|
-
@ds.literal(:xyz.
|
175
|
+
@ds.literal(:xyz.asc).should == "`xyz` ASC"
|
188
176
|
@ds.literal(:avg[:xyz, 1].desc).should == "avg(`xyz`, 1) DESC"
|
189
177
|
end
|
190
178
|
|
@@ -194,14 +182,14 @@ context "Column references" do
|
|
194
182
|
end
|
195
183
|
end
|
196
184
|
|
197
|
-
context "Symbol
|
185
|
+
context "Symbol#*" do
|
198
186
|
setup do
|
199
187
|
@ds = Sequel::Dataset.new(nil)
|
200
188
|
end
|
201
189
|
|
202
190
|
specify "should format a qualified wildcard" do
|
203
|
-
:xyz
|
204
|
-
:abc
|
191
|
+
:xyz.*.to_s(@ds).should == 'xyz.*'
|
192
|
+
:abc.*.to_s(@ds).should == 'abc.*'
|
205
193
|
end
|
206
194
|
end
|
207
195
|
|
@@ -233,6 +221,7 @@ context "Symbol#to_column_ref" do
|
|
233
221
|
end
|
234
222
|
end
|
235
223
|
|
224
|
+
### DEPRECATED
|
236
225
|
context "Symbol" do
|
237
226
|
setup do
|
238
227
|
@ds = Sequel::Dataset.new(nil)
|
@@ -309,3 +298,19 @@ context "String#to_date" do
|
|
309
298
|
end
|
310
299
|
end
|
311
300
|
|
301
|
+
context "Sequel::SQL::Function#==" do
|
302
|
+
specify "should be true for functions with the same name and arguments, false otherwise" do
|
303
|
+
a = :date[:t]
|
304
|
+
b = :date[:t]
|
305
|
+
a.should == b
|
306
|
+
(a == b).should == true
|
307
|
+
c = :date[:c]
|
308
|
+
a.should_not == c
|
309
|
+
(a == c).should == false
|
310
|
+
d = :time[:c]
|
311
|
+
a.should_not == d
|
312
|
+
c.should_not == d
|
313
|
+
(a == d).should == false
|
314
|
+
(c == d).should == false
|
315
|
+
end
|
316
|
+
end
|