sequel 3.41.0 → 3.42.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,30 @@
1
+ module Sequel
2
+ class Model
3
+ # This Module subclass is used by Model.dataset_module
4
+ # to add dataset methods to classes. It adds a couple
5
+ # of features standard Modules, allowing you to use
6
+ # the same subset method you can call on Model, as well
7
+ # as making sure that public methods added to the module
8
+ # automatically have class methods created for them.
9
+ class DatasetModule < ::Module
10
+ # Store the model related to this dataset module.
11
+ def initialize(model)
12
+ @model = model
13
+ end
14
+
15
+ # Define a named filter for this dataset, see
16
+ # Model.subset for details.
17
+ def subset(name, *args, &block)
18
+ define_method(name){filter(*args, &block)}
19
+ end
20
+
21
+ private
22
+
23
+ # Add a class method to the related model that
24
+ # calls the dataset method of the same name.
25
+ def method_added(meth)
26
+ @model.send(:def_model_dataset_method, meth)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -63,7 +63,10 @@ module Sequel
63
63
  # Force the encoding of all returned strings to the model's forced_encoding.
64
64
  def typecast_value(column, value)
65
65
  s = super
66
- s.force_encoding(model.forced_encoding) if s.is_a?(String) && model.forced_encoding
66
+ if s.is_a?(String) && (fe = model.forced_encoding)
67
+ s = s.dup if s.frozen?
68
+ s.force_encoding(fe)
69
+ end
67
70
  s
68
71
  end
69
72
  end
@@ -3,7 +3,7 @@ module Sequel
3
3
  MAJOR = 3
4
4
  # The minor version of Sequel. Bumped for every non-patch level
5
5
  # release, generally around once a month.
6
- MINOR = 41
6
+ MINOR = 42
7
7
  # The tiny version of Sequel. Usually 0, only bumped for bugfix
8
8
  # releases that fix regressions from previous versions.
9
9
  TINY = 0
@@ -159,6 +159,15 @@ describe "A PostgreSQL dataset" do
159
159
  @db.alter_table(:atest){drop_constraint 'atest_ex'}
160
160
  end if POSTGRES_DB.server_version >= 90000
161
161
 
162
+ specify "should support Database#do for executing anonymous code blocks" do
163
+ @db.drop_table?(:btest)
164
+ @db.do "BEGIN EXECUTE 'CREATE TABLE btest (a INTEGER)'; EXECUTE 'INSERT INTO btest VALUES (1)'; END"
165
+ @db[:btest].select_map(:a).should == [1]
166
+
167
+ @db.do "BEGIN EXECUTE 'DROP TABLE btest; CREATE TABLE atest (a INTEGER)'; EXECUTE 'INSERT INTO atest VALUES (1)'; END", :language=>:plpgsql
168
+ @db[:atest].select_map(:a).should == [1]
169
+ end if POSTGRES_DB.server_version >= 90000
170
+
162
171
  specify "should support adding foreign key constarints that are not yet valid, and validating them later" do
163
172
  @db.create_table!(:atest){primary_key :id; Integer :fk}
164
173
  @db[:atest].insert(1, 5)
@@ -1222,7 +1231,79 @@ if POSTGRES_DB.adapter_scheme == :postgres
1222
1231
  end
1223
1232
  end
1224
1233
 
