sequel 4.34.0 → 4.35.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.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +30 -0
  3. data/Rakefile +14 -17
  4. data/doc/object_model.rdoc +4 -4
  5. data/doc/release_notes/4.35.0.txt +130 -0
  6. data/doc/schema_modification.rdoc +8 -3
  7. data/doc/security.rdoc +3 -3
  8. data/lib/sequel/adapters/ado.rb +2 -2
  9. data/lib/sequel/adapters/ado/access.rb +6 -6
  10. data/lib/sequel/adapters/ado/mssql.rb +2 -2
  11. data/lib/sequel/adapters/amalgalite.rb +6 -6
  12. data/lib/sequel/adapters/cubrid.rb +4 -4
  13. data/lib/sequel/adapters/do.rb +2 -2
  14. data/lib/sequel/adapters/do/mysql.rb +1 -1
  15. data/lib/sequel/adapters/do/postgres.rb +1 -1
  16. data/lib/sequel/adapters/do/sqlite3.rb +1 -1
  17. data/lib/sequel/adapters/ibmdb.rb +6 -6
  18. data/lib/sequel/adapters/jdbc.rb +15 -15
  19. data/lib/sequel/adapters/jdbc/db2.rb +1 -1
  20. data/lib/sequel/adapters/jdbc/derby.rb +3 -3
  21. data/lib/sequel/adapters/jdbc/h2.rb +3 -3
  22. data/lib/sequel/adapters/jdbc/hsqldb.rb +2 -2
  23. data/lib/sequel/adapters/jdbc/mssql.rb +1 -1
  24. data/lib/sequel/adapters/jdbc/mysql.rb +1 -1
  25. data/lib/sequel/adapters/jdbc/oracle.rb +1 -1
  26. data/lib/sequel/adapters/jdbc/postgresql.rb +2 -2
  27. data/lib/sequel/adapters/jdbc/sqlanywhere.rb +1 -1
  28. data/lib/sequel/adapters/jdbc/sqlite.rb +1 -1
  29. data/lib/sequel/adapters/jdbc/transactions.rb +10 -10
  30. data/lib/sequel/adapters/mock.rb +1 -1
  31. data/lib/sequel/adapters/mysql.rb +2 -2
  32. data/lib/sequel/adapters/mysql2.rb +2 -2
  33. data/lib/sequel/adapters/odbc.rb +2 -2
  34. data/lib/sequel/adapters/odbc/mssql.rb +2 -2
  35. data/lib/sequel/adapters/oracle.rb +9 -9
  36. data/lib/sequel/adapters/postgres.rb +3 -3
  37. data/lib/sequel/adapters/shared/mssql.rb +36 -8
  38. data/lib/sequel/adapters/shared/oracle.rb +15 -0
  39. data/lib/sequel/adapters/shared/postgres.rb +22 -1
  40. data/lib/sequel/adapters/sqlanywhere.rb +1 -1
  41. data/lib/sequel/adapters/sqlite.rb +7 -7
  42. data/lib/sequel/adapters/swift.rb +3 -3
  43. data/lib/sequel/adapters/swift/mysql.rb +1 -1
  44. data/lib/sequel/adapters/swift/postgres.rb +1 -1
  45. data/lib/sequel/adapters/swift/sqlite.rb +1 -1
  46. data/lib/sequel/adapters/tinytds.rb +5 -7
  47. data/lib/sequel/database/logging.rb +18 -3
  48. data/lib/sequel/database/misc.rb +19 -8
  49. data/lib/sequel/database/schema_generator.rb +7 -2
  50. data/lib/sequel/database/schema_methods.rb +9 -2
  51. data/lib/sequel/database/transactions.rb +52 -18
  52. data/lib/sequel/dataset/actions.rb +24 -19
  53. data/lib/sequel/dataset/features.rb +5 -0
  54. data/lib/sequel/dataset/query.rb +6 -0
  55. data/lib/sequel/extensions/_pretty_table.rb +1 -1
  56. data/lib/sequel/extensions/error_sql.rb +3 -3
  57. data/lib/sequel/extensions/pg_range.rb +10 -1
  58. data/lib/sequel/extensions/schema_dumper.rb +8 -5
  59. data/lib/sequel/extensions/server_logging.rb +61 -0
  60. data/lib/sequel/extensions/sql_comments.rb +91 -0
  61. data/lib/sequel/model/associations.rb +40 -8
  62. data/lib/sequel/model/base.rb +19 -5
  63. data/lib/sequel/plugins/class_table_inheritance.rb +12 -0
  64. data/lib/sequel/plugins/delay_add_association.rb +1 -0
  65. data/lib/sequel/plugins/json_serializer.rb +10 -2
  66. data/lib/sequel/version.rb +1 -1
  67. data/spec/adapter_spec.rb +4 -0
  68. data/spec/adapters/mysql_spec.rb +1 -1
  69. data/spec/adapters/postgres_spec.rb +3 -2
  70. data/spec/core/connection_pool_spec.rb +2 -0
  71. data/spec/core/database_spec.rb +49 -0
  72. data/spec/core/dataset_spec.rb +25 -1
  73. data/spec/core/mock_adapter_spec.rb +3 -1
  74. data/spec/core/schema_generator_spec.rb +1 -1
  75. data/spec/core_model_spec.rb +2 -0
  76. data/spec/core_spec.rb +1 -0
  77. data/spec/extensions/delay_add_association_spec.rb +22 -0
  78. data/spec/extensions/json_serializer_spec.rb +6 -0
  79. data/spec/extensions/pg_range_spec.rb +30 -2
  80. data/spec/extensions/schema_dumper_spec.rb +3 -2
  81. data/spec/extensions/server_logging_spec.rb +45 -0
  82. data/spec/extensions/sql_comments_spec.rb +27 -0
  83. data/spec/files/reversible_migrations/006_reversible.rb +10 -0
  84. data/spec/files/reversible_migrations/007_reversible.rb +10 -0
  85. data/spec/integration/dataset_test.rb +28 -2
  86. data/spec/integration/migrator_test.rb +23 -1
  87. data/spec/integration/schema_test.rb +12 -32
  88. data/spec/integration/transaction_test.rb +10 -0
  89. data/spec/integration/type_test.rb +1 -1
  90. data/spec/model/eager_loading_spec.rb +16 -0
  91. data/spec/model/record_spec.rb +9 -0
  92. data/spec/model_no_assoc_spec.rb +1 -0
  93. data/spec/model_spec.rb +1 -0
  94. data/spec/plugin_spec.rb +1 -0
  95. metadata +16 -2
