sequel 3.46.0 → 3.47.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.
- 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
|