1225
- if POSTGRES_DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG && POSTGRES_DB.server_version >= 90000
1234
+ if ((POSTGRES_DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG) || POSTGRES_DB.adapter_scheme == :jdbc) && POSTGRES_DB.server_version >= 90000
1235
+ describe "Postgres::Database#copy_into" do
1236
+ before(:all) do
1237
+ @db = POSTGRES_DB
1238
+ @db.create_table!(:test_copy){Integer :x; Integer :y}
1239
+ @ds = @db[:test_copy].order(:x, :y)
1240
+ end
1241
+ before do
1242
+ @db[:test_copy].delete
1243
+ end
1244
+ after(:all) do
1245
+ @db.drop_table?(:test_copy)
1246
+ end
1247
+
1248
+ specify "should work with a :data option containing data in PostgreSQL text format" do
1249
+ @db.copy_into(:test_copy, :data=>"1\t2\n3\t4\n")
1250
+ @ds.select_map([:x, :y]).should == [[1, 2], [3, 4]]
1251
+ end
1252
+
1253
+ specify "should work with :format=>:csv option and :data option containing data in CSV format" do
1254
+ @db.copy_into(:test_copy, :format=>:csv, :data=>"1,2\n3,4\n")
1255
+ @ds.select_map([:x, :y]).should == [[1, 2], [3, 4]]
1256
+ end
1257
+
1258
+ specify "should respect given :options" do
1259
+ @db.copy_into(:test_copy, :options=>"FORMAT csv, HEADER TRUE", :data=>"x,y\n1,2\n3,4\n")
1260
+ @ds.select_map([:x, :y]).should == [[1, 2], [3, 4]]
1261
+ end
1262
+
1263
+ specify "should respect given :options options when :format is used" do
1264
+ @db.copy_into(:test_copy, :options=>"QUOTE '''', DELIMITER '|'", :format=>:csv, :data=>"'1'|'2'\n'3'|'4'\n")
1265
+ @ds.select_map([:x, :y]).should == [[1, 2], [3, 4]]
1266
+ end
1267
+
1268
+ specify "should accept :columns option to online copy the given columns" do
1269
+ @db.copy_into(:test_copy, :data=>"1\t2\n3\t4\n", :columns=>[:y, :x])
1270
+ @ds.select_map([:x, :y]).should == [[2, 1], [4, 3]]
1271
+ end
1272
+
1273
+ specify "should accept a block and use returned values for the copy in data stream" do
1274
+ buf = ["1\t2\n", "3\t4\n"]
1275
+ @db.copy_into(:test_copy){buf.shift}
1276
+ @ds.select_map([:x, :y]).should == [[1, 2], [3, 4]]
1277
+ end
1278
+
1279
+ specify "should work correctly with a block and :format=>:csv" do
1280
+ buf = ["1,2\n", "3,4\n"]
1281
+ @db.copy_into(:test_copy, :format=>:csv){buf.shift}
1282
+ @ds.select_map([:x, :y]).should == [[1, 2], [3, 4]]
1283
+ end
1284
+
1285
+ specify "should accept an enumerable as the :data option" do
1286
+ @db.copy_into(:test_copy, :data=>["1\t2\n", "3\t4\n"])
1287
+ @ds.select_map([:x, :y]).should == [[1, 2], [3, 4]]
1288
+ end
1289
+
1290
+ specify "should have an exception, cause a rollback of copied data and still have a usable connection" do
1291
+ 2.times do
1292
+ sent = false
1293
+ proc{@db.copy_into(:test_copy){raise ArgumentError if sent; sent = true; "1\t2\n"}}.should raise_error(ArgumentError)
1294
+ @ds.select_map([:x, :y]).should == []
1295
+ end
1296
+ end
1297
+
1298
+ specify "should raise an Error if both :data and a block are provided" do
1299
+ proc{@db.copy_into(:test_copy, :data=>["1\t2\n", "3\t4\n"]){}}.should raise_error(Sequel::Error)
1300
+ end
1301
+
1302
+ specify "should raise an Error if neither :data or a block are provided" do
1303
+ proc{@db.copy_into(:test_copy)}.should raise_error(Sequel::Error)
1304
+ end
1305
+ end
1306
+
1226
1307
  describe "Postgres::Database#copy_table" do
1227
1308
  before(:all) do
1228
1309
  @db = POSTGRES_DB
@@ -1293,79 +1374,9 @@ if POSTGRES_DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG && POSTGRE
1293
1374
  @db[:test_copy].select_order_map(:x).should == [1, 3]
1294
1375
  end
1295
1376
  end
1377
+ end
1296
1378
 
