sequel 2.6.0 → 2.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +64 -0
- data/Rakefile +1 -1
- data/lib/sequel_core/adapters/jdbc.rb +6 -2
- data/lib/sequel_core/adapters/jdbc/oracle.rb +23 -0
- data/lib/sequel_core/adapters/oracle.rb +4 -77
- data/lib/sequel_core/adapters/postgres.rb +39 -26
- data/lib/sequel_core/adapters/shared/mssql.rb +0 -1
- data/lib/sequel_core/adapters/shared/mysql.rb +1 -1
- data/lib/sequel_core/adapters/shared/oracle.rb +82 -0
- data/lib/sequel_core/adapters/shared/postgres.rb +65 -46
- data/lib/sequel_core/core_ext.rb +10 -0
- data/lib/sequel_core/core_sql.rb +7 -0
- data/lib/sequel_core/database.rb +22 -0
- data/lib/sequel_core/database/schema.rb +1 -1
- data/lib/sequel_core/dataset.rb +29 -11
- data/lib/sequel_core/dataset/sql.rb +27 -7
- data/lib/sequel_core/migration.rb +20 -2
- data/lib/sequel_core/object_graph.rb +24 -10
- data/lib/sequel_core/schema/generator.rb +22 -9
- data/lib/sequel_core/schema/sql.rb +13 -9
- data/lib/sequel_core/sql.rb +27 -2
- data/lib/sequel_model/association_reflection.rb +251 -141
- data/lib/sequel_model/associations.rb +114 -61
- data/lib/sequel_model/base.rb +25 -21
- data/lib/sequel_model/eager_loading.rb +17 -40
- data/lib/sequel_model/hooks.rb +25 -24
- data/lib/sequel_model/record.rb +29 -51
- data/lib/sequel_model/schema.rb +1 -1
- data/lib/sequel_model/validations.rb +13 -3
- data/spec/adapters/postgres_spec.rb +104 -18
- data/spec/adapters/spec_helper.rb +4 -1
- data/spec/integration/eager_loader_test.rb +5 -4
- data/spec/integration/spec_helper.rb +4 -1
- data/spec/sequel_core/connection_pool_spec.rb +24 -24
- data/spec/sequel_core/core_sql_spec.rb +12 -0
- data/spec/sequel_core/dataset_spec.rb +77 -2
- data/spec/sequel_core/expression_filters_spec.rb +6 -0
- data/spec/sequel_core/object_graph_spec.rb +40 -2
- data/spec/sequel_core/schema_spec.rb +13 -0
- data/spec/sequel_model/association_reflection_spec.rb +8 -8
- data/spec/sequel_model/associations_spec.rb +164 -3
- data/spec/sequel_model/caching_spec.rb +2 -1
- data/spec/sequel_model/eager_loading_spec.rb +107 -3
- data/spec/sequel_model/hooks_spec.rb +38 -22
- data/spec/sequel_model/model_spec.rb +11 -35
- data/spec/sequel_model/plugins_spec.rb +4 -2
- data/spec/sequel_model/record_spec.rb +8 -5
- data/spec/sequel_model/validations_spec.rb +25 -0
- data/spec/spec_config.rb +4 -3
- metadata +21 -19
@@ -228,7 +228,6 @@ describe "has_many :through has_many and has_one :through belongs_to" do
|
|
228
228
|
firms.each{|firm| firm.associations[:invoices] = []}
|
229
229
|
Invoice.eager_graph(:client).filter(:client__firm_id=>id_map.keys).all do |inv|
|
230
230
|
id_map[inv.client.firm_id].each do |firm|
|
231
|
-
inv.client.associations[:firm] = inv.associations[:firm] = firm
|
232
231
|
firm.associations[:invoices] << inv
|
233
232
|
end
|
234
233
|
end
|
@@ -255,20 +254,22 @@ describe "has_many :through has_many and has_one :through belongs_to" do
|
|
255
254
|
:after_load=>(proc do |inv, firm|
|
256
255
|
# Delete the cached associations from firm, because it only has the
|
257
256
|
# client with this invoice, instead of all clients of the firm
|
258
|
-
|
257
|
+
if c = firm.associations.delete(:clients)
|
258
|
+
firm.associations[:invoice_client] = c.first
|
259
|
+
end
|
260
|
+
inv.associations[:client] ||= firm.associations[:invoice_client]
|
259
261
|
end), \
|
260
262
|
:eager_loader=>(proc do |key_hash, invoices, associations|
|
261
263
|
id_map = {}
|
262
264
|
invoices.each do |inv|
|
263
265
|
inv.associations[:firm] = nil
|
264
|
-
inv.associations[:client] = nil
|
265
266
|
(id_map[inv.client_id] ||= []) << inv
|
266
267
|
end
|
267
268
|
Firm.eager_graph(:clients).filter(:clients__id=>id_map.keys).all do |firm|
|
268
269
|
# Delete the cached associations from firm, because it only has the
|
269
270
|
# clients related the invoices being eagerly loaded, instead of all
|
270
271
|
# clients of the firm.
|
271
|
-
firm.associations
|
272
|
+
firm.associations[:clients].each do |client|
|
272
273
|
id_map[client.pk].each do |inv|
|
273
274
|
inv.associations[:firm] = firm
|
274
275
|
inv.associations[:client] = client
|
@@ -3,7 +3,10 @@ unless Object.const_defined?('Sequel')
|
|
3
3
|
$:.unshift(File.join(File.dirname(__FILE__), "../../lib/"))
|
4
4
|
require 'sequel'
|
5
5
|
end
|
6
|
-
|
6
|
+
begin
|
7
|
+
require File.join(File.dirname(__FILE__), '../spec_config.rb')
|
8
|
+
rescue LoadError
|
9
|
+
end
|
7
10
|
|
8
11
|
$sqls = []
|
9
12
|
def clear_sqls
|
@@ -137,13 +137,13 @@ context "A connection pool with a max size of 1" do
|
|
137
137
|
specify "should let only one thread access the connection at any time" do
|
138
138
|
cc,c1, c2 = nil
|
139
139
|
|
140
|
-
t1 = Thread.new {@pool.hold {|c| cc = c; c1 = c.dup; while c == 'herro';sleep 0.
|
141
|
-
sleep 0.
|
140
|
+
t1 = Thread.new {@pool.hold {|c| cc = c; c1 = c.dup; while c == 'herro';sleep 0.01;end}}
|
141
|
+
sleep 0.02
|
142
142
|
cc.should == 'herro'
|
143
143
|
c1.should == 'herro'
|
144
144
|
|
145
|
-
t2 = Thread.new {@pool.hold {|c| c2 = c.dup; while c == 'hello';sleep 0.
|
146
|
-
sleep 0.
|
145
|
+
t2 = Thread.new {@pool.hold {|c| c2 = c.dup; while c == 'hello';sleep 0.01;end}}
|
146
|
+
sleep 0.02
|
147
147
|
|
148
148
|
# connection held by t1
|
149
149
|
t1.should be_alive
|
@@ -157,7 +157,7 @@ context "A connection pool with a max size of 1" do
|
|
157
157
|
@pool.allocated.should == {t1=>cc}
|
158
158
|
|
159
159
|
cc.gsub!('rr', 'll')
|
160
|
-
sleep 0.
|
160
|
+
sleep 0.05
|
161
161
|
|
162
162
|
# connection held by t2
|
163
163
|
t1.should_not be_alive
|
@@ -169,7 +169,7 @@ context "A connection pool with a max size of 1" do
|
|
169
169
|
@pool.allocated.should == {t2=>cc}
|
170
170
|
|
171
171
|
cc.gsub!('ll', 'rr')
|
172
|
-
sleep 0.
|
172
|
+
sleep 0.05
|
173
173
|
|
174
174
|
#connection released
|
175
175
|
t2.should_not be_alive
|
@@ -215,8 +215,8 @@ context "A connection pool with a max size of 5" do
|
|
215
215
|
threads = []
|
216
216
|
stop = nil
|
217
217
|
|
218
|
-
5.times {|i| threads << Thread.new {@pool.hold {|c| cc[i] = c; while !stop;sleep 0.
|
219
|
-
sleep 0.
|
218
|
+
5.times {|i| threads << Thread.new {@pool.hold {|c| cc[i] = c; while !stop;sleep 0.01;end}}; sleep 0.01}
|
219
|
+
sleep 0.02
|
220
220
|
threads.each {|t| t.should be_alive}
|
221
221
|
cc.size.should == 5
|
222
222
|
@invoked_count.should == 5
|
@@ -228,16 +228,16 @@ context "A connection pool with a max size of 5" do
|
|
228
228
|
@pool.allocated.should == h
|
229
229
|
|
230
230
|
threads[0].raise "your'e dead"
|
231
|
-
sleep 0.
|
231
|
+
sleep 0.01
|
232
232
|
threads[3].raise "your'e dead too"
|
233
233
|
|
234
|
-
sleep 0.
|
234
|
+
sleep 0.01
|
235
235
|
|
236
236
|
@pool.available_connections.should == [1, 4]
|
237
237
|
@pool.allocated.should == {threads[1]=>2, threads[2]=>3, threads[4]=>5}
|
238
238
|
|
239
239
|
stop = true
|
240
|
-
sleep 0.
|
240
|
+
sleep 0.02
|
241
241
|
|
242
242
|
@pool.available_connections.size.should == 5
|
243
243
|
@pool.allocated.should be_empty
|
@@ -248,14 +248,14 @@ context "A connection pool with a max size of 5" do
|
|
248
248
|
threads = []
|
249
249
|
stop = nil
|
250
250
|
|
251
|
-
5.times {|i| threads << Thread.new {@pool.hold {|c| cc[i] = c; while !stop;sleep 0.
|
252
|
-
sleep 0.
|
251
|
+
5.times {|i| threads << Thread.new {@pool.hold {|c| cc[i] = c; while !stop;sleep 0.01;end}}; sleep 0.01}
|
252
|
+
sleep 0.02
|
253
253
|
threads.each {|t| t.should be_alive}
|
254
254
|
@pool.available_connections.should be_empty
|
255
255
|
|
256
256
|
3.times {|i| threads << Thread.new {@pool.hold {|c| cc[i + 5] = c}}}
|
257
257
|
|
258
|
-
sleep 0.
|
258
|
+
sleep 0.02
|
259
259
|
threads[5].should be_alive
|
260
260
|
threads[6].should be_alive
|
261
261
|
threads[7].should be_alive
|
@@ -265,7 +265,7 @@ context "A connection pool with a max size of 5" do
|
|
265
265
|
cc[7].should be_nil
|
266
266
|
|
267
267
|
stop = true
|
268
|
-
sleep 0.
|
268
|
+
sleep 0.05
|
269
269
|
|
270
270
|
threads.each {|t| t.should_not be_alive}
|
271
271
|
|
@@ -285,12 +285,12 @@ context "ConnectionPool#disconnect" do
|
|
285
285
|
specify "should invoke the given block for each available connection" do
|
286
286
|
threads = []
|
287
287
|
stop = nil
|
288
|
-
5.times {|i| threads << Thread.new {@pool.hold {|c| while !stop;sleep 0.
|
288
|
+
5.times {|i| threads << Thread.new {@pool.hold {|c| while !stop;sleep 0.01;end}}; sleep 0.01}
|
289
289
|
while @pool.size < 5
|
290
|
-
sleep 0.
|
290
|
+
sleep 0.02
|
291
291
|
end
|
292
292
|
stop = true
|
293
|
-
sleep 1
|
293
|
+
sleep 0.1
|
294
294
|
threads.each {|t| t.join}
|
295
295
|
|
296
296
|
@pool.size.should == 5
|
@@ -304,12 +304,12 @@ context "ConnectionPool#disconnect" do
|
|
304
304
|
specify "should remove all available connections" do
|
305
305
|
threads = []
|
306
306
|
stop = nil
|
307
|
-
5.times {|i| threads << Thread.new {@pool.hold {|c| while !stop;sleep 0.
|
307
|
+
5.times {|i| threads << Thread.new {@pool.hold {|c| while !stop;sleep 0.01;end}}; sleep 0.01}
|
308
308
|
while @pool.size < 5
|
309
|
-
sleep 0.
|
309
|
+
sleep 0.02
|
310
310
|
end
|
311
311
|
stop = true
|
312
|
-
sleep 1
|
312
|
+
sleep 0.1
|
313
313
|
threads.each {|t| t.join}
|
314
314
|
|
315
315
|
@pool.size.should == 5
|
@@ -320,12 +320,12 @@ context "ConnectionPool#disconnect" do
|
|
320
320
|
specify "should not touch connections in use" do
|
321
321
|
threads = []
|
322
322
|
stop = nil
|
323
|
-
5.times {|i| threads << Thread.new {@pool.hold {|c| while !stop;sleep 0.
|
323
|
+
5.times {|i| threads << Thread.new {@pool.hold {|c| while !stop;sleep 0.01;end}}; sleep 0.01}
|
324
324
|
while @pool.size < 5
|
325
|
-
sleep 0.
|
325
|
+
sleep 0.02
|
326
326
|
end
|
327
327
|
stop = true
|
328
|
-
sleep 1
|
328
|
+
sleep 0.1
|
329
329
|
threads.each {|t| t.join}
|
330
330
|
|
331
331
|
@pool.size.should == 5
|
@@ -51,6 +51,18 @@ context "Array#case and Hash#case" do
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
+
context "Array#sql_array" do
|
55
|
+
setup do
|
56
|
+
@d = Sequel::Dataset.new(nil)
|
57
|
+
end
|
58
|
+
|
59
|
+
specify "should treat the array as an SQL array instead of conditions" do
|
60
|
+
@d.literal([[:x, 1], [:y, 2]]).should == '((x = 1) AND (y = 2))'
|
61
|
+
@d.literal([[:x, 1], [:y, 2]].sql_array).should == '((x, 1), (y, 2))'
|
62
|
+
@d.filter([:a, :b]=>[[:x, 1], [:y, 2]].sql_array).sql.should == 'SELECT * WHERE ((a, b) IN ((x, 1), (y, 2)))'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
54
66
|
context "Array#to_sql" do
|
55
67
|
specify "should concatenate multiple lines into a single string" do
|
56
68
|
"SELECT * \r\nFROM items\r\n WHERE a = 1".split.to_sql. \
|
@@ -725,6 +725,15 @@ context "Dataset#from" do
|
|
725
725
|
@dataset.from(:a[:i]).select_sql.should ==
|
726
726
|
"SELECT * FROM a(i)"
|
727
727
|
end
|
728
|
+
|
729
|
+
specify "should accept :schema__table___alias symbol format" do
|
730
|
+
@dataset.from(:abc__def).select_sql.should ==
|
731
|
+
"SELECT * FROM abc.def"
|
732
|
+
@dataset.from(:abc__def___d).select_sql.should ==
|
733
|
+
"SELECT * FROM abc.def AS d"
|
734
|
+
@dataset.from(:abc___def).select_sql.should ==
|
735
|
+
"SELECT * FROM abc AS def"
|
736
|
+
end
|
728
737
|
end
|
729
738
|
|
730
739
|
context "Dataset#select" do
|
@@ -1111,8 +1120,9 @@ context "Dataset#count" do
|
|
1111
1120
|
end
|
1112
1121
|
|
1113
1122
|
def fetch_rows(sql)
|
1123
|
+
@columns = [sql =~ /SELECT COUNT/i ? :count : :a]
|
1114
1124
|
@@sql = sql
|
1115
|
-
yield({
|
1125
|
+
yield({@columns.first=>1})
|
1116
1126
|
end
|
1117
1127
|
end
|
1118
1128
|
@dataset = @c.new(nil).from(:test)
|
@@ -1148,6 +1158,14 @@ context "Dataset#count" do
|
|
1148
1158
|
@dataset.graph(@dataset, [:a], :table_alias=>:test2).count.should == 1
|
1149
1159
|
@c.sql.should == 'SELECT COUNT(*) FROM test LEFT OUTER JOIN test AS test2 USING (a) LIMIT 1'
|
1150
1160
|
end
|
1161
|
+
|
1162
|
+
specify "should not cache the columns value" do
|
1163
|
+
ds = @dataset.from(:blah)
|
1164
|
+
ds.columns.should == [:a]
|
1165
|
+
ds.count.should == 1
|
1166
|
+
@c.sql.should == 'SELECT COUNT(*) FROM blah LIMIT 1'
|
1167
|
+
ds.columns.should == [:a]
|
1168
|
+
end
|
1151
1169
|
end
|
1152
1170
|
|
1153
1171
|
|
@@ -1274,16 +1292,28 @@ context "Dataset#join_table" do
|
|
1274
1292
|
'SELECT * FROM "items" INNER JOIN "categories" ON ("categories"."category_id" = "items"."id")'
|
1275
1293
|
end
|
1276
1294
|
|
1277
|
-
specify "should support aliased tables" do
|
1295
|
+
specify "should support aliased tables using the deprecated argument" do
|
1278
1296
|
@d.from('stats').join('players', {:id => :player_id}, 'p').sql.should ==
|
1279
1297
|
'SELECT * FROM "stats" INNER JOIN "players" AS "p" ON ("p"."id" = "stats"."player_id")'
|
1298
|
+
end
|
1280
1299
|
|
1300
|
+
specify "should support aliased tables using the :table_alias option" do
|
1301
|
+
@d.from('stats').join('players', {:id => :player_id}, :table_alias=>:p).sql.should ==
|
1302
|
+
'SELECT * FROM "stats" INNER JOIN "players" AS "p" ON ("p"."id" = "stats"."player_id")'
|
1303
|
+
end
|
1304
|
+
|
1305
|
+
specify "should support using an alias for the FROM when doing the first join with unqualified condition columns" do
|
1281
1306
|
ds = MockDataset.new(nil).from(:foo => :f)
|
1282
1307
|
ds.quote_identifiers = true
|
1283
1308
|
ds.join_table(:inner, :bar, :id => :bar_id).sql.should ==
|
1284
1309
|
'SELECT * FROM "foo" AS "f" INNER JOIN "bar" ON ("bar"."id" = "f"."bar_id")'
|
1285
1310
|
end
|
1286
1311
|
|
1312
|
+
specify "should support the :implicit_qualifier option" do
|
1313
|
+
@d.from('stats').join('players', {:id => :player_id}, :implicit_qualifier=>:p).sql.should ==
|
1314
|
+
'SELECT * FROM "stats" INNER JOIN "players" ON ("players"."id" = "p"."player_id")'
|
1315
|
+
end
|
1316
|
+
|
1287
1317
|
specify "should allow for arbitrary conditions in the JOIN clause" do
|
1288
1318
|
@d.join_table(:left_outer, :categories, :status => 0).sql.should ==
|
1289
1319
|
'SELECT * FROM "items" LEFT OUTER JOIN "categories" ON ("categories"."status" = 0)'
|
@@ -2953,6 +2983,11 @@ context "Dataset#grep" do
|
|
2953
2983
|
@ds.grep(:title, [/^ruby/, 'ruby']).sql.should ==
|
2954
2984
|
"SELECT * FROM posts WHERE (((title ~ '^ruby') OR (title LIKE 'ruby')))"
|
2955
2985
|
end
|
2986
|
+
|
2987
|
+
specify "should support searching against other columns" do
|
2988
|
+
@ds.grep(:title, :body).sql.should ==
|
2989
|
+
"SELECT * FROM posts WHERE ((title LIKE body))"
|
2990
|
+
end
|
2956
2991
|
end
|
2957
2992
|
|
2958
2993
|
context "Sequel.use_parse_tree" do
|
@@ -3158,3 +3193,43 @@ context "Sequel::Dataset #set_overrides" do
|
|
3158
3193
|
@ds.set_overrides(:x=>2).update_sql.should == "UPDATE items SET x = 1"
|
3159
3194
|
end
|
3160
3195
|
end
|
3196
|
+
|
3197
|
+
context "Sequel::Dataset#each" do
|
3198
|
+
before do
|
3199
|
+
@ds = Sequel::Dataset.new(nil).from(:items)
|
3200
|
+
def @ds.fetch_rows(sql)
|
3201
|
+
@columns = /count/i.match(sql) ? [:count] : [:a]
|
3202
|
+
yield({@columns.first=>sql})
|
3203
|
+
end
|
3204
|
+
end
|
3205
|
+
|
3206
|
+
specify "should not set the columns if passing an option that modifies them" do
|
3207
|
+
@ds.each(:select=>[:count]){}
|
3208
|
+
@ds.columns.should == [:a]
|
3209
|
+
@ds.each(:from=>[:count]){}
|
3210
|
+
@ds.columns.should == [:a]
|
3211
|
+
@ds.each(:join=>[Sequel::SQL::JoinClause.new(:natural, :count)]){}
|
3212
|
+
@ds.columns.should == [:a]
|
3213
|
+
@ds.each(:sql=>'SELECT COUNT'){}
|
3214
|
+
@ds.columns.should == [:a]
|
3215
|
+
end
|
3216
|
+
|
3217
|
+
specify "should have the correct columns inside the block regardless" do
|
3218
|
+
@ds.each(:select=>[:count]) do |x|
|
3219
|
+
x[:count].should == 'SELECT count FROM items'
|
3220
|
+
@ds.columns.should == [:count]
|
3221
|
+
end
|
3222
|
+
@ds.each(:from=>[:count]) do |x|
|
3223
|
+
x[:count].should == 'SELECT * FROM count'
|
3224
|
+
@ds.columns.should == [:count]
|
3225
|
+
end
|
3226
|
+
@ds.each(:join=>[Sequel::SQL::JoinClause.new(:natural, :count)]) do |x|
|
3227
|
+
x[:count].should == 'SELECT * FROM items NATURAL JOIN count'
|
3228
|
+
@ds.columns.should == [:count]
|
3229
|
+
end
|
3230
|
+
@ds.each(:sql=>'SELECT COUNT') do |x|
|
3231
|
+
x[:count].should == 'SELECT COUNT'
|
3232
|
+
@ds.columns.should == [:count]
|
3233
|
+
end
|
3234
|
+
end
|
3235
|
+
end
|
@@ -343,4 +343,10 @@ context "Blockless Ruby Filters" do
|
|
343
343
|
ce.instance_variable_set(:@op, :BANG)
|
344
344
|
proc{@d.lit(ce)}.should raise_error(Sequel::Error)
|
345
345
|
end
|
346
|
+
|
347
|
+
it "should support equality comparison of two expressions" do
|
348
|
+
e1 = ~:comment.like('%:hidden:%')
|
349
|
+
e2 = ~:comment.like('%:hidden:%')
|
350
|
+
e1.should == e2
|
351
|
+
end
|
346
352
|
end
|
@@ -55,6 +55,11 @@ describe Sequel::Dataset, " graphing" do
|
|
55
55
|
ds.sql.should == 'SELECT points.id, points.x, points.y, planes.id AS planes_id, planes.x AS planes_x, planes.y AS planes_y, planes.graph_id FROM points LEFT OUTER JOIN lines AS planes ON (planes.x = points.id)'
|
56
56
|
end
|
57
57
|
|
58
|
+
it "#graph should accept a :implicit_qualifier option" do
|
59
|
+
ds = @ds1.graph(:lines, {:x=>:id}, :implicit_qualifier=>:planes)
|
60
|
+
ds.sql.should == 'SELECT points.id, points.x, points.y, lines.id AS lines_id, lines.x AS lines_x, lines.y AS lines_y, lines.graph_id FROM points LEFT OUTER JOIN lines ON (lines.x = planes.id)'
|
61
|
+
end
|
62
|
+
|
58
63
|
it "#graph should accept a :join_type option" do
|
59
64
|
ds = @ds1.graph(:lines, {:x=>:id}, :join_type=>:inner)
|
60
65
|
ds.sql.should == 'SELECT points.id, points.x, points.y, lines.id AS lines_id, lines.x AS lines_x, lines.y AS lines_y, lines.graph_id FROM points INNER JOIN lines ON (lines.x = points.id)'
|
@@ -104,13 +109,19 @@ describe Sequel::Dataset, " graphing" do
|
|
104
109
|
proc{@ds1.graph(@ds2, :x=>:id).graph(@ds2, {:x=>:id}, :table_alias=>:blah)}.should_not raise_error
|
105
110
|
end
|
106
111
|
|
107
|
-
it "#set_graph_aliases should not modify the current dataset's opts" do
|
112
|
+
it "#set_graph_aliases and #add_graph_aliases should not modify the current dataset's opts" do
|
108
113
|
o1 = @ds1.opts
|
109
114
|
o2 = o1.dup
|
110
115
|
ds1 = @ds1.set_graph_aliases(:x=>[:graphs,:id])
|
111
116
|
@ds1.opts.should == o1
|
112
117
|
@ds1.opts.should == o2
|
113
118
|
ds1.opts.should_not == o1
|
119
|
+
o3 = ds1.opts
|
120
|
+
o4 = o3.dup
|
121
|
+
ds2 = ds1.add_graph_aliases(:y=>[:blah,:id])
|
122
|
+
ds1.opts.should == o3
|
123
|
+
ds1.opts.should == o3
|
124
|
+
ds2.opts.should_not == o2
|
114
125
|
end
|
115
126
|
|
116
127
|
it "#set_graph_aliases should specify the graph mapping" do
|
@@ -122,6 +133,17 @@ describe Sequel::Dataset, " graphing" do
|
|
122
133
|
].should(include(ds.sql))
|
123
134
|
end
|
124
135
|
|
136
|
+
it "#add_graph_aliases should add columns to the graph mapping" do
|
137
|
+
@ds1.graph(:lines, :x=>:id).set_graph_aliases(:x=>[:points, :q]).add_graph_aliases(:y=>[:lines, :r]).sql.should == 'SELECT points.q AS x, lines.r AS y FROM points LEFT OUTER JOIN lines ON (lines.x = points.id)'
|
138
|
+
end
|
139
|
+
|
140
|
+
it "#set_graph_aliases should allow a third entry to specify an expression to use other than the default" do
|
141
|
+
ds = @ds1.graph(:lines, :x=>:id).set_graph_aliases(:x=>[:points, :x, 1], :y=>[:lines, :y, :random[]])
|
142
|
+
['SELECT 1 AS x, random() AS y FROM points LEFT OUTER JOIN lines ON (lines.x = points.id)',
|
143
|
+
'SELECT random() AS y, 1 AS x FROM points LEFT OUTER JOIN lines ON (lines.x = points.id)'
|
144
|
+
].should(include(ds.sql))
|
145
|
+
end
|
146
|
+
|
125
147
|
it "#set_graph_aliases should only alias columns if necessary" do
|
126
148
|
ds = @ds1.set_graph_aliases(:x=>[:points, :x], :y=>[:lines, :y])
|
127
149
|
['SELECT points.x, lines.y FROM points',
|
@@ -194,7 +216,7 @@ describe Sequel::Dataset, " graphing" do
|
|
194
216
|
results.first.should == {:points=>{:id=>1, :x=>2, :y=>3}, :graphs=>{:id=>8, :name=>9, :x=>10, :y=>11, :lines_x=>12}}
|
195
217
|
end
|
196
218
|
|
197
|
-
it "#graph_each should only include the columns selected with #set_graph_aliases, if called" do
|
219
|
+
it "#graph_each should only include the columns selected with #set_graph_aliases and #add_graph_aliases, if called" do
|
198
220
|
ds = @ds1.graph(:lines, :x=>:id).set_graph_aliases(:x=>[:points, :x], :y=>[:lines, :y])
|
199
221
|
def ds.fetch_rows(sql, &block)
|
200
222
|
yield({:x=>2,:y=>3})
|
@@ -210,6 +232,22 @@ describe Sequel::Dataset, " graphing" do
|
|
210
232
|
results = ds.all
|
211
233
|
results.length.should == 1
|
212
234
|
results.first.should == {:points=>{:x=>2}, :lines=>nil}
|
235
|
+
|
236
|
+
ds = ds.add_graph_aliases(:q=>[:points, :r, 18])
|
237
|
+
def ds.fetch_rows(sql, &block)
|
238
|
+
yield({:x=>2, :q=>18})
|
239
|
+
end
|
240
|
+
ds.all.should == [{:points=>{:x=>2, :r=>18}, :lines=>nil}]
|
241
|
+
end
|
242
|
+
|
243
|
+
it "#graph_each should correctly map values when #set_graph_aliases is used with a third argument for each entry" do
|
244
|
+
ds = @ds1.graph(:lines, :x=>:id).set_graph_aliases(:x=>[:points, :z1, 2], :y=>[:lines, :z2, :random[]])
|
245
|
+
def ds.fetch_rows(sql, &block)
|
246
|
+
yield({:x=>2,:y=>3})
|
247
|
+
end
|
248
|
+
results = ds.all
|
249
|
+
results.length.should == 1
|
250
|
+
results.first.should == {:points=>{:z1=>2}, :lines=>{:z2=>3}}
|
213
251
|
end
|
214
252
|
|
215
253
|
it "#graph_each should run the row_proc and transform for graphed datasets" do
|
@@ -10,6 +10,19 @@ context "DB#create_table" do
|
|
10
10
|
@db.sqls.should == ['CREATE TABLE cats ()']
|
11
11
|
end
|
12
12
|
|
13
|
+
specify "should accept the table name in multiple formats" do
|
14
|
+
@db.create_table(:cats__cats) {}
|
15
|
+
@db.create_table("cats__cats1") {}
|
16
|
+
@db.create_table(:cats__cats2.identifier) {}
|
17
|
+
@db.create_table(:cats.qualify(:cats3)) {}
|
18
|
+
@db.sqls.should == ['CREATE TABLE cats.cats ()', 'CREATE TABLE cats__cats1 ()', 'CREATE TABLE cats__cats2 ()', 'CREATE TABLE cats3.cats ()']
|
19
|
+
end
|
20
|
+
|
21
|
+
specify "should raise an error if the table name argument is not valid" do
|
22
|
+
proc{@db.create_table(1) {}}.should raise_error(Sequel::Error)
|
23
|
+
proc{@db.create_table(:cats.as(:c)) {}}.should raise_error(Sequel::Error)
|
24
|
+
end
|
25
|
+
|
13
26
|
specify "should accept multiple columns" do
|
14
27
|
@db.create_table(:cats) do
|
15
28
|
column :id, :integer
|