@@ -338,7 +338,9 @@ describe "Sequel Mock Adapter" do
338
338
  db[:b].delete
339
339
  db[:c].insert(:a=>1)
340
340
  db[:d].update(:a=>1)
341
- a.must_equal ['SELECT * FROM t', 'DELETE FROM b', 'INSERT INTO c (a) VALUES (1)', 'UPDATE d SET a = 1']
341
+ a.zip(['SELECT * FROM t', 'DELETE FROM b', 'INSERT INTO c (a) VALUES (1)', 'UPDATE d SET a = 1']).each do |is, should|
342
+ is.must_match should
343
+ end
342
344
  end
343
345
 
344
346
  it "should correctly handle transactions" do
@@ -198,6 +198,6 @@ describe "Sequel::Schema::Generator generic type methods" do
198
198
  File :k
199
199
  TrueClass :l
200
200
  FalseClass :m
201
- end.columns.map{|c| c[:type]}.must_equal [String, Integer, Fixnum, Bignum, Float, BigDecimal, Date, DateTime, Time, Numeric, File, TrueClass, FalseClass]
201
+ end.columns.map{|c| c[:type]}.must_equal [String, Integer, Fixnum, :Bignum, Float, BigDecimal, Date, DateTime, Time, Numeric, File, TrueClass, FalseClass]
202
202
  end
203
203
  end
@@ -0,0 +1,2 @@
1
+ require './spec/core_spec'
2
+ require './spec/model_spec'
data/spec/core_spec.rb ADDED
@@ -0,0 +1 @@
1
+ Dir['./spec/core/*_spec.rb'].each{|f| require f}
@@ -49,4 +49,26 @@ describe "Sequel::Plugins::DelayAddAssociation" do
49
49
  @o.errors[:cs].must_equal ["name is b"]
50
50
  @o.cs.first.errors[:name].must_equal ['is b']