1297
- describe "Postgres::Database#copy_table_from" do
1298
- before(:all) do
1299
- @db = POSTGRES_DB
1300
- @db.create_table!(:test_copy){Integer :x; Integer :y}
1301
- @ds = @db[:test_copy].order(:x, :y)
1302
- end
1303
- before do
1304
- @db[:test_copy].delete
1305
- end
1306
- after(:all) do
1307
- @db.drop_table?(:test_copy)
1308
- end
1309
-
1310
- specify "should work with a :data option containing data in PostgreSQL text format" do
1311
- @db.copy_into(:test_copy, :data=>"1\t2\n3\t4\n")
1312
- @ds.select_map([:x, :y]).should == [[1, 2], [3, 4]]
1313
- end
1314
-
1315
- specify "should work with :format=>:csv option and :data option containing data in CSV format" do
1316
- @db.copy_into(:test_copy, :format=>:csv, :data=>"1,2\n3,4\n")
1317
- @ds.select_map([:x, :y]).should == [[1, 2], [3, 4]]
1318
- end
1319
-
1320
- specify "should respect given :options" do
1321
- @db.copy_into(:test_copy, :options=>"FORMAT csv, HEADER TRUE", :data=>"x,y\n1,2\n3,4\n")
1322
- @ds.select_map([:x, :y]).should == [[1, 2], [3, 4]]
1323
- end
1324
-
1325
- specify "should respect given :options options when :format is used" do
1326
- @db.copy_into(:test_copy, :options=>"QUOTE '''', DELIMITER '|'", :format=>:csv, :data=>"'1'|'2'\n'3'|'4'\n")
1327
- @ds.select_map([:x, :y]).should == [[1, 2], [3, 4]]
1328
- end
1329
-
1330
- specify "should accept :columns option to online copy the given columns" do
1331
- @db.copy_into(:test_copy, :data=>"1\t2\n3\t4\n", :columns=>[:y, :x])
1332
- @ds.select_map([:x, :y]).should == [[2, 1], [4, 3]]
1333
- end
1334
-
1335
- specify "should accept a block and use returned values for the copy in data stream" do
1336
- buf = ["1\t2\n", "3\t4\n"]
1337
- @db.copy_into(:test_copy){buf.shift}
1338
- @ds.select_map([:x, :y]).should == [[1, 2], [3, 4]]
1339
- end
1340
-
1341
- specify "should work correctly with a block and :format=>:csv" do
1342
- buf = ["1,2\n", "3,4\n"]
1343
- @db.copy_into(:test_copy, :format=>:csv){buf.shift}
1344
- @ds.select_map([:x, :y]).should == [[1, 2], [3, 4]]
1345
- end
1346
-
1347
- specify "should accept an enumerable as the :data option" do
1348
- @db.copy_into(:test_copy, :data=>["1\t2\n", "3\t4\n"])
1349
- @ds.select_map([:x, :y]).should == [[1, 2], [3, 4]]
1350
- end
1351
-
1352
- specify "should have an exception should cause a rollback of copied data and still have a usable connection" do
1353
- 2.times do
1354
- sent = false
1355
- proc{@db.copy_into(:test_copy){raise ArgumentError if sent; sent = true; "1\t2\n"}}.should raise_error(ArgumentError)
1356
- @ds.select_map([:x, :y]).should == []
1357
- end
1358
- end
1359
-
1360
- specify "should raise an Error if both :data and a block are provided" do
1361
- proc{@db.copy_into(:test_copy, :data=>["1\t2\n", "3\t4\n"]){}}.should raise_error(Sequel::Error)
1362
- end
1363
-
1364
- specify "should raise an Error if neither :data or a block are provided" do
1365
- proc{@db.copy_into(:test_copy)}.should raise_error(Sequel::Error)
1366
- end
1367
- end
1368
-
1379
+ if POSTGRES_DB.adapter_scheme == :postgres && SEQUEL_POSTGRES_USES_PG && POSTGRES_DB.server_version >= 90000
1369
1380
  describe "Postgres::Database LISTEN/NOTIFY" do
1370
1381
  before(:all) do
1371
1382
  @db = POSTGRES_DB
@@ -22,10 +22,18 @@ describe "A new Database" do
22
22
  Sequel::Database.new(1 => 2, :logger => 4, :loggers => 3).loggers.should == [4,3]
23
23
  Sequel::Database.new(1 => 2, :logger => [4], :loggers => [3]).loggers.should == [4,3]
24
24
  end
25
+
26
+ specify "should handle the default string column size" do
27
+ @db.default_string_column_size.should == 255
28
+ db = Sequel::Database.new(:default_string_column_size=>50)
29
+ db.default_string_column_size.should == 50
30
+ db.default_string_column_size = 2
31
+ db.default_string_column_size.should == 2
32
+ end
25
33
 
26
34
  specify "should set the sql_log_level from opts[:sql_log_level]" do
27
- db = Sequel::Database.new(1 => 2, :sql_log_level=>:debug).sql_log_level.should == :debug
28
- db = Sequel::Database.new(1 => 2, :sql_log_level=>'debug').sql_log_level.should == :debug
35
+ Sequel::Database.new(1 => 2, :sql_log_level=>:debug).sql_log_level.should == :debug
36
+ Sequel::Database.new(1 => 2, :sql_log_level=>'debug').sql_log_level.should == :debug
29
37
  end
30
38
 
31
39
  specify "should create a connection pool" do
@@ -675,7 +683,7 @@ shared_examples_for "Database#transaction" do
675
683
  end
