sequel 4.34.0 → 4.35.0

Sign up to get free protection for your applications and to get access to all the features.
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