51
51
  end
52
+
53
+ it "should work when passing in hashes" do
54
+ @o = @c.new(:name=>'a')
55
+ @o.add_c(:name=>'b')
56
+ @db.sqls.must_equal []
57
+ @o.save
58
+ sqls = @db.sqls
59
+ sqls.length.must_equal 4
60
+ sqls[0].must_equal "INSERT INTO cs (name) VALUES ('a')"
61
+ ["INSERT INTO cs (name, c_id) VALUES ('b', 1)", "INSERT INTO cs (c_id, name) VALUES (1, 'b')"].must_include sqls[1]
62
+ sqls[2].must_equal "SELECT * FROM cs WHERE (id = 2) LIMIT 1"
63
+ sqls[3].must_equal "SELECT * FROM cs WHERE (id = 1) LIMIT 1"
64
+ end
65
+
66
+ it "should work when passing in primary keys" do
67
+ @db.fetch = [[{:id=>2, :name=>'b', :c_id=>nil}], [{:id=>1, :name=>'a', :c_id=>nil}]]
68
+ @o = @c.new(:name=>'a')
69
+ @o.add_c(2)
70
+ @db.sqls.must_equal ["SELECT * FROM cs WHERE (id = 2) LIMIT 1"]
71
+ @o.save
72
+ @db.sqls.must_equal ["INSERT INTO cs (name) VALUES ('a')", "UPDATE cs SET c_id = 1 WHERE (id = 2)", "SELECT * FROM cs WHERE (id = 1) LIMIT 1"]
73
+ end
52
74
  end
@@ -127,6 +127,12 @@ describe "Sequel::Plugins::JsonSerializer" do
127
127
  Album.from_json(@album.to_json(:include=>{:artist=>{:include=>{:albums=>{:only=>:name}}}}), :associations=>{:artist=>{:associations=>:albums}}).artist.albums.must_equal [Album.load(:name=>@album.name)]
128
128
  end
129
129
 
130
+ it "should handle usage of association_proxies when cascading using the :include option" do
131
+ Artist.plugin :association_proxies
132
+ Artist.one_to_many :albums, :clone=>:albums
133
+ Artist.from_json(@artist.to_json(:include=>{:albums=>{:include=>:artist}}), :associations=>{:albums=>{:associations=>:artist}}).albums.map{|a| a.artist}.must_equal [@artist]
134
+ end
135
+
130
136
  it "should handle the :include option cascading with an empty hash" do
131
137
  Album.from_json(@album.to_json(:include=>{:artist=>{}}), :associations=>:artist).artist.must_equal @artist
132
138
  Album.from_json(@album.to_json(:include=>{:blah=>{}})).blah.must_equal @album.blah
@@ -325,9 +325,9 @@ describe "pg_range extension" do
325
325
  end
326
326
 
327
327
  it "should quack like a range" do
328
+ @r1.cover?(1.5).must_equal true
329
+ @r1.cover?(2.5).must_equal false
328
330
  if RUBY_VERSION >= '1.9'
329
- @r1.cover?(1.5).must_equal true
330
- @r1.cover?(2.5).must_equal false
331
331
  @r1.first(1).must_equal [1]
332
332
  @r1.last(1).must_equal [2]
333
333
  end
@@ -339,6 +339,34 @@ describe "pg_range extension" do
339
339
  a.must_equal [1, 2]
340
340
  end
341
341
 
342
+ it "should have cover? handle empty, unbounded, and exclusive beginning ranges" do
343
+ @R.empty.cover?(1).must_equal false
344
+
345
+ r = @R.new(1, nil)
346
+ r.cover?(0).must_equal false
347
+ r.cover?(1).must_equal true
348
+ r.cover?(2).must_equal true
349
+ r.cover?(3).must_equal true
350
+
351
+ r = @R.new(nil, 2)
352
+ r.cover?(0).must_equal true
353
+ r.cover?(1).must_equal true
354
+ r.cover?(2).must_equal true
355
+ r.cover?(3).must_equal false
356
+
357
+ r = @R.new(1, 2, :exclude_begin=>true)
358
+ r.cover?(0).must_equal false
359
+ r.cover?(1).must_equal false
360
+ r.cover?(2).must_equal true
361
+ r.cover?(3).must_equal false
362
+
363
+ r = @R.new(1, 2, :exclude_end=>true)
364
+ r.cover?(0).must_equal false
365
+ r.cover?(1).must_equal true
366
+ r.cover?(2).must_equal false
367
+ r.cover?(3).must_equal false
368
+ end
369
+
342
370
  it "should only consider PGRanges equal if they have the same db_type" do
