sequel 3.46.0 → 3.47.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +96 -0
- data/Rakefile +7 -1
- data/bin/sequel +6 -4
- data/doc/active_record.rdoc +1 -1
- data/doc/advanced_associations.rdoc +14 -35
- data/doc/association_basics.rdoc +66 -4
- data/doc/migration.rdoc +4 -0
- data/doc/opening_databases.rdoc +6 -0
- data/doc/postgresql.rdoc +302 -0
- data/doc/release_notes/3.47.0.txt +270 -0
- data/doc/security.rdoc +6 -0
- data/lib/sequel/adapters/ibmdb.rb +9 -9
- data/lib/sequel/adapters/jdbc.rb +22 -7
- data/lib/sequel/adapters/jdbc/postgresql.rb +7 -2
- data/lib/sequel/adapters/mock.rb +2 -0
- data/lib/sequel/adapters/postgres.rb +44 -13
- data/lib/sequel/adapters/shared/mssql.rb +1 -1
- data/lib/sequel/adapters/shared/mysql.rb +2 -2
- data/lib/sequel/adapters/shared/postgres.rb +94 -55
- data/lib/sequel/adapters/shared/sqlite.rb +3 -1
- data/lib/sequel/adapters/sqlite.rb +2 -2
- data/lib/sequel/adapters/utils/pg_types.rb +1 -14
- data/lib/sequel/adapters/utils/split_alter_table.rb +3 -3
- data/lib/sequel/connection_pool/threaded.rb +1 -1
- data/lib/sequel/core.rb +1 -1
- data/lib/sequel/database/connecting.rb +2 -2
- data/lib/sequel/database/features.rb +5 -0
- data/lib/sequel/database/misc.rb +47 -5
- data/lib/sequel/database/query.rb +2 -2
- data/lib/sequel/dataset/actions.rb +4 -2
- data/lib/sequel/dataset/misc.rb +1 -1
- data/lib/sequel/dataset/prepared_statements.rb +1 -1
- data/lib/sequel/dataset/query.rb +8 -6
- data/lib/sequel/dataset/sql.rb +8 -6
- data/lib/sequel/extensions/constraint_validations.rb +5 -2
- data/lib/sequel/extensions/migration.rb +10 -8
- data/lib/sequel/extensions/pagination.rb +3 -0
- data/lib/sequel/extensions/pg_array.rb +85 -25
- data/lib/sequel/extensions/pg_hstore.rb +8 -1
- data/lib/sequel/extensions/pg_hstore_ops.rb +4 -1
- data/lib/sequel/extensions/pg_inet.rb +16 -13
- data/lib/sequel/extensions/pg_interval.rb +6 -2
- data/lib/sequel/extensions/pg_json.rb +18 -11
- data/lib/sequel/extensions/pg_range.rb +17 -2
- data/lib/sequel/extensions/pg_range_ops.rb +7 -5
- data/lib/sequel/extensions/pg_row.rb +29 -12
- data/lib/sequel/extensions/pretty_table.rb +3 -0
- data/lib/sequel/extensions/query.rb +3 -0
- data/lib/sequel/extensions/schema_caching.rb +2 -0
- data/lib/sequel/extensions/schema_dumper.rb +3 -1
- data/lib/sequel/extensions/select_remove.rb +3 -0
- data/lib/sequel/model.rb +8 -2
- data/lib/sequel/model/associations.rb +39 -27
- data/lib/sequel/model/base.rb +99 -38
- data/lib/sequel/model/plugins.rb +25 -0
- data/lib/sequel/plugins/association_autoreloading.rb +27 -22
- data/lib/sequel/plugins/association_dependencies.rb +1 -7
- data/lib/sequel/plugins/auto_validations.rb +110 -0
- data/lib/sequel/plugins/boolean_readers.rb +1 -6
- data/lib/sequel/plugins/caching.rb +6 -13
- data/lib/sequel/plugins/class_table_inheritance.rb +1 -0
- data/lib/sequel/plugins/composition.rb +14 -7
- data/lib/sequel/plugins/constraint_validations.rb +2 -13
- data/lib/sequel/plugins/defaults_setter.rb +1 -6
- data/lib/sequel/plugins/dirty.rb +8 -0
- data/lib/sequel/plugins/error_splitter.rb +54 -0
- data/lib/sequel/plugins/force_encoding.rb +1 -5
- data/lib/sequel/plugins/hook_class_methods.rb +1 -6
- data/lib/sequel/plugins/input_transformer.rb +79 -0
- data/lib/sequel/plugins/instance_filters.rb +7 -1
- data/lib/sequel/plugins/instance_hooks.rb +7 -1
- data/lib/sequel/plugins/json_serializer.rb +5 -10
- data/lib/sequel/plugins/lazy_attributes.rb +20 -7
- data/lib/sequel/plugins/list.rb +1 -6
- data/lib/sequel/plugins/many_through_many.rb +1 -2
- data/lib/sequel/plugins/many_to_one_pk_lookup.rb +23 -39
- data/lib/sequel/plugins/optimistic_locking.rb +1 -5
- data/lib/sequel/plugins/pg_row.rb +4 -2
- data/lib/sequel/plugins/pg_typecast_on_load.rb +3 -7
- data/lib/sequel/plugins/prepared_statements.rb +1 -5
- data/lib/sequel/plugins/prepared_statements_safe.rb +2 -11
- data/lib/sequel/plugins/rcte_tree.rb +2 -2
- data/lib/sequel/plugins/serialization.rb +11 -13
- data/lib/sequel/plugins/serialization_modification_detection.rb +13 -1
- data/lib/sequel/plugins/single_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/static_cache.rb +67 -19
- data/lib/sequel/plugins/string_stripper.rb +7 -27
- data/lib/sequel/plugins/subclasses.rb +3 -5
- data/lib/sequel/plugins/tactical_eager_loading.rb +2 -2
- data/lib/sequel/plugins/timestamps.rb +2 -7
- data/lib/sequel/plugins/touch.rb +5 -8
- data/lib/sequel/plugins/tree.rb +1 -6
- data/lib/sequel/plugins/typecast_on_load.rb +1 -5
- data/lib/sequel/plugins/update_primary_key.rb +26 -14
- data/lib/sequel/plugins/validation_class_methods.rb +31 -16
- data/lib/sequel/plugins/validation_helpers.rb +50 -26
- data/lib/sequel/plugins/xml_serializer.rb +3 -6
- data/lib/sequel/sql.rb +1 -1
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/postgres_spec.rb +131 -15
- data/spec/adapters/sqlite_spec.rb +1 -1
- data/spec/core/connection_pool_spec.rb +16 -17
- data/spec/core/database_spec.rb +111 -40
- data/spec/core/dataset_spec.rb +65 -74
- data/spec/core/expression_filters_spec.rb +6 -5
- data/spec/core/object_graph_spec.rb +0 -1
- data/spec/core/schema_spec.rb +23 -23
- data/spec/core/spec_helper.rb +5 -1
- data/spec/extensions/association_dependencies_spec.rb +1 -1
- data/spec/extensions/association_proxies_spec.rb +1 -1
- data/spec/extensions/auto_validations_spec.rb +90 -0
- data/spec/extensions/caching_spec.rb +6 -0
- data/spec/extensions/class_table_inheritance_spec.rb +8 -1
- data/spec/extensions/composition_spec.rb +12 -5
- data/spec/extensions/constraint_validations_spec.rb +4 -4
- data/spec/extensions/core_refinements_spec.rb +29 -79
- data/spec/extensions/dirty_spec.rb +14 -0
- data/spec/extensions/error_splitter_spec.rb +18 -0
- data/spec/extensions/identity_map_spec.rb +0 -1
- data/spec/extensions/input_transformer_spec.rb +54 -0
- data/spec/extensions/instance_filters_spec.rb +6 -0
- data/spec/extensions/instance_hooks_spec.rb +12 -1
- data/spec/extensions/json_serializer_spec.rb +0 -1
- data/spec/extensions/lazy_attributes_spec.rb +64 -55
- data/spec/extensions/looser_typecasting_spec.rb +1 -1
- data/spec/extensions/many_through_many_spec.rb +3 -4
- data/spec/extensions/many_to_one_pk_lookup_spec.rb +53 -15
- data/spec/extensions/migration_spec.rb +16 -0
- data/spec/extensions/null_dataset_spec.rb +1 -1
- data/spec/extensions/pg_array_spec.rb +48 -1
- data/spec/extensions/pg_hstore_ops_spec.rb +10 -2
- data/spec/extensions/pg_hstore_spec.rb +5 -0
- data/spec/extensions/pg_inet_spec.rb +5 -0
- data/spec/extensions/pg_interval_spec.rb +7 -3
- data/spec/extensions/pg_json_spec.rb +6 -1
- data/spec/extensions/pg_range_ops_spec.rb +4 -1
- data/spec/extensions/pg_range_spec.rb +5 -0
- data/spec/extensions/pg_row_plugin_spec.rb +13 -0
- data/spec/extensions/pg_row_spec.rb +28 -19
- data/spec/extensions/pg_typecast_on_load_spec.rb +6 -1
- data/spec/extensions/prepared_statements_associations_spec.rb +1 -1
- data/spec/extensions/query_literals_spec.rb +1 -1
- data/spec/extensions/rcte_tree_spec.rb +2 -2
- data/spec/extensions/schema_spec.rb +2 -2
- data/spec/extensions/serialization_modification_detection_spec.rb +8 -0
- data/spec/extensions/serialization_spec.rb +15 -1
- data/spec/extensions/sharding_spec.rb +1 -1
- data/spec/extensions/single_table_inheritance_spec.rb +1 -1
- data/spec/extensions/static_cache_spec.rb +59 -9
- data/spec/extensions/tactical_eager_loading_spec.rb +19 -4
- data/spec/extensions/update_primary_key_spec.rb +17 -1
- data/spec/extensions/validation_class_methods_spec.rb +25 -0
- data/spec/extensions/validation_helpers_spec.rb +59 -3
- data/spec/integration/associations_test.rb +5 -5
- data/spec/integration/eager_loader_test.rb +32 -63
- data/spec/integration/model_test.rb +2 -2
- data/spec/integration/plugin_test.rb +88 -56
- data/spec/integration/prepared_statement_test.rb +1 -1
- data/spec/integration/schema_test.rb +1 -1
- data/spec/integration/timezone_test.rb +0 -1
- data/spec/integration/transaction_test.rb +0 -1
- data/spec/model/association_reflection_spec.rb +1 -1
- data/spec/model/associations_spec.rb +106 -84
- data/spec/model/base_spec.rb +4 -4
- data/spec/model/eager_loading_spec.rb +8 -8
- data/spec/model/model_spec.rb +27 -9
- data/spec/model/plugins_spec.rb +71 -0
- data/spec/model/record_spec.rb +99 -13
- metadata +12 -2
@@ -618,7 +618,7 @@ describe "A SQLite database" do
|
|
618
618
|
|
619
619
|
specify "should have support for various #transaction modes" do
|
620
620
|
sqls = []
|
621
|
-
@db.loggers <<
|
621
|
+
@db.loggers << Class.new{%w'info error'.each{|m| define_method(m){|sql| sqls << sql}}}.new
|
622
622
|
|
623
623
|
@db.transaction(:mode => :immediate) do
|
624
624
|
sqls.last.should == "BEGIN IMMEDIATE TRANSACTION"
|
@@ -3,9 +3,9 @@ CONNECTION_POOL_DEFAULTS = {:pool_timeout=>5, :pool_sleep_time=>0.001, :max_conn
|
|
3
3
|
|
4
4
|
mock_db = lambda do |*a, &b|
|
5
5
|
db = Sequel.mock
|
6
|
-
db.
|
6
|
+
(class << db; self end).send(:define_method, :connect){|c| b.arity == 1 ? b.call(c) : b.call} if b
|
7
7
|
if b2 = a.shift
|
8
|
-
db.
|
8
|
+
(class << db; self end).send(:define_method, :disconnect_connection){|c| b2.arity == 1 ? b2.call(c) : b2.call}
|
9
9
|
end
|
10
10
|
db
|
11
11
|
end
|
@@ -100,7 +100,7 @@ describe "A connection pool handling connections" do
|
|
100
100
|
@cpool.created_count.should <= @max_size
|
101
101
|
end
|
102
102
|
|
103
|
-
specify "
|
103
|
+
specify "database's disconnect connection method should be called when a disconnect is detected" do
|
104
104
|
@max_size.should == 2
|
105
105
|
proc{@cpool.hold{raise Sequel::DatabaseDisconnectError}}.should raise_error(Sequel::DatabaseDisconnectError)
|
106
106
|
@max_size.should == 3
|
@@ -144,7 +144,7 @@ describe "ConnectionPool#hold" do
|
|
144
144
|
@pool = Sequel::ConnectionPool.get_pool(mock_db.call{c.new}, CONNECTION_POOL_DEFAULTS)
|
145
145
|
end
|
146
146
|
|
147
|
-
specify "
|
147
|
+
specify "shoulda use the database's connect method to get new connections" do
|
148
148
|
res = nil
|
149
149
|
@pool.hold {|c| res = c}
|
150
150
|
res.should be_a_kind_of(@c)
|
@@ -156,7 +156,7 @@ describe "ConnectionPool#hold" do
|
|
156
156
|
|
157
157
|
specify "should be re-entrant by the same thread" do
|
158
158
|
cc = nil
|
159
|
-
@pool.hold {|c| @pool.hold {|
|
159
|
+
@pool.hold {|c| @pool.hold {|c1| @pool.hold {|c2| cc = c2}}}
|
160
160
|
cc.should be_a_kind_of(@c)
|
161
161
|
end
|
162
162
|
|
@@ -220,10 +220,10 @@ describe "A connection pool with a max size of 1" do
|
|
220
220
|
c1, c2, c3 = nil
|
221
221
|
@pool.hold do |c|
|
222
222
|
c1 = c
|
223
|
-
@pool.hold do |
|
224
|
-
c2 =
|
225
|
-
@pool.hold do |
|
226
|
-
c3 =
|
223
|
+
@pool.hold do |cc2|
|
224
|
+
c2 = cc2
|
225
|
+
@pool.hold do |cc3|
|
226
|
+
c3 = cc3
|
227
227
|
end
|
228
228
|
end
|
229
229
|
end
|
@@ -295,7 +295,6 @@ shared_examples_for "A threaded connection pool" do
|
|
295
295
|
end
|
296
296
|
|
297
297
|
specify "should raise a PoolTimeout error if a connection couldn't be acquired before timeout" do
|
298
|
-
x = nil
|
299
298
|
q, q1 = Queue.new, Queue.new
|
300
299
|
pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts.merge(:max_connections=>1, :pool_timeout=>0))
|
301
300
|
t = Thread.new{pool.hold{|c| q1.push nil; q.pop}}
|
@@ -396,8 +395,8 @@ shared_examples_for "A threaded connection pool" do
|
|
396
395
|
specify "should not store connections if :connection_handling=>:disconnect" do
|
397
396
|
@pool = Sequel::ConnectionPool.get_pool(mock_db.call(&@icpp), @cp_opts.merge(:connection_handling=>:disconnect))
|
398
397
|
d = []
|
399
|
-
@pool.db
|
400
|
-
|
398
|
+
meta_def(@pool.db, :disconnect_connection){|c| d << c}
|
399
|
+
@pool.hold do |cc|
|
401
400
|
cc.should == 1
|
402
401
|
Thread.new{@pool.hold{|cc2| cc2.should == 2}}.join
|
403
402
|
d.should == [2]
|
@@ -456,7 +455,7 @@ describe "ConnectionPool#disconnect" do
|
|
456
455
|
@pool.available_connections.size.should == 5
|
457
456
|
@pool.available_connections.each {|c| c[:id].should_not be_nil}
|
458
457
|
conns = []
|
459
|
-
@pool.db
|
458
|
+
meta_def(@pool.db, :disconnect_connection){|c| conns << c}
|
460
459
|
@pool.disconnect
|
461
460
|
conns.size.should == 5
|
462
461
|
end
|
@@ -473,7 +472,7 @@ describe "ConnectionPool#disconnect" do
|
|
473
472
|
@pool.available_connections.size.should == 4
|
474
473
|
@pool.available_connections.each {|c| c.should_not be(conn)}
|
475
474
|
conns = []
|
476
|
-
@pool.db
|
475
|
+
meta_def(@pool.db, :disconnect_connection){|c| conns << c}
|
477
476
|
@pool.disconnect
|
478
477
|
conns.size.should == 4
|
479
478
|
@pool.size.should == 1
|
@@ -575,7 +574,7 @@ describe "A connection pool with multiple servers" do
|
|
575
574
|
conns = []
|
576
575
|
@pool.size.should == 1
|
577
576
|
@pool.size(:read_only).should == 1
|
578
|
-
@pool.db
|
577
|
+
meta_def(@pool.db, :disconnect_connection){|c| conns << c}
|
579
578
|
@pool.disconnect
|
580
579
|
conns.sort.should == %w'default1 read_only1'
|
581
580
|
@pool.size.should == 0
|
@@ -923,13 +922,13 @@ shared_examples_for "All connection pools classes" do
|
|
923
922
|
|
924
923
|
specify "should call the disconnection_proc option if the hold block raises a DatabaseDisconnectError" do
|
925
924
|
x = nil
|
926
|
-
proc{
|
925
|
+
proc{@class.new(mock_db.call(proc{|c| x = c}){123}).hold{raise Sequel::DatabaseDisconnectError}}.should raise_error(Sequel::DatabaseDisconnectError)
|
927
926
|
x.should == 123
|
928
927
|
end
|
929
928
|
|
930
929
|
specify "should have a disconnect method that disconnects the connection" do
|
931
930
|
x = nil
|
932
|
-
c = @class.new(mock_db.call(proc{|
|
931
|
+
c = @class.new(mock_db.call(proc{|c1| x = c1}){123})
|
933
932
|
c.hold{}
|
934
933
|
x.should == nil
|
935
934
|
c.disconnect
|
data/spec/core/database_spec.rb
CHANGED
@@ -43,10 +43,10 @@ describe "A new Database" do
|
|
43
43
|
Sequel::Database.new(:max_connections => 10).pool.max_size.should == 10
|
44
44
|
end
|
45
45
|
|
46
|
-
specify "should
|
46
|
+
specify "should have the connection pool use the connect method to get connections" do
|
47
47
|
cc = nil
|
48
48
|
d = Sequel::Database.new
|
49
|
-
|
49
|
+
meta_def(d, :connect){|c| 1234}
|
50
50
|
d.synchronize {|c| cc = c}
|
51
51
|
cc.should == 1234
|
52
52
|
end
|
@@ -204,6 +204,11 @@ describe "A new Database" do
|
|
204
204
|
specify "should populate :adapter option when using connection string" do
|
205
205
|
Sequel.connect('mock:/').opts[:adapter].should == "mock"
|
206
206
|
end
|
207
|
+
|
208
|
+
specify "should respect the :keep_reference option for not keeping a reference in Sequel::DATABASES" do
|
209
|
+
db = Sequel.connect('mock:///?keep_reference=f')
|
210
|
+
Sequel::DATABASES.should_not include(db)
|
211
|
+
end
|
207
212
|
end
|
208
213
|
|
209
214
|
describe "Database#disconnect" do
|
@@ -343,7 +348,7 @@ describe "Database#uri" do
|
|
343
348
|
end
|
344
349
|
|
345
350
|
describe "Database.adapter_scheme and #adapter_scheme" do
|
346
|
-
specify "should return the database
|
351
|
+
specify "should return the database scheme" do
|
347
352
|
Sequel::Database.adapter_scheme.should be_nil
|
348
353
|
|
349
354
|
@c = Class.new(Sequel::Database) do
|
@@ -470,7 +475,7 @@ describe "Database#extend_datasets" do
|
|
470
475
|
@db[:t].select(:a, :b).sql.should == 'SELECT a, b FROM t ORDER BY a, b'
|
471
476
|
end
|
472
477
|
|
473
|
-
specify "should reapply settings if dataset_class is
|
478
|
+
specify "should reapply settings if dataset_class is changed" do
|
474
479
|
c = Class.new(Sequel::Dataset)
|
475
480
|
@db.dataset_class = c
|
476
481
|
@db.dataset_class.superclass.should == c
|
@@ -568,11 +573,11 @@ end
|
|
568
573
|
describe "Database#synchronize" do
|
569
574
|
before do
|
570
575
|
@db = Sequel::Database.new(:max_connections => 1)
|
571
|
-
@db
|
576
|
+
meta_def(@db, :connect){|c| 12345}
|
572
577
|
end
|
573
578
|
|
574
579
|
specify "should wrap the supplied block in pool.hold" do
|
575
|
-
q, q1, q2
|
580
|
+
q, q1, q2 = Queue.new, Queue.new, Queue.new
|
576
581
|
c1, c2 = nil
|
577
582
|
t1 = Thread.new{@db.synchronize{|c| c1 = c; q.push nil; q1.pop}; q.push nil}
|
578
583
|
q.pop
|
@@ -593,7 +598,7 @@ describe "Database#test_connection" do
|
|
593
598
|
before do
|
594
599
|
@db = Sequel::Database.new
|
595
600
|
pr = proc{@test = rand(100)}
|
596
|
-
@db
|
601
|
+
meta_def(@db, :connect){|c| pr.call}
|
597
602
|
end
|
598
603
|
|
599
604
|
specify "should attempt to get a connection" do
|
@@ -611,7 +616,7 @@ describe "Database#test_connection" do
|
|
611
616
|
end
|
612
617
|
|
613
618
|
describe "Database#table_exists?" do
|
614
|
-
specify "should
|
619
|
+
specify "should test existence by selecting a row from the table's dataset" do
|
615
620
|
db = Sequel.mock(:fetch=>[Sequel::Error, [], [{:a=>1}]])
|
616
621
|
db.table_exists?(:a).should be_false
|
617
622
|
db.sqls.should == ["SELECT NULL FROM a LIMIT 1"]
|
@@ -627,7 +632,7 @@ shared_examples_for "Database#transaction" do
|
|
627
632
|
end
|
628
633
|
|
629
634
|
specify "should support transaction isolation levels" do
|
630
|
-
@db
|
635
|
+
meta_def(@db, :supports_transaction_isolation_levels?){true}
|
631
636
|
[:uncommitted, :committed, :repeatable, :serializable].each do |l|
|
632
637
|
@db.transaction(:isolation=>l){@db.run "DROP TABLE #{l}"}
|
633
638
|
end
|
@@ -638,7 +643,7 @@ shared_examples_for "Database#transaction" do
|
|
638
643
|
end
|
639
644
|
|
640
645
|
specify "should allow specifying a default transaction isolation level" do
|
641
|
-
@db
|
646
|
+
meta_def(@db, :supports_transaction_isolation_levels?){true}
|
642
647
|
[:uncommitted, :committed, :repeatable, :serializable].each do |l|
|
643
648
|
@db.transaction_isolation_level = l
|
644
649
|
@db.transaction{@db.run "DROP TABLE #{l}"}
|
@@ -715,7 +720,6 @@ shared_examples_for "Database#transaction" do
|
|
715
720
|
transaction do
|
716
721
|
execute 'DROP TABLE test;'
|
717
722
|
return
|
718
|
-
execute 'DROP TABLE test2;';
|
719
723
|
end
|
720
724
|
end
|
721
725
|
@db.ret_commit
|
@@ -731,8 +735,8 @@ shared_examples_for "Database#transaction" do
|
|
731
735
|
|
732
736
|
specify "should handle errors when sending BEGIN" do
|
733
737
|
ec = Class.new(StandardError)
|
734
|
-
@db
|
735
|
-
@db
|
738
|
+
meta_def(@db, :database_error_classes){[ec]}
|
739
|
+
meta_def(@db, :log_connection_execute){|c, sql| sql =~ /BEGIN/ ? raise(ec, 'bad') : super(c, sql)}
|
736
740
|
begin
|
737
741
|
@db.transaction{@db.execute 'DROP TABLE test;'}
|
738
742
|
rescue Sequel::DatabaseError => e
|
@@ -744,8 +748,8 @@ shared_examples_for "Database#transaction" do
|
|
744
748
|
|
745
749
|
specify "should handle errors when sending COMMIT" do
|
746
750
|
ec = Class.new(StandardError)
|
747
|
-
@db
|
748
|
-
@db
|
751
|
+
meta_def(@db, :database_error_classes){[ec]}
|
752
|
+
meta_def(@db, :log_connection_execute){|c, sql| sql =~ /COMMIT/ ? raise(ec, 'bad') : super(c, sql)}
|
749
753
|
begin
|
750
754
|
@db.transaction{@db.execute 'DROP TABLE test;'}
|
751
755
|
rescue Sequel::DatabaseError => e
|
@@ -757,8 +761,8 @@ shared_examples_for "Database#transaction" do
|
|
757
761
|
|
758
762
|
specify "should handle errors when sending ROLLBACK" do
|
759
763
|
ec = Class.new(StandardError)
|
760
|
-
@db
|
761
|
-
@db
|
764
|
+
meta_def(@db, :database_error_classes){[ec]}
|
765
|
+
meta_def(@db, :log_connection_execute){|c, sql| sql =~ /ROLLBACK/ ? raise(ec, 'bad') : super(c, sql)}
|
762
766
|
begin
|
763
767
|
@db.transaction{raise ArgumentError, 'asdf'}
|
764
768
|
rescue Sequel::DatabaseError => e
|
@@ -815,17 +819,17 @@ shared_examples_for "Database#transaction" do
|
|
815
819
|
@db.sqls.should == ['BEGIN', 'ROLLBACK']
|
816
820
|
@db.transaction(:rollback=>:always){1}.should be_nil
|
817
821
|
@db.sqls.should == ['BEGIN', 'ROLLBACK']
|
818
|
-
catch
|
822
|
+
catch(:foo) do
|
819
823
|
@db.transaction(:rollback=>:always){throw :foo}
|
820
824
|
end
|
821
825
|
@db.sqls.should == ['BEGIN', 'ROLLBACK']
|
822
826
|
end
|
823
827
|
|
824
828
|
specify "should raise database errors when commiting a transaction as Sequel::DatabaseError" do
|
825
|
-
@db
|
829
|
+
meta_def(@db, :commit_transaction){raise ArgumentError}
|
826
830
|
lambda{@db.transaction{}}.should raise_error(ArgumentError)
|
827
831
|
|
828
|
-
@db
|
832
|
+
meta_def(@db, :database_error_classes){[ArgumentError]}
|
829
833
|
lambda{@db.transaction{}}.should raise_error(Sequel::DatabaseError)
|
830
834
|
end
|
831
835
|
|
@@ -942,13 +946,13 @@ shared_examples_for "Database#transaction" do
|
|
942
946
|
end
|
943
947
|
|
944
948
|
specify "should raise an error if you attempt to use after_commit inside a prepared transaction" do
|
945
|
-
@db
|
949
|
+
meta_def(@db, :supports_prepared_transactions?){true}
|
946
950
|
proc{@db.transaction(:prepare=>'XYZ'){@db.after_commit{@db.execute('foo')}}}.should raise_error(Sequel::Error)
|
947
951
|
@db.sqls.should == ['BEGIN', 'ROLLBACK']
|
948
952
|
end
|
949
953
|
|
950
954
|
specify "should raise an error if you attempt to use after_rollback inside a prepared transaction" do
|
951
|
-
@db
|
955
|
+
meta_def(@db, :supports_prepared_transactions?){true}
|
952
956
|
proc{@db.transaction(:prepare=>'XYZ'){@db.after_rollback{@db.execute('foo')}}}.should raise_error(Sequel::Error)
|
953
957
|
@db.sqls.should == ['BEGIN', 'ROLLBACK']
|
954
958
|
end
|
@@ -962,7 +966,7 @@ describe "Database#transaction with savepoint support" do
|
|
962
966
|
it_should_behave_like "Database#transaction"
|
963
967
|
|
964
968
|
specify "should support after_commit inside savepoints" do
|
965
|
-
@db
|
969
|
+
meta_def(@db, :supports_savepoints?){true}
|
966
970
|
@db.transaction do
|
967
971
|
@db.after_commit{@db.execute('foo')}
|
968
972
|
@db.transaction(:savepoint=>true){@db.after_commit{@db.execute('bar')}}
|
@@ -972,7 +976,7 @@ describe "Database#transaction with savepoint support" do
|
|
972
976
|
end
|
973
977
|
|
974
978
|
specify "should support after_rollback inside savepoints" do
|
975
|
-
@db
|
979
|
+
meta_def(@db, :supports_savepoints?){true}
|
976
980
|
@db.transaction do
|
977
981
|
@db.after_rollback{@db.execute('foo')}
|
978
982
|
@db.transaction(:savepoint=>true){@db.after_rollback{@db.execute('bar')}}
|
@@ -983,15 +987,15 @@ describe "Database#transaction with savepoint support" do
|
|
983
987
|
end
|
984
988
|
|
985
989
|
specify "should raise an error if you attempt to use after_commit inside a savepoint in a prepared transaction" do
|
986
|
-
@db
|
987
|
-
@db
|
990
|
+
meta_def(@db, :supports_savepoints?){true}
|
991
|
+
meta_def(@db, :supports_prepared_transactions?){true}
|
988
992
|
proc{@db.transaction(:prepare=>'XYZ'){@db.transaction(:savepoint=>true){@db.after_commit{@db.execute('foo')}}}}.should raise_error(Sequel::Error)
|
989
993
|
@db.sqls.should == ['BEGIN', 'SAVEPOINT autopoint_1','ROLLBACK TO SAVEPOINT autopoint_1', 'ROLLBACK']
|
990
994
|
end
|
991
995
|
|
992
996
|
specify "should raise an error if you attempt to use after_rollback inside a savepoint in a prepared transaction" do
|
993
|
-
@db
|
994
|
-
@db
|
997
|
+
meta_def(@db, :supports_savepoints?){true}
|
998
|
+
meta_def(@db, :supports_prepared_transactions?){true}
|
995
999
|
proc{@db.transaction(:prepare=>'XYZ'){@db.transaction(:savepoint=>true){@db.after_rollback{@db.execute('foo')}}}}.should raise_error(Sequel::Error)
|
996
1000
|
@db.sqls.should == ['BEGIN', 'SAVEPOINT autopoint_1','ROLLBACK TO SAVEPOINT autopoint_1', 'ROLLBACK']
|
997
1001
|
end
|
@@ -1000,7 +1004,7 @@ end
|
|
1000
1004
|
describe "Database#transaction without savepoint support" do
|
1001
1005
|
before do
|
1002
1006
|
@db = Sequel.mock(:servers=>{:test=>{}})
|
1003
|
-
@db
|
1007
|
+
meta_def(@db, :supports_savepoints?){false}
|
1004
1008
|
end
|
1005
1009
|
|
1006
1010
|
it_should_behave_like "Database#transaction"
|
@@ -1058,7 +1062,7 @@ describe "Database#transaction with savepoints" do
|
|
1058
1062
|
@db.sqls.should == ['BEGIN', 'SAVEPOINT autopoint_1', 'DROP TABLE test;', 'RELEASE SAVEPOINT autopoint_1', 'COMMIT']
|
1059
1063
|
end
|
1060
1064
|
|
1061
|
-
specify "should not use a
|
1065
|
+
specify "should not use a savepoint if no transaction is in progress" do
|
1062
1066
|
@db.transaction(:savepoint=>true){@db.execute 'DROP TABLE test;'}
|
1063
1067
|
@db.sqls.should == ['BEGIN', 'DROP TABLE test;', 'COMMIT']
|
1064
1068
|
end
|
@@ -1073,7 +1077,6 @@ describe "Database#transaction with savepoints" do
|
|
1073
1077
|
transaction do
|
1074
1078
|
execute 'DROP TABLE test;'
|
1075
1079
|
return
|
1076
|
-
execute 'DROP TABLE test2;';
|
1077
1080
|
end
|
1078
1081
|
end
|
1079
1082
|
@db.ret_commit
|
@@ -1086,7 +1089,6 @@ describe "Database#transaction with savepoints" do
|
|
1086
1089
|
transaction(:savepoint=>true) do
|
1087
1090
|
execute 'DROP TABLE test;'
|
1088
1091
|
return
|
1089
|
-
execute 'DROP TABLE test2;';
|
1090
1092
|
end
|
1091
1093
|
end
|
1092
1094
|
end
|
@@ -1131,11 +1133,11 @@ describe "Database#transaction with savepoints" do
|
|
1131
1133
|
end
|
1132
1134
|
|
1133
1135
|
specify "should raise database errors when commiting a transaction as Sequel::DatabaseError" do
|
1134
|
-
@db
|
1136
|
+
meta_def(@db, :commit_transaction){raise ArgumentError}
|
1135
1137
|
lambda{@db.transaction{}}.should raise_error(ArgumentError)
|
1136
1138
|
lambda{@db.transaction{@db.transaction(:savepoint=>true){}}}.should raise_error(ArgumentError)
|
1137
1139
|
|
1138
|
-
@db
|
1140
|
+
meta_def(@db, :database_error_classes){[ArgumentError]}
|
1139
1141
|
lambda{@db.transaction{}}.should raise_error(Sequel::DatabaseError)
|
1140
1142
|
lambda{@db.transaction{@db.transaction(:savepoint=>true){}}}.should raise_error(Sequel::DatabaseError)
|
1141
1143
|
end
|
@@ -1200,6 +1202,7 @@ describe "A Database adapter with a scheme" do
|
|
1200
1202
|
Sequel.send(:def_adapter_method, :ccc)
|
1201
1203
|
Sequel.ccc('db', :host=>'localhost', &p).should == returnValue
|
1202
1204
|
@ccc::DISCONNECTS.should == [z, y, x]
|
1205
|
+
class << Sequel; remove_method(:ccc) end
|
1203
1206
|
end
|
1204
1207
|
|
1205
1208
|
specify "should be accessible through Sequel.<adapter>" do
|
@@ -1223,6 +1226,7 @@ describe "A Database adapter with a scheme" do
|
|
1223
1226
|
c = Sequel.ccc(:database => 'mydb', :host => 'localhost')
|
1224
1227
|
c.should be_a_kind_of(@ccc)
|
1225
1228
|
c.opts.values_at(:adapter, :database, :host, :adapter_class).should == [:ccc, 'mydb', 'localhost', @ccc]
|
1229
|
+
class << Sequel; remove_method(:ccc) end
|
1226
1230
|
end
|
1227
1231
|
|
1228
1232
|
specify "should be accessible through Sequel.connect with options" do
|
@@ -1340,7 +1344,7 @@ describe "A single threaded database" do
|
|
1340
1344
|
before do
|
1341
1345
|
conn = 1234567
|
1342
1346
|
@db = Sequel::Database.new(:single_threaded => true)
|
1343
|
-
@db
|
1347
|
+
meta_def(@db, :connect) do |c|
|
1344
1348
|
conn += 1
|
1345
1349
|
end
|
1346
1350
|
end
|
@@ -1692,7 +1696,7 @@ describe "Database#each_server" do
|
|
1692
1696
|
@db.each_server do |db|
|
1693
1697
|
dbs << db
|
1694
1698
|
Sequel::DATABASES.should include(db)
|
1695
|
-
|
1699
|
+
meta_def(db, :disconnect){dcs << db}
|
1696
1700
|
end
|
1697
1701
|
dbs.each do |db|
|
1698
1702
|
Sequel::DATABASES.should_not include(db)
|
@@ -2099,6 +2103,18 @@ describe "Database#schema_autoincrementing_primary_key?" do
|
|
2099
2103
|
end
|
2100
2104
|
end
|
2101
2105
|
|
2106
|
+
describe "Database#supports_schema_parsing?" do
|
2107
|
+
specify "should be false by default" do
|
2108
|
+
Sequel::Database.new.supports_schema_parsing?.should == false
|
2109
|
+
end
|
2110
|
+
|
2111
|
+
specify "should be true if the database implements schema_parse_table" do
|
2112
|
+
db = Sequel::Database.new
|
2113
|
+
def db.schema_parse_table(*) end
|
2114
|
+
db.supports_schema_parsing?.should == true
|
2115
|
+
end
|
2116
|
+
end
|
2117
|
+
|
2102
2118
|
describe "Database#supports_deferrable_constraints?" do
|
2103
2119
|
specify "should be false by default" do
|
2104
2120
|
Sequel::Database.new.supports_deferrable_constraints?.should == false
|
@@ -2136,8 +2152,8 @@ describe "Database#supports_savepoints_in_prepared_transactions?" do
|
|
2136
2152
|
|
2137
2153
|
specify "should be true if both savepoints and prepared transactions are supported" do
|
2138
2154
|
db = Sequel::Database.new
|
2139
|
-
|
2140
|
-
|
2155
|
+
meta_def(db, :supports_savepoints?){true}
|
2156
|
+
meta_def(db, :supports_prepared_transactions?){true}
|
2141
2157
|
db.supports_savepoints_in_prepared_transactions?.should == true
|
2142
2158
|
end
|
2143
2159
|
end
|
@@ -2259,25 +2275,31 @@ describe "Database extensions" do
|
|
2259
2275
|
before(:all) do
|
2260
2276
|
class << Sequel
|
2261
2277
|
alias _extension extension
|
2278
|
+
remove_method :extension
|
2262
2279
|
def extension(*)
|
2263
2280
|
end
|
2264
2281
|
end
|
2265
2282
|
end
|
2266
2283
|
after(:all) do
|
2267
2284
|
class << Sequel
|
2285
|
+
remove_method :extension
|
2268
2286
|
alias extension _extension
|
2287
|
+
remove_method :_extension
|
2269
2288
|
end
|
2270
2289
|
end
|
2271
2290
|
before do
|
2272
2291
|
@db = Sequel.mock
|
2273
2292
|
end
|
2293
|
+
after do
|
2294
|
+
Sequel::Database.instance_variable_set(:@initialize_hook, Proc.new {|db| })
|
2295
|
+
end
|
2274
2296
|
|
2275
|
-
specify "should be able to register an extension with a module Database#extension extend the module" do
|
2297
|
+
specify "should be able to register an extension with a module have Database#extension extend the module" do
|
2276
2298
|
Sequel::Database.register_extension(:foo, Module.new{def a; 1; end})
|
2277
2299
|
@db.extension(:foo).a.should == 1
|
2278
2300
|
end
|
2279
2301
|
|
2280
|
-
specify "should be able to register an extension with a block and Database#extension call the block" do
|
2302
|
+
specify "should be able to register an extension with a block and have Database#extension call the block" do
|
2281
2303
|
@db.quote_identifiers = false
|
2282
2304
|
Sequel::Database.register_extension(:foo){|db| db.quote_identifiers = true}
|
2283
2305
|
@db.extension(:foo).quote_identifiers?.should be_true
|
@@ -2311,6 +2333,16 @@ describe "Database extensions" do
|
|
2311
2333
|
specify "should raise an Error if attempting to load an incompatible extension" do
|
2312
2334
|
proc{@db.extension(:foo2)}.should raise_error(Sequel::Error)
|
2313
2335
|
end
|
2336
|
+
|
2337
|
+
specify "should be able to load an extension into all future Databases with Database.extension" do
|
2338
|
+
Sequel::Database.register_extension(:foo, Module.new{def a; 1; end})
|
2339
|
+
Sequel::Database.register_extension(:bar, Module.new{def b; 2; end})
|
2340
|
+
Sequel::Database.extension(:foo, :bar)
|
2341
|
+
@db.should_not respond_to(:a)
|
2342
|
+
@db.should_not respond_to(:b)
|
2343
|
+
Sequel.mock.a.should == 1
|
2344
|
+
Sequel.mock.b.should == 2
|
2345
|
+
end
|
2314
2346
|
end
|
2315
2347
|
|
2316
2348
|
describe "Database specific exception classes" do
|
@@ -2339,3 +2371,42 @@ describe "Database specific exception classes" do
|
|
2339
2371
|
proc{@db.get(1)}.should raise_error(Sequel::SerializationFailure)
|
2340
2372
|
end
|
2341
2373
|
end
|
2374
|
+
|
2375
|
+
describe "Database.after_initialize" do
|
2376
|
+
after do
|
2377
|
+
Sequel::Database.instance_variable_set(:@initialize_hook, Proc.new {|db| })
|
2378
|
+
end
|
2379
|
+
|
2380
|
+
specify "should allow a block to be run after each new instance is created" do
|
2381
|
+
Sequel::Database.after_initialize{|db| db.sql_log_level = :debug }
|
2382
|
+
db = Sequel.mock
|
2383
|
+
db.sql_log_level.should == :debug
|
2384
|
+
end
|
2385
|
+
|
2386
|
+
specify "should allow multiple hooks to be registered" do
|
2387
|
+
Sequel::Database.after_initialize{|db| db.sql_log_level = :debug }
|
2388
|
+
Sequel::Database.after_initialize{|db| db.loggers << 11 }
|
2389
|
+
|
2390
|
+
db = Sequel.mock
|
2391
|
+
|
2392
|
+
db.sql_log_level.should == :debug
|
2393
|
+
db.loggers.should include(11)
|
2394
|
+
end
|
2395
|
+
|
2396
|
+
specify "should raise an error if registration is called without a block" do
|
2397
|
+
proc {
|
2398
|
+
Sequel::Database.after_initialize
|
2399
|
+
}.should raise_error(Sequel::Error, /must provide block/i)
|
2400
|
+
end
|
2401
|
+
end
|
2402
|
+
|
2403
|
+
describe "Database#schema_type_class" do
|
2404
|
+
specify "should return the class or array of classes for the given type symbol" do
|
2405
|
+
db = Sequel.mock
|
2406
|
+
{:string=>String, :integer=>Integer, :date=>Date, :datetime=>[Time, DateTime],
|
2407
|
+
:time=>Sequel::SQLTime, :boolean=>[TrueClass, FalseClass], :float=>Float, :decimal=>BigDecimal,
|
2408
|
+
:blob=>Sequel::SQL::Blob}.each do |sym, klass|
|
2409
|
+
db.schema_type_class(sym).should == klass
|
2410
|
+
end
|
2411
|
+
end
|
2412
|
+
end
|