676
684
  e.should_not be_nil
677
685
  e.wrapped_exception.should be_a_kind_of(ec)
678
- @db.sqls.should == ['BEGIN', 'DROP TABLE test;']
686
+ @db.sqls.should == ['BEGIN', 'DROP TABLE test;', 'ROLLBACK']
679
687
  end
680
688
 
681
689
  specify "should handle errors when sending ROLLBACK" do
@@ -1885,6 +1885,11 @@ describe "Dataset#count" do
1885
1885
  @db.sqls.should == ["SELECT COUNT(*) AS count FROM (SELECT * FROM test LIMIT 5) AS t1 LIMIT 1"]
1886
1886
  end
1887
1887
 
1888
+ specify "should work correctly with offsets" do
1889
+ @dataset.limit(nil, 5).count.should == 1
1890
+ @db.sqls.should == ["SELECT COUNT(*) AS count FROM (SELECT * FROM test OFFSET 5) AS t1 LIMIT 1"]
1891
+ end
1892
+
1888
1893
  it "should work on a graphed_dataset" do
1889
1894
  @dataset.should_receive(:columns).twice.and_return([:a])
1890
1895
  @dataset.graph(@dataset, [:a], :table_alias=>:test2).count.should == 1
@@ -2382,6 +2387,13 @@ describe "Dataset aggregate methods" do
2382
2387
  d.min(:a).should == 'SELECT min(a) FROM (SELECT * FROM test ORDER BY a LIMIT 5) AS t1 LIMIT 1'
2383
2388
  d.max(:a).should == 'SELECT max(a) FROM (SELECT * FROM test ORDER BY a LIMIT 5) AS t1 LIMIT 1'
2384
2389
  end
2390
+
2391
+ specify "should accept virtual row blocks" do
2392
+ @d.avg{a(b)}.should == 'SELECT avg(a(b)) FROM test LIMIT 1'
2393
+ @d.sum{a(b)}.should == 'SELECT sum(a(b)) FROM test LIMIT 1'
2394
+ @d.min{a(b)}.should == 'SELECT min(a(b)) FROM test LIMIT 1'
2395
+ @d.max{a(b)}.should == 'SELECT max(a(b)) FROM test LIMIT 1'
2396
+ end
2385
2397
  end
2386
2398
 
2387
2399
  describe "Dataset#range" do
@@ -2406,6 +2418,11 @@ describe "Dataset#range" do
2406
2418
  @ds.order(:stamp).limit(5).range(:stamp).should == (1..10)
2407
2419
  @db.sqls.should == ['SELECT min(stamp) AS v1, max(stamp) AS v2 FROM (SELECT * FROM test ORDER BY stamp LIMIT 5) AS t1 LIMIT 1']
2408
2420
  end
2421
+
2422
+ specify "should accept virtual row blocks" do
2423
+ @ds.range{a(b)}
2424
+ @db.sqls.should == ["SELECT min(a(b)) AS v1, max(a(b)) AS v2 FROM test LIMIT 1"]
2425
+ end
2409
2426
  end
2410
2427
 
2411
2428
  describe "Dataset#interval" do
@@ -2426,6 +2443,11 @@ describe "Dataset#interval" do
2426
2443
  @ds.order(:stamp).limit(5).interval(:stamp).should == 1234
2427
2444
  @db.sqls.should == ['SELECT (max(stamp) - min(stamp)) FROM (SELECT * FROM test ORDER BY stamp LIMIT 5) AS t1 LIMIT 1']
2428
2445
  end
2446
+
2447
+ specify "should accept virtual row blocks" do
2448
+ @ds.interval{a(b)}
2449
+ @db.sqls.should == ["SELECT (max(a(b)) - min(a(b))) FROM test LIMIT 1"]
2450
+ end
2429
2451
  end
2430
2452
 
2431
2453
  describe "Dataset #first and #last" do
@@ -67,6 +67,20 @@ describe "DB#create_table" do
67
67
  @db.sqls.should == ['CREATE TABLE cats (o varchar(255) PRIMARY KEY AUTOINCREMENT, a varchar(255), b integer, c integer, d bigint, e double precision, f numeric, g date, h timestamp, i timestamp, j numeric, k blob, l boolean, m boolean, n integer, p date REFERENCES f)']
68
68
  end
69
69
 