343
371
  @R.new(1, 2, :db_type=>'int4range').must_equal @R.new(1, 2, :db_type=>'int4range')
344
372
  @R.new(1, 2, :db_type=>'int8range').wont_equal @R.new(1, 2, :db_type=>'int4range')
@@ -107,7 +107,7 @@ describe "Sequel::Database dump methods" do
107
107
 
108
108
  it "should dump non-Integer primary key columns with explicit :type" do
109
109
  @d.meta_def(:schema){|*s| [[:c1, {:db_type=>'bigint', :primary_key=>true, :allow_null=>true, :auto_increment=>true}]]}
110
- @d.dump_table_schema(:t6).must_equal "create_table(:t6) do\n primary_key :c1, :type=>Bignum\nend"
110
+ @d.dump_table_schema(:t6).must_equal "create_table(:t6) do\n primary_key :c1, :type=>:Bignum\nend"
111
111
  end
112
112
 
113
113
  it "should dump auto incrementing primary keys with :keep_order option if they are not first" do
@@ -665,7 +665,7 @@ END_MIG
665
665
  %w"nvarchar ntext smalldatetime smallmoney binary varbinary nchar" +
666
666
  ["timestamp(6) without time zone", "timestamp(6) with time zone", 'mediumint(10) unsigned', 'int(9) unsigned',
667
667
  'int(10) unsigned', "int(12) unsigned", 'bigint unsigned', 'tinyint(3) unsigned', 'identity', 'int identity'] +
668
- %w"integer(10) bit"
668
+ %w"integer(10) bit bool"
669
669
  @d.meta_def(:schema) do |t, *o|
670
670
  i = 0
671
671
  types.map{|x| [:"c#{i+=1}", {:db_type=>x, :allow_null=>true}]}
@@ -745,6 +745,7 @@ create_table(:x) do
745
745
  Integer :c71
746
746
  Integer :c72
747
747
  TrueClass :c73
748
+ TrueClass :c74
748
749
 
749
750
  check Sequel::SQL::BooleanExpression.new(:>=, Sequel::SQL::Identifier.new(:c64), 0)
750
751
  check Sequel::SQL::BooleanExpression.new(:>=, Sequel::SQL::Identifier.new(:c65), 0)
