sequel 3.20.0 → 3.21.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.
- data/CHANGELOG +32 -0
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/Rakefile +13 -3
- data/bin/sequel +18 -5
- data/doc/active_record.rdoc +4 -4
- data/doc/opening_databases.rdoc +38 -1
- data/doc/release_notes/3.21.0.txt +87 -0
- data/doc/validations.rdoc +2 -2
- data/lib/sequel/adapters/informix.rb +1 -1
- data/lib/sequel/adapters/jdbc/h2.rb +2 -5
- data/lib/sequel/adapters/jdbc/mssql.rb +1 -4
- data/lib/sequel/adapters/jdbc/mysql.rb +1 -4
- data/lib/sequel/adapters/jdbc/postgresql.rb +1 -6
- data/lib/sequel/adapters/jdbc/sqlite.rb +2 -8
- data/lib/sequel/adapters/shared/mssql.rb +8 -0
- data/lib/sequel/adapters/shared/mysql.rb +23 -3
- data/lib/sequel/adapters/shared/oracle.rb +2 -2
- data/lib/sequel/adapters/tinytds.rb +125 -0
- data/lib/sequel/database/connecting.rb +1 -1
- data/lib/sequel/database/schema_methods.rb +37 -5
- data/lib/sequel/dataset/sql.rb +6 -6
- data/lib/sequel/extensions/schema_dumper.rb +1 -1
- data/lib/sequel/model/base.rb +50 -0
- data/lib/sequel/model/plugins.rb +0 -55
- data/lib/sequel/plugins/association_autoreloading.rb +48 -0
- data/lib/sequel/plugins/validation_class_methods.rb +6 -5
- data/lib/sequel/plugins/validation_helpers.rb +2 -2
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/firebird_spec.rb +6 -6
- data/spec/adapters/informix_spec.rb +2 -2
- data/spec/adapters/mssql_spec.rb +18 -13
- data/spec/adapters/mysql_spec.rb +47 -20
- data/spec/adapters/oracle_spec.rb +40 -4
- data/spec/adapters/postgres_spec.rb +14 -14
- data/spec/adapters/spec_helper.rb +1 -1
- data/spec/adapters/sqlite_spec.rb +8 -8
- data/spec/core/connection_pool_spec.rb +18 -17
- data/spec/core/core_sql_spec.rb +18 -18
- data/spec/core/database_spec.rb +62 -62
- data/spec/core/dataset_spec.rb +105 -92
- data/spec/core/expression_filters_spec.rb +2 -2
- data/spec/core/schema_spec.rb +6 -6
- data/spec/core/version_spec.rb +1 -1
- data/spec/extensions/association_autoreloading_spec.rb +94 -0
- data/spec/extensions/blank_spec.rb +6 -6
- data/spec/extensions/looser_typecasting_spec.rb +1 -1
- data/spec/extensions/migration_spec.rb +6 -6
- data/spec/extensions/pagination_spec.rb +2 -2
- data/spec/extensions/pretty_table_spec.rb +2 -2
- data/spec/extensions/query_spec.rb +2 -2
- data/spec/extensions/schema_dumper_spec.rb +2 -1
- data/spec/extensions/single_table_inheritance_spec.rb +1 -1
- data/spec/extensions/sql_expr_spec.rb +1 -1
- data/spec/extensions/string_date_time_spec.rb +4 -4
- data/spec/extensions/validation_class_methods_spec.rb +2 -2
- data/spec/integration/dataset_test.rb +8 -3
- data/spec/integration/plugin_test.rb +5 -5
- data/spec/integration/prepared_statement_test.rb +1 -1
- data/spec/integration/schema_test.rb +7 -0
- data/spec/integration/spec_helper.rb +14 -1
- data/spec/integration/timezone_test.rb +4 -4
- data/spec/integration/type_test.rb +1 -1
- data/spec/model/model_spec.rb +3 -3
- metadata +9 -4
@@ -72,7 +72,7 @@ module Sequel
|
|
72
72
|
|
73
73
|
# Check attribute value(s) is included in the given set.
|
74
74
|
def validates_includes(set, atts, opts={})
|
75
|
-
validatable_attributes_for_type(:includes, atts, opts){|a,v,m| validation_error_message(m, set) unless set.
|
75
|
+
validatable_attributes_for_type(:includes, atts, opts){|a,v,m| validation_error_message(m, set) unless set.send(set.respond_to?(:cover?) ? :cover? : :include?, v)}
|
76
76
|
end
|
77
77
|
|
78
78
|
# Check attribute value(s) string representation is a valid integer.
|
@@ -89,7 +89,7 @@ module Sequel
|
|
89
89
|
|
90
90
|
# Check that the attribute values length is in the specified range.
|
91
91
|
def validates_length_range(range, atts, opts={})
|
92
|
-
validatable_attributes_for_type(:length_range, atts, opts){|a,v,m| validation_error_message(m, range) unless v && range.
|
92
|
+
validatable_attributes_for_type(:length_range, atts, opts){|a,v,m| validation_error_message(m, range) unless v && range.send(range.respond_to?(:cover?) ? :cover? : :include?, v.length)}
|
93
93
|
end
|
94
94
|
|
95
95
|
# Check that the attribute values are not longer than the given max length.
|
data/lib/sequel/version.rb
CHANGED
@@ -3,7 +3,7 @@ module Sequel
|
|
3
3
|
MAJOR = 3
|
4
4
|
# The minor version of Sequel. Bumped for every non-patch level
|
5
5
|
# release, generally around once a month.
|
6
|
-
MINOR =
|
6
|
+
MINOR = 21
|
7
7
|
# The tiny version of Sequel. Usually 0, only bumped for bugfix
|
8
8
|
# releases that fix regressions from previous versions.
|
9
9
|
TINY = 0
|
@@ -43,7 +43,7 @@ FIREBIRD_DB.create_table! :test6 do
|
|
43
43
|
String :val4, :text=>true
|
44
44
|
end
|
45
45
|
|
46
|
-
|
46
|
+
describe "A Firebird database" do
|
47
47
|
before do
|
48
48
|
@db = FIREBIRD_DB
|
49
49
|
end
|
@@ -60,7 +60,7 @@ context "A Firebird database" do
|
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
-
|
63
|
+
describe "A Firebird dataset" do
|
64
64
|
before do
|
65
65
|
@d = FIREBIRD_DB[:test]
|
66
66
|
@d.delete # remove all records
|
@@ -230,7 +230,7 @@ context "A Firebird dataset" do
|
|
230
230
|
end
|
231
231
|
end
|
232
232
|
|
233
|
-
|
233
|
+
describe "A Firebird dataset with a timestamp field" do
|
234
234
|
before do
|
235
235
|
@d = FIREBIRD_DB[:test3]
|
236
236
|
@d.delete
|
@@ -244,7 +244,7 @@ context "A Firebird dataset with a timestamp field" do
|
|
244
244
|
end
|
245
245
|
end
|
246
246
|
|
247
|
-
|
247
|
+
describe "A Firebird database" do
|
248
248
|
before do
|
249
249
|
@db = FIREBIRD_DB
|
250
250
|
@db.drop_table(:posts) rescue nil
|
@@ -353,7 +353,7 @@ context "A Firebird database" do
|
|
353
353
|
end
|
354
354
|
end
|
355
355
|
|
356
|
-
|
356
|
+
describe "Postgres::Dataset#insert" do
|
357
357
|
before do
|
358
358
|
@ds = FIREBIRD_DB[:test5]
|
359
359
|
@ds.delete
|
@@ -387,7 +387,7 @@ context "Postgres::Dataset#insert" do
|
|
387
387
|
end
|
388
388
|
end
|
389
389
|
|
390
|
-
|
390
|
+
describe "Postgres::Dataset#insert" do
|
391
391
|
before do
|
392
392
|
@ds = FIREBIRD_DB[:test6]
|
393
393
|
@ds.delete
|
@@ -15,7 +15,7 @@ INFORMIX_DB.create_table :test do
|
|
15
15
|
index :value
|
16
16
|
end
|
17
17
|
|
18
|
-
|
18
|
+
describe "A Informix database" do
|
19
19
|
specify "should provide disconnect functionality" do
|
20
20
|
INFORMIX_DB.execute("select user from dual")
|
21
21
|
INFORMIX_DB.pool.size.should == 1
|
@@ -24,7 +24,7 @@ context "A Informix database" do
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
|
27
|
+
describe "A Informix dataset" do
|
28
28
|
before do
|
29
29
|
@d = INFORMIX_DB[:test]
|
30
30
|
@d.delete # remove all records
|
data/spec/adapters/mssql_spec.rb
CHANGED
@@ -34,7 +34,7 @@ MSSQL_DB.create_table! :test4 do
|
|
34
34
|
varbinary :value
|
35
35
|
end
|
36
36
|
|
37
|
-
|
37
|
+
describe "A MSSQL database" do
|
38
38
|
before do
|
39
39
|
@db = MSSQL_DB
|
40
40
|
end
|
@@ -59,7 +59,7 @@ context "A MSSQL database" do
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
-
|
62
|
+
describe "MSSQL Dataset#join_table" do
|
63
63
|
specify "should emulate the USING clause with ON" do
|
64
64
|
MSSQL_DB[:items].join(:categories, [:id]).sql.should ==
|
65
65
|
'SELECT * FROM ITEMS INNER JOIN CATEGORIES ON (CATEGORIES.ID = ITEMS.ID)'
|
@@ -71,7 +71,7 @@ context "MSSQL Dataset#join_table" do
|
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
-
|
74
|
+
describe "MSSQL Dataset#output" do
|
75
75
|
before do
|
76
76
|
@db = MSSQL_DB
|
77
77
|
@db.create_table!(:items){String :name; Integer :value}
|
@@ -150,13 +150,13 @@ context "MSSQL Dataset#output" do
|
|
150
150
|
end
|
151
151
|
end
|
152
152
|
|
153
|
-
|
153
|
+
describe "MSSQL dataset" do
|
154
154
|
before do
|
155
155
|
@db = MSSQL_DB
|
156
156
|
@ds = MSSQL_DB[:t]
|
157
157
|
end
|
158
158
|
|
159
|
-
|
159
|
+
describe "using #with and #with_recursive" do
|
160
160
|
before do
|
161
161
|
@ds1 = @ds.with(:t, @db[:x])
|
162
162
|
@ds2 = @ds.with_recursive(:t, @db[:x], @db[:t])
|
@@ -177,7 +177,12 @@ context "MSSQL dataset" do
|
|
177
177
|
@ds2.insert_sql(@db[:t]).should == 'WITH T AS (SELECT * FROM X UNION ALL SELECT * FROM T) INSERT INTO T SELECT * FROM T'
|
178
178
|
end
|
179
179
|
|
180
|
-
|
180
|
+
specify "should move WITH clause on joined dataset to top level" do
|
181
|
+
@db[:s].inner_join(@ds1).sql.should == "WITH T AS (SELECT * FROM X) SELECT * FROM S INNER JOIN (SELECT * FROM T) AS T1"
|
182
|
+
@ds1.inner_join(@db[:s].with(:s, @db[:y])).sql.should == "WITH T AS (SELECT * FROM X), S AS (SELECT * FROM Y) SELECT * FROM T INNER JOIN (SELECT * FROM S) AS T1"
|
183
|
+
end
|
184
|
+
|
185
|
+
describe "on #import" do
|
181
186
|
before do
|
182
187
|
@db = @db.clone
|
183
188
|
class << @db
|
@@ -213,7 +218,7 @@ context "MSSQL dataset" do
|
|
213
218
|
end
|
214
219
|
end
|
215
220
|
|
216
|
-
|
221
|
+
describe "MSSQL joined datasets" do
|
217
222
|
before do
|
218
223
|
@db = MSSQL_DB
|
219
224
|
end
|
@@ -325,7 +330,7 @@ describe "Common Table Expressions" do
|
|
325
330
|
end
|
326
331
|
end
|
327
332
|
|
328
|
-
|
333
|
+
describe "MSSSQL::Dataset#insert" do
|
329
334
|
before do
|
330
335
|
@db = MSSQL_DB
|
331
336
|
@db.create_table!(:test5){primary_key :xid; Integer :value}
|
@@ -352,13 +357,13 @@ context "MSSSQL::Dataset#insert" do
|
|
352
357
|
end
|
353
358
|
end
|
354
359
|
|
355
|
-
|
360
|
+
describe "MSSSQL::Dataset#disable_insert_output" do
|
356
361
|
specify "should play nicely with simple_select_all?" do
|
357
362
|
MSSQL_DB[:test].disable_insert_output.send(:simple_select_all?).should == true
|
358
363
|
end
|
359
364
|
end
|
360
365
|
|
361
|
-
|
366
|
+
describe "MSSSQL::Dataset#into" do
|
362
367
|
before do
|
363
368
|
@db = MSSQL_DB
|
364
369
|
end
|
@@ -377,7 +382,7 @@ context "MSSSQL::Dataset#into" do
|
|
377
382
|
end
|
378
383
|
end
|
379
384
|
|
380
|
-
|
385
|
+
describe "A MSSQL database" do
|
381
386
|
before do
|
382
387
|
@db = MSSQL_DB
|
383
388
|
end
|
@@ -403,7 +408,7 @@ context "A MSSQL database" do
|
|
403
408
|
end
|
404
409
|
end
|
405
410
|
|
406
|
-
|
411
|
+
describe "MSSQL::Database#rename_table" do
|
407
412
|
specify "should work on non-schema bound tables which need escaping" do
|
408
413
|
MSSQL_DB.quote_identifiers = true
|
409
414
|
MSSQL_DB.create_table! :'foo bar' do
|
@@ -426,7 +431,7 @@ context "MSSQL::Database#rename_table" do
|
|
426
431
|
end
|
427
432
|
end
|
428
433
|
|
429
|
-
|
434
|
+
describe "MSSQL::Dataset#count" do
|
430
435
|
specify "should work with a distinct query with an order clause" do
|
431
436
|
MSSQL_DB.create_table!(:items){String :name; Integer :value}
|
432
437
|
MSSQL_DB[:items].insert(:name => "name", :value => 1)
|
data/spec/adapters/mysql_spec.rb
CHANGED
@@ -34,7 +34,7 @@ SQL_BEGIN = 'BEGIN'
|
|
34
34
|
SQL_ROLLBACK = 'ROLLBACK'
|
35
35
|
SQL_COMMIT = 'COMMIT'
|
36
36
|
|
37
|
-
|
37
|
+
describe "MySQL", '#create_table' do
|
38
38
|
before do
|
39
39
|
@db = MYSQL_DB
|
40
40
|
MYSQL_DB.sqls.clear
|
@@ -84,7 +84,7 @@ context "MySQL", '#create_table' do
|
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
87
|
-
|
87
|
+
describe "A MySQL database" do
|
88
88
|
specify "should provide the server version" do
|
89
89
|
MYSQL_DB.server_version.should >= 40000
|
90
90
|
end
|
@@ -99,7 +99,7 @@ context "A MySQL database" do
|
|
99
99
|
end
|
100
100
|
|
101
101
|
if MYSQL_DB.adapter_scheme == :mysql
|
102
|
-
|
102
|
+
describe "Sequel::MySQL.convert_tinyint_to_bool" do
|
103
103
|
before do
|
104
104
|
@db = MYSQL_DB
|
105
105
|
@db.create_table(:booltest){column :b, 'tinyint(1)'; column :i, 'tinyint(4)'}
|
@@ -148,7 +148,7 @@ if MYSQL_DB.adapter_scheme == :mysql
|
|
148
148
|
end
|
149
149
|
end
|
150
150
|
|
151
|
-
|
151
|
+
describe "A MySQL dataset" do
|
152
152
|
before do
|
153
153
|
MYSQL_DB.create_table(:items){String :name; Integer :value}
|
154
154
|
@d = MYSQL_DB[:items]
|
@@ -243,7 +243,7 @@ context "A MySQL dataset" do
|
|
243
243
|
end
|
244
244
|
end
|
245
245
|
|
246
|
-
|
246
|
+
describe "MySQL datasets" do
|
247
247
|
before do
|
248
248
|
@d = MYSQL_DB[:orders]
|
249
249
|
end
|
@@ -282,7 +282,7 @@ describe "Dataset#distinct" do
|
|
282
282
|
end
|
283
283
|
end
|
284
284
|
|
285
|
-
|
285
|
+
describe "MySQL join expressions" do
|
286
286
|
before do
|
287
287
|
@ds = MYSQL_DB[:nodes]
|
288
288
|
@ds.db.meta_def(:server_version) {50014}
|
@@ -333,7 +333,7 @@ context "MySQL join expressions" do
|
|
333
333
|
end
|
334
334
|
end
|
335
335
|
|
336
|
-
|
336
|
+
describe "Joined MySQL dataset" do
|
337
337
|
before do
|
338
338
|
@ds = MYSQL_DB[:nodes]
|
339
339
|
end
|
@@ -357,7 +357,7 @@ context "Joined MySQL dataset" do
|
|
357
357
|
end
|
358
358
|
end
|
359
359
|
|
360
|
-
|
360
|
+
describe "A MySQL database" do
|
361
361
|
before do
|
362
362
|
@db = MYSQL_DB
|
363
363
|
end
|
@@ -424,7 +424,7 @@ context "A MySQL database" do
|
|
424
424
|
end
|
425
425
|
end
|
426
426
|
|
427
|
-
|
427
|
+
describe "A MySQL database with table options" do
|
428
428
|
before do
|
429
429
|
@options = {:engine=>'MyISAM', :charset=>'latin1', :collate => 'latin1_swedish_ci'}
|
430
430
|
|
@@ -461,7 +461,7 @@ context "A MySQL database with table options" do
|
|
461
461
|
end
|
462
462
|
end
|
463
463
|
|
464
|
-
|
464
|
+
describe "A MySQL database" do
|
465
465
|
before do
|
466
466
|
@db = MYSQL_DB
|
467
467
|
@db.drop_table(:items) rescue nil
|
@@ -547,7 +547,7 @@ end
|
|
547
547
|
|
548
548
|
# Socket tests should only be run if the MySQL server is on localhost
|
549
549
|
if %w'localhost 127.0.0.1 ::1'.include?(MYSQL_URI.host) and MYSQL_DB.adapter_scheme == :mysql
|
550
|
-
|
550
|
+
describe "A MySQL database" do
|
551
551
|
specify "should accept a socket option" do
|
552
552
|
db = Sequel.mysql(MYSQL_DB.opts[:database], :host => 'localhost', :user => MYSQL_DB.opts[:user], :password => MYSQL_DB.opts[:password], :socket => MYSQL_SOCKET_FILE)
|
553
553
|
proc {db.test_connection}.should_not raise_error
|
@@ -565,7 +565,7 @@ if %w'localhost 127.0.0.1 ::1'.include?(MYSQL_URI.host) and MYSQL_DB.adapter_sch
|
|
565
565
|
end
|
566
566
|
end
|
567
567
|
|
568
|
-
|
568
|
+
describe "A MySQL database" do
|
569
569
|
specify "should accept a read_timeout option when connecting" do
|
570
570
|
db = Sequel.connect(MYSQL_DB.opts.merge(:read_timeout=>22342))
|
571
571
|
proc {db.test_connection}.should_not raise_error
|
@@ -577,7 +577,7 @@ context "A MySQL database" do
|
|
577
577
|
end
|
578
578
|
end
|
579
579
|
|
580
|
-
|
580
|
+
describe "A grouped MySQL dataset" do
|
581
581
|
before do
|
582
582
|
MYSQL_DB[:test2].delete
|
583
583
|
MYSQL_DB[:test2] << {:name => '11', :value => 10}
|
@@ -599,7 +599,7 @@ context "A grouped MySQL dataset" do
|
|
599
599
|
end
|
600
600
|
end
|
601
601
|
|
602
|
-
|
602
|
+
describe "A MySQL database" do
|
603
603
|
before do
|
604
604
|
@db = MYSQL_DB
|
605
605
|
@db.drop_table(:posts) rescue nil
|
@@ -668,7 +668,7 @@ context "A MySQL database" do
|
|
668
668
|
end
|
669
669
|
end
|
670
670
|
|
671
|
-
|
671
|
+
describe "MySQL::Dataset#insert and related methods" do
|
672
672
|
before do
|
673
673
|
MYSQL_DB.create_table(:items){String :name; Integer :value}
|
674
674
|
@d = MYSQL_DB[:items]
|
@@ -853,7 +853,7 @@ context "MySQL::Dataset#insert and related methods" do
|
|
853
853
|
|
854
854
|
end
|
855
855
|
|
856
|
-
|
856
|
+
describe "MySQL::Dataset#replace" do
|
857
857
|
before do
|
858
858
|
MYSQL_DB.create_table(:items){Integer :id, :unique=>true; Integer :value}
|
859
859
|
@d = MYSQL_DB[:items]
|
@@ -895,7 +895,7 @@ context "MySQL::Dataset#replace" do
|
|
895
895
|
end
|
896
896
|
end
|
897
897
|
|
898
|
-
|
898
|
+
describe "MySQL::Dataset#complex_expression_sql" do
|
899
899
|
before do
|
900
900
|
@d = MYSQL_DB.dataset
|
901
901
|
end
|
@@ -923,8 +923,35 @@ context "MySQL::Dataset#complex_expression_sql" do
|
|
923
923
|
end
|
924
924
|
end
|
925
925
|
|
926
|
+
describe "MySQL::Dataset#calc_found_rows" do
|
927
|
+
before do
|
928
|
+
MYSQL_DB.create_table!(:items){Integer :a}
|
929
|
+
end
|
930
|
+
after do
|
931
|
+
MYSQL_DB.drop_table(:items)
|
932
|
+
end
|
933
|
+
|
934
|
+
specify "should add the SQL_CALC_FOUND_ROWS keyword when selecting" do
|
935
|
+
MYSQL_DB[:items].select(:a).calc_found_rows.limit(1).sql.should == \
|
936
|
+
'SELECT SQL_CALC_FOUND_ROWS a FROM items LIMIT 1'
|
937
|
+
end
|
938
|
+
|
939
|
+
specify "should count matching rows disregarding LIMIT clause" do
|
940
|
+
MYSQL_DB[:items].multi_insert([{:a => 1}, {:a => 1}, {:a => 2}])
|
941
|
+
MYSQL_DB.sqls.clear
|
942
|
+
|
943
|
+
MYSQL_DB[:items].calc_found_rows.filter(:a => 1).limit(1).all.should == [{:a => 1}]
|
944
|
+
MYSQL_DB.dataset.select(:FOUND_ROWS.sql_function.as(:rows)).all.should == [{:rows => 2 }]
|
945
|
+
|
946
|
+
MYSQL_DB.sqls.should == [
|
947
|
+
'SELECT SQL_CALC_FOUND_ROWS * FROM items WHERE (a = 1) LIMIT 1',
|
948
|
+
'SELECT FOUND_ROWS() AS rows',
|
949
|
+
]
|
950
|
+
end
|
951
|
+
end
|
952
|
+
|
926
953
|
if MYSQL_DB.adapter_scheme == :mysql or MYSQL_DB.adapter_scheme == :jdbc
|
927
|
-
|
954
|
+
describe "MySQL Stored Procedures" do
|
928
955
|
before do
|
929
956
|
MYSQL_DB.create_table(:items){Integer :id; Integer :value}
|
930
957
|
@d = MYSQL_DB[:items]
|
@@ -969,7 +996,7 @@ if MYSQL_DB.adapter_scheme == :mysql or MYSQL_DB.adapter_scheme == :jdbc
|
|
969
996
|
end
|
970
997
|
|
971
998
|
if MYSQL_DB.adapter_scheme == :mysql
|
972
|
-
|
999
|
+
describe "MySQL bad date/time conversions" do
|
973
1000
|
after do
|
974
1001
|
Sequel::MySQL.convert_invalid_date_time = false
|
975
1002
|
end
|
@@ -1000,7 +1027,7 @@ if MYSQL_DB.adapter_scheme == :mysql
|
|
1000
1027
|
end
|
1001
1028
|
end
|
1002
1029
|
|
1003
|
-
|
1030
|
+
describe "MySQL multiple result sets" do
|
1004
1031
|
before do
|
1005
1032
|
MYSQL_DB.create_table!(:a){Integer :a}
|
1006
1033
|
MYSQL_DB.create_table!(:b){Integer :b}
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
|
2
|
+
require "timeout"
|
2
3
|
|
3
4
|
unless defined?(ORACLE_DB)
|
4
5
|
ORACLE_DB = Sequel.connect('oracle://hr:hr@localhost/XE')
|
@@ -32,7 +33,7 @@ ORACLE_DB.create_table :categories do
|
|
32
33
|
varchar2 :cat_name, :size => 50
|
33
34
|
end
|
34
35
|
|
35
|
-
|
36
|
+
describe "An Oracle database" do
|
36
37
|
specify "should provide disconnect functionality" do
|
37
38
|
ORACLE_DB.execute("select user from dual")
|
38
39
|
ORACLE_DB.pool.size.should == 1
|
@@ -74,7 +75,7 @@ context "An Oracle database" do
|
|
74
75
|
end
|
75
76
|
end
|
76
77
|
|
77
|
-
|
78
|
+
describe "An Oracle dataset" do
|
78
79
|
before do
|
79
80
|
@d = ORACLE_DB[:items]
|
80
81
|
@d.delete # remove all records
|
@@ -222,7 +223,7 @@ context "An Oracle dataset" do
|
|
222
223
|
end
|
223
224
|
end
|
224
225
|
|
225
|
-
|
226
|
+
describe "Joined Oracle dataset" do
|
226
227
|
before do
|
227
228
|
@d1 = ORACLE_DB[:books]
|
228
229
|
@d1.delete # remove all records
|
@@ -263,7 +264,7 @@ context "Joined Oracle dataset" do
|
|
263
264
|
end
|
264
265
|
end
|
265
266
|
|
266
|
-
|
267
|
+
describe "Oracle aliasing" do
|
267
268
|
before do
|
268
269
|
@d1 = ORACLE_DB[:books]
|
269
270
|
@d1.delete # remove all records
|
@@ -284,3 +285,38 @@ context "Oracle aliasing" do
|
|
284
285
|
@d1.select(:title).group_by(:title).count.should == 2
|
285
286
|
end
|
286
287
|
end
|
288
|
+
|
289
|
+
describe "Row locks in Oracle" do
|
290
|
+
before do
|
291
|
+
@d1 = ORACLE_DB[:books]
|
292
|
+
@d1.delete # remove all records
|
293
|
+
@d1 << {:id => 1, :title => 'aaa'}
|
294
|
+
end
|
295
|
+
|
296
|
+
specify "#for_update should use FOR UPDATE" do
|
297
|
+
@d1.for_update.sql.should == "SELECT * FROM BOOKS FOR UPDATE"
|
298
|
+
end
|
299
|
+
|
300
|
+
specify "#lock_style should accept symbols" do
|
301
|
+
@d1.lock_style(:update).sql.should == "SELECT * FROM BOOKS FOR UPDATE"
|
302
|
+
end
|
303
|
+
|
304
|
+
specify "should not update during row lock" do
|
305
|
+
ORACLE_DB.transaction do
|
306
|
+
@d1.filter(:id => 1).for_update.to_a
|
307
|
+
proc do
|
308
|
+
t1 = Thread.start do
|
309
|
+
# wait for unlock
|
310
|
+
Timeout::timeout(0.02) do
|
311
|
+
ORACLE_DB[:books].filter(:id => 1).update(:title => "bbb")
|
312
|
+
end
|
313
|
+
end
|
314
|
+
t1.join
|
315
|
+
end.should raise_error
|
316
|
+
@d1.filter(:id => 1).first[:title].should == "aaa"
|
317
|
+
end
|
318
|
+
t2 = Thread.start { ORACLE_DB[:books].filter(:id => 1).update(:title => "bbb") }
|
319
|
+
t2.join
|
320
|
+
@d1.filter(:id => 1).first[:title].should == "bbb"
|
321
|
+
end
|
322
|
+
end
|