70
+ specify "should transform types given as ruby classes to database-specific types" do
71
+ @db.default_string_column_size = 50
72
+ @db.create_table(:cats) do
73
+ String :a
74
+ String :a2, :size=>13
75
+ String :a3, :fixed=>true
76
+ String :a4, :size=>13, :fixed=>true
77
+ String :a5, :text=>true
78
+ varchar :a6
79
+ varchar :a7, :size=>13
80
+ end
81
+ @db.sqls.should == ['CREATE TABLE cats (a varchar(50), a2 varchar(13), a3 char(50), a4 char(13), a5 text, a6 varchar(50), a7 varchar(13))']
82
+ end
83
+
70
84
  specify "should allow the use of modifiers with ruby class types" do
71
85
  @db.create_table(:cats) do
72
86
  String :a, :size=>50
@@ -133,6 +147,33 @@ describe "DB#create_table" do
133
147
  @db.sqls.should == ["CREATE TABLE cats (id integer, name text UNIQUE)"]
134
148
  end
135
149
 
150
+ specify "should handle not deferred unique constraints" do
151
+ @db.create_table(:cats) do
152
+ integer :id
153
+ text :name
154
+ unique :name, :deferrable=>false
155
+ end
156
+ @db.sqls.should == ["CREATE TABLE cats (id integer, name text, UNIQUE (name) NOT DEFERRABLE)"]
157
+ end
158
+
159
+ specify "should handle deferred unique constraints" do
160
+ @db.create_table(:cats) do
161
+ integer :id
162
+ text :name
163
+ unique :name, :deferrable=>true
164
+ end
165
+ @db.sqls.should == ["CREATE TABLE cats (id integer, name text, UNIQUE (name) DEFERRABLE INITIALLY DEFERRED)"]
166
+ end
167
+
168
+ specify "should handle deferred initially immediate unique constraints" do
169
+ @db.create_table(:cats) do
170
+ integer :id
171
+ text :name
172
+ unique :name, :deferrable=>:immediate
173
+ end
174
+ @db.sqls.should == ["CREATE TABLE cats (id integer, name text, UNIQUE (name) DEFERRABLE INITIALLY IMMEDIATE)"]
175
+ end
176
+
136
177
  specify "should accept unsigned definition" do
137
178
  @db.create_table(:cats) do
138
179
  integer :value, :unsigned => true
@@ -25,6 +25,15 @@ describe "force_encoding plugin" do
25
25
  o.x.encoding.should == @e1
26
26
  end
27
27
 
28
+ specify "should work correctly when given a frozen string" do
29
+ s = 'blah'
30
+ s.force_encoding('US-ASCII')
31
+ s.freeze
32
+ o = @c.new(:x=>s)
33
+ o.x.should == 'blah'
34
+ o.x.encoding.should == @e1
35
+ end
36
+
28
37
  specify "should have a forced_encoding class accessor" do
29
38
  s = 'blah'
30
39
  s.force_encoding('US-ASCII')
@@ -163,20 +163,23 @@ describe "Database index parsing" do
163
163
  end
164
164
 
165
165
  specify "should parse indexes into a hash" do
166
+ # Delete :deferrable entry, since not all adapters implement it
167
+ f = lambda{h = INTEGRATION_DB.indexes(:items); h.values.each{|h2| h2.delete(:deferrable)}; h}
168
+
166
169
  INTEGRATION_DB.create_table!(:items){Integer :n; Integer :a}
167
- INTEGRATION_DB.indexes(:items).should == {}
170
+ f.call.should == {}
168
171
  INTEGRATION_DB.add_index(:items, :n)
169
- INTEGRATION_DB.indexes(:items).should == {:items_n_index=>{:columns=>[:n], :unique=>false}}
172
+ f.call.should == {:items_n_index=>{:columns=>[:n], :unique=>false}}
170
173
  INTEGRATION_DB.drop_index(:items, :n)
171
- INTEGRATION_DB.indexes(:items).should == {}
174
+ f.call.should == {}
172
175
  INTEGRATION_DB.add_index(:items, :n, :unique=>true, :name=>:blah_blah_index)
173
- INTEGRATION_DB.indexes(:items).should == {:blah_blah_index=>{:columns=>[:n], :unique=>true}}
176
+ f.call.should == {:blah_blah_index=>{:columns=>[:n], :unique=>true}}
174
177
  INTEGRATION_DB.add_index(:items, [:n, :a])
175
- INTEGRATION_DB.indexes(:items).should == {:blah_blah_index=>{:columns=>[:n], :unique=>true}, :items_n_a_index=>{:columns=>[:n, :a], :unique=>false}}
178
+ f.call.should == {:blah_blah_index=>{:columns=>[:n], :unique=>true}, :items_n_a_index=>{:columns=>[:n, :a], :unique=>false}}
176
179
  INTEGRATION_DB.drop_index(:items, :n, :name=>:blah_blah_index)
177
- INTEGRATION_DB.indexes(:items).should == {:items_n_a_index=>{:columns=>[:n, :a], :unique=>false}}
180
+ f.call.should == {:items_n_a_index=>{:columns=>[:n, :a], :unique=>false}}
178
181
  INTEGRATION_DB.drop_index(:items, [:n, :a])
179
- INTEGRATION_DB.indexes(:items).should == {}
182
+ f.call.should == {}
180
183
  end
181
184
 
182
185
  specify "should not include a primary key index" do
@@ -619,6 +622,28 @@ describe "Database schema modifiers" do
619
622
  @db[:items].insert(:number=>1)
620
623
  @db[:items].get(:name).should == 'A13'
621
624
  end
625
+
626
+ specify "should support deferrable foreign key constraints" do
627
+ @db.create_table!(:items2){Integer :id, :primary_key=>true}
628
+ @db.create_table!(:items){foreign_key :id, :items2, :deferrable=>true}
629
+ proc{@db[:items].insert(1)}.should raise_error(Sequel::DatabaseError)
630
+ proc{@db.transaction{proc{@db[:items].insert(1)}.should_not raise_error}}.should raise_error(Sequel::DatabaseError)
631
+ end if INTEGRATION_DB.supports_deferrable_foreign_key_constraints?
632
+
633
+ specify "should support deferrable unique constraints when creating or altering tables" do
634
+ @db.create_table!(:items){Integer :t; unique [:t], :name=>:atest_def, :deferrable=>true, :using=>:btree}
635
+ @db[:items].insert(1)
636
+ @db[:items].insert(2)
637
+ proc{@db[:items].insert(2)}.should raise_error(Sequel::DatabaseError)
638
+ proc{@db.transaction{proc{@db[:items].insert(2)}.should_not raise_error}}.should raise_error(Sequel::DatabaseError)
639
+
640
+ @db.create_table!(:items){Integer :t}
641
+ @db.alter_table(:items){add_unique_constraint [:t], :name=>:atest_def, :deferrable=>true, :using=>:btree}
642
+ @db[:items].insert(1)
643
+ @db[:items].insert(2)
644
+ proc{@db[:items].insert(2)}.should raise_error(Sequel::DatabaseError)
645
+ proc{@db.transaction{proc{@db[:items].insert(2)}.should_not raise_error}}.should raise_error(Sequel::DatabaseError)
646
+ end if INTEGRATION_DB.supports_deferrable_constraints?
622
647
  end
623
648
 
624
649
  test_tables = begin
@@ -182,11 +182,21 @@ describe Sequel::Model, ".dataset_module" do
182
182
  @c.dataset.return_3.should == 3
183
183
  end
184
184
 
185
+ it "should also extend the instance_dataset with the module if the model has a dataset" do
186
+ @c.dataset_module{def return_3() 3 end}
187
+ @c.instance_dataset.return_3.should == 3
188
+ end
189
+
185
190
  it "should add methods defined in the module to the class" do
186
191
  @c.dataset_module{def return_3() 3 end}
187
192
  @c.return_3.should == 3
188
193
  end
189
194
 
195
+ it "should add methods defined in the module outside the block to the class" do
196
+ @c.dataset_module.module_eval{def return_3() 3 end}
197
+ @c.return_3.should == 3
198
+ end
199
+
190
200
  it "should cache calls and readd methods if set_dataset is used" do
191
201
  @c.dataset_module{def return_3() 3 end}
192
202
  @c.set_dataset :items
@@ -251,6 +261,12 @@ describe Sequel::Model, ".dataset_module" do
251
261
  Object.new.extend(@c.dataset_module Module.new{def return_3() 3 end}).return_3.should == 3
252
262
  end
253
263
 
264
+ it "should have dataset_module support a subset method" do
265
+ @c.dataset_module{subset :released, :released}
266
+ @c.released.sql.should == 'SELECT * FROM items WHERE released'
267
+ @c.where(:foo).released.sql.should == 'SELECT * FROM items WHERE (foo AND released)'
268
+ end
269
+
254
270
  it "should raise error if called with both an argument and ablock" do
255
271
  proc{@c.dataset_module(Module.new{def return_3() 3 end}){}}.should raise_error(Sequel::Error)
256
272
  end