@@ -0,0 +1,45 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
+
3
+ describe "server_logging extension" do
4
+ before do
5
+ @o = Object.new
6
+ def @o.logs; @logs || []; end
7
+ def @o.log; logs.length.must_equal 1; logs.first.length.must_equal 1; logs.shift.first; end
8
+ def @o.to_ary; [self]; end
9
+ def @o.method_missing(m, *args); (@logs ||= []) << args; end
10
+ @db = Sequel::mock(:servers=>{:read_only=>{}, :b=>{}}, :logger=>@o).extension(:server_logging)
11
+ end
12
+
13
+ it "should include shard when logging" do
14
+ @db[:a].all
15
+ @o.log.must_include "server: read_only) SELECT * FROM a"
16
+ @db[:a].insert
17
+ @o.log.must_include "server: default) INSERT INTO a DEFAULT VALUES"
18
+ @db[:a].server(:b).all
19
+ @o.log.must_include "server: b) SELECT * FROM a"
20
+ end
21
+
22
+ it "should not include shard when not logging connection info" do
23
+ @db.log_connection_info = false
24
+ @db[:a].all
25
+ log = @o.log
26
+ log.wont_include "server: read_only) SELECT * FROM a"
27
+ log.must_include "SELECT * FROM a"
28
+ end
29
+
30
+ it "should not turn on logging connction info if it was turned off" do
31
+ @db.log_connection_info = false
32
+ @db.extension :server_logging
33
+ @db[:a].all
34
+ log = @o.log
35
+ log.wont_include "server: read_only) SELECT * FROM a"
36
+ log.must_include "SELECT * FROM a"
37
+ end
38
+
39
+ it "should remove mapping when disconnecting" do
40
+ c = @db.synchronize{|c1| c1}
41
+ @db.disconnect
42
+ @db.send(:log_connection_execute, c, "SELECT * FROM a")
43
+ @o.log.must_include "server: ) SELECT * FROM a"
44
+ end
45
+ end
@@ -0,0 +1,27 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
+
3
+ describe "sql_comments extension" do
4
+ before do
5
+ @ds = Sequel.mock[:t].extension(:sql_comments)
6
+ end
7
+
8
+ it "should not add a comment if one is not set for the dataset" do
9
+ @ds.select_sql.must_equal 'SELECT * FROM t'
10
+ @ds.insert_sql(:a=>1).must_equal 'INSERT INTO t (a) VALUES (1)'
11
+ @ds.delete_sql.must_equal 'DELETE FROM t'
12
+ @ds.update_sql(:a=>1).must_equal 'UPDATE t SET a = 1'
13
+ end
14
+
15
+ it "should add a comment if one is set for the dataset" do
16
+ ds = @ds.comment("Some\nComment\r\n Here")
17
+ ds.select_sql.must_equal "SELECT * FROM t -- Some Comment Here\n"
18
+ ds.insert_sql(:a=>1).must_equal "INSERT INTO t (a) VALUES (1) -- Some Comment Here\n"
19
+ ds.delete_sql.must_equal "DELETE FROM t -- Some Comment Here\n"
20
+ ds.update_sql(:a=>1).must_equal "UPDATE t SET a = 1 -- Some Comment Here\n"
21
+ end
22
+
23
+ it "should handle comments used in nested datasets" do
24
+ ds = @ds.comment("Some\nComment\r\n Here")
25
+ ds.where(:id=>ds).select_sql.must_equal "SELECT * FROM t WHERE (id IN (SELECT * FROM t -- Some Comment Here\n)) -- Some Comment Here\n"
26
+ end
27
+ end
@@ -0,0 +1,10 @@
1
+ Sequel.migration do
2
+ change do
3
+ create_table(:c) do
4
+ primary_key :id
5
+ end
6
+ alter_table(:b) do
7
+ add_foreign_key :f, :c
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ Sequel.migration do
2
+ change do
3
+ create_table(:d) do
4
+ primary_key :id
5
+ end
6
+ alter_table(:b) do
7
+ add_foreign_key :g, :d, :foreign_key_constraint_name=>:b_f_foo
8
+ end
9
+ end
10
+ end
@@ -25,7 +25,7 @@ describe "Simple Dataset operations" do
25
25
 
26
26
  it "should support sequential primary keys with a Bignum" do
27
27
  @db.create_table!(:items) do
28
- primary_key :id, :type=>Bignum
28
+ primary_key :id, :type=>:Bignum
29
29
  Integer :number
30
30
  end
31
31
  @ds << {:number=>20}
@@ -171,6 +171,24 @@ describe "Simple Dataset operations" do
171
171
  @ds.all.must_equal [{:id=>1, :number=>10}]
172
172
  end
173
173
 
174
+ cspecify "should skip locked rows correctly", [:do] do
175
+ @ds.insert(:number=>10)
176
+ q1 = Queue.new
177
+ q2 = Queue.new
178
+ ds = @ds.order(:id).for_update.skip_locked
179
+ begin
180
+ t = Thread.new{@db.transaction(:isolation=>:committed){q2.push(ds.get(:id)); q1.pop}}
181
+ q2.pop.must_equal 1
182
+ # Some databases do row level locking, others do page level locking
183
+ [2, nil].must_include @db.transaction(:isolation=>:committed){ds.get(:id)}
184
+ ensure
185
+ q1.push(nil)
186
+ t.join
187
+ # Keep only one active connection, as some other specs expect that
188
+ @db.disconnect
189
+ end
190
+ end if DB.dataset.supports_skip_locked?
191
+
174
192
  it "should raise exception if raising on duplication columns" do
175
193
  proc{@ds.select_map([:id, :id])}.must_raise Sequel::DuplicateColumnError
176
194
  end if DB.opts[:on_duplicate_columns] == :raise
@@ -325,6 +343,14 @@ describe "Simple Dataset operations" do
325
343
  @ds.filter(true).select_map(:number).must_equal [10]
326
344
  @ds.filter(false).select_map(:number).must_equal []
327
345
  end
346
+
347
+ it "should support the sql_comments extension" do
348
+ ds = @ds.extension(:sql_comments).comment("Some\rComment\r\nHere")
349
+ ds.all.must_equal [{:id=>1, :number=>10}]
350
+ ds.insert(:number=>20).must_equal 2
351
+ ds.update(:number=>30).must_equal 2
352
+ ds.delete.must_equal 2
353
+ end
328
354
  end
329
355
 
330
356
  describe "Simple dataset operations with nasty table names" do
@@ -873,7 +899,7 @@ describe Sequel::SQL::Constants do
873
899
  d.to_s.must_equal Date.today.to_s
874
900
  end
875
901
 
876
- cspecify "should have working CURRENT_TIME", [:jdbc, :sqlite], [:mysql2] do
902
+ cspecify "should have working CURRENT_TIME", [:jdbc, :sqlite], [:mysql2], [:tinytds] do
877
903
  @db.create_table!(:constants){Time :t, :only_time=>true}
878
904
  @ds.insert(:t=>Sequel::CURRENT_TIME)
879
905
  (Time.now - @c[@ds.get(:t)]).must_be_close_to 0, 60
@@ -7,7 +7,7 @@ describe Sequel::Migrator do
7
7
  @m = Sequel::Migrator
8
8
  end
9
9
  after do
10
- @db.drop_table?(:schema_info, :schema_migrations, :sm1111, :sm1122, :sm2222, :sm2233, :sm3333, :sm11111, :sm22222)
10
+ @db.drop_table?(:schema_info, :schema_migrations, :sm1111, :sm1122, :sm2222, :sm2233, :sm3333, :sm11111, :sm22222, :a, :b, :c, :d)
11
11
  end
12
12
 
13
13
  it "should be able to migrate up and down all the way successfully" do
@@ -213,6 +213,28 @@ describe Sequel::Migrator do
213
213
  [:schema_migrations, :a].each{|n| @db.table_exists?(n).must_equal false}
214
214
  @db[:b].columns.must_equal [:a, :c, :e]
215
215
 
216
+ if @db.supports_foreign_key_parsing?
217
+ @m.apply(@db, @dir, 6)
218
+ [:schema_info, :b, :c].each{|n| @db.table_exists?(n).must_equal true}
219
+ [:schema_migrations, :a].each{|n| @db.table_exists?(n).must_equal false}
220
+ @db[:b].columns.must_equal [:a, :c, :e, :f]
221
+
222
+ @m.apply(@db, @dir, 7)
223
+ [:schema_info, :b, :c, :d].each{|n| @db.table_exists?(n).must_equal true}
224
+ [:schema_migrations, :a].each{|n| @db.table_exists?(n).must_equal false}
225
+ @db[:b].columns.must_equal [:a, :c, :e, :f, :g]
226
+
227
+ @m.apply(@db, @dir, 6)
228
+ [:schema_info, :b, :c].each{|n| @db.table_exists?(n).must_equal true}
229
+ [:schema_migrations, :a, :d].each{|n| @db.table_exists?(n).must_equal false}
230
+ @db[:b].columns.must_equal [:a, :c, :e, :f]
231
+ end
232
+
233
+ @m.apply(@db, @dir, 5)
234
+ [:schema_info, :b].each{|n| @db.table_exists?(n).must_equal true}
235
+ [:schema_migrations, :a, :c].each{|n| @db.table_exists?(n).must_equal false}
236
+ @db[:b].columns.must_equal [:a, :c, :e]
237
+
216
238
  @m.apply(@db, @dir, 4)
217
239
  [:schema_info, :b].each{|n| @db.table_exists?(n).must_equal true}
218
240
  [:schema_migrations, :a].each{|n| @db.table_exists?(n).must_equal false}
@@ -762,7 +762,7 @@ describe "Database schema modifiers" do
762
762
  end if DB.supports_deferrable_constraints?
763
763
  end
764
764
 
765
- describe "Database#tables" do
765
+ describe "Database#tables and #views" do
766
766
  before do
767
767
  class ::String
768
768
  @@xxxxx = 0
@@ -771,6 +771,8 @@ describe "Database#tables" do
771
771
  end
772
772
  end
773
773
  @db = DB
774
+ @db.drop_view(:sequel_test_view) rescue nil
775
+ @db.drop_table?(:sequel_test_table)
774
776
  @db.create_table(:sequel_test_table){Integer :a}
775
777
  @db.create_view :sequel_test_view, @db[:sequel_test_table]
776
778
  @iom = @db.identifier_output_method
@@ -783,53 +785,31 @@ describe "Database#tables" do
783
785
  @db.drop_table :sequel_test_table
784
786
  end
785
787
 
786
- it "should return an array of symbols" do
788
+ it "#tables should return an array of symbols" do
787
789
  ts = @db.tables
788
790
  ts.must_be_kind_of(Array)
789
791
  ts.each{|t| t.must_be_kind_of(Symbol)}
790
792
  ts.must_include(:sequel_test_table)
791
793
  ts.wont_include(:sequel_test_view)
792
- end
794
+ end if DB.supports_table_listing?
793
795
 
794
- it "should respect the database's identifier_output_method" do
796
+ it "#tables should respect the database's identifier_output_method" do
795
797
  @db.identifier_output_method = :xxxxx
796
798
  @db.identifier_input_method = :xxxxx
797
799
  @db.tables.each{|t| t.to_s.must_match(/\Ax{5}\d+\z/)}
798
- end
799
- end if DB.supports_table_listing?
800
+ end if DB.supports_table_listing?
800
801
 
801
- describe "Database#views" do
802
- before do
803
- class ::String
804
- @@xxxxx = 0
805
- def xxxxx
806
- "xxxxx#{@@xxxxx += 1}"
807
- end
808
- end
809
- @db = DB
810
- @db.create_table(:sequel_test_table){Integer :a}
811
- @db.create_view :sequel_test_view, @db[:sequel_test_table]
812
- @iom = @db.identifier_output_method
813
- @iim = @db.identifier_input_method
814
- end
815
- after do
816
- @db.identifier_output_method = @iom
817
- @db.identifier_input_method = @iim
818
- @db.drop_view :sequel_test_view
819
- @db.drop_table :sequel_test_table
820
- end
821
-
822
- it "should return an array of symbols" do
802
+ it "#views should return an array of symbols" do
823
803
  ts = @db.views
824
804
  ts.must_be_kind_of(Array)
825
805
  ts.each{|t| t.must_be_kind_of(Symbol)}
826
806
  ts.wont_include(:sequel_test_table)
827
807
  ts.must_include(:sequel_test_view)
828
- end
808
+ end if DB.supports_view_listing?
829
809
 
830
- it "should respect the database's identifier_output_method" do
810
+ it "#views should respect the database's identifier_output_method" do
831
811
  @db.identifier_output_method = :xxxxx
832
812
  @db.identifier_input_method = :xxxxx
833
813
  @db.views.each{|t| t.to_s.must_match(/\Ax{5}\d+\z/)}
834
- end
835
- end if DB.supports_view_listing?
814
+ end if DB.supports_view_listing?
815
+ end
@@ -93,6 +93,16 @@ describe "Database transactions" do
93
93
  @d.select_order_map(:name).must_equal %w'1 2'
94
94
  end
95
95
 
96
+ it "should handle :rollback=>:always inside transactions" do
97
+ @db.transaction do
98
+ @db.transaction(:rollback=>:always) do
99
+ @d << {:name => 'abc', :value => 1}
100
+ 2
101
+ end.must_equal 2
102
+ end
103
+ @d.select_order_map(:value).must_equal []
104
+ end
105
+
96
106
  it "should handle table_exists? failures inside savepoints" do
97
107
  @db.transaction do
98
108
  @d << {:name => '1'}
@@ -38,7 +38,7 @@ describe "Supported types" do
38
38
  end
39
39
 
40
40
  it "should support generic bignum type" do
41
- ds = create_items_table_with_column(:number, Bignum)
41
+ ds = create_items_table_with_column(:number, :Bignum)
42
42
  ds.insert(:number => 2**34)
43
43
  ds.all.must_equal [{:number=>2**34}]
44
44
  end