sequel 2.10.0 → 2.11.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +51 -1
- data/README.rdoc +2 -2
- data/Rakefile +2 -2
- data/doc/advanced_associations.rdoc +6 -18
- data/doc/release_notes/1.0.txt +38 -0
- data/doc/release_notes/1.1.txt +143 -0
- data/doc/release_notes/1.3.txt +101 -0
- data/doc/release_notes/1.4.0.txt +53 -0
- data/doc/release_notes/1.5.0.txt +155 -0
- data/doc/release_notes/2.0.0.txt +298 -0
- data/doc/release_notes/2.1.0.txt +271 -0
- data/doc/release_notes/2.10.0.txt +328 -0
- data/doc/release_notes/2.11.0.txt +215 -0
- data/doc/release_notes/2.2.0.txt +253 -0
- data/doc/release_notes/2.3.0.txt +88 -0
- data/doc/release_notes/2.4.0.txt +106 -0
- data/doc/release_notes/2.5.0.txt +137 -0
- data/doc/release_notes/2.6.0.txt +157 -0
- data/doc/release_notes/2.7.0.txt +166 -0
- data/doc/release_notes/2.8.0.txt +171 -0
- data/doc/release_notes/2.9.0.txt +97 -0
- data/lib/sequel_core/adapters/ado.rb +3 -0
- data/lib/sequel_core/adapters/db2.rb +0 -11
- data/lib/sequel_core/adapters/dbi.rb +0 -11
- data/lib/sequel_core/adapters/do.rb +0 -12
- data/lib/sequel_core/adapters/firebird.rb +21 -16
- data/lib/sequel_core/adapters/informix.rb +1 -11
- data/lib/sequel_core/adapters/jdbc.rb +1 -13
- data/lib/sequel_core/adapters/jdbc/h2.rb +3 -11
- data/lib/sequel_core/adapters/jdbc/mysql.rb +0 -17
- data/lib/sequel_core/adapters/jdbc/postgresql.rb +3 -15
- data/lib/sequel_core/adapters/mysql.rb +31 -27
- data/lib/sequel_core/adapters/odbc.rb +34 -28
- data/lib/sequel_core/adapters/openbase.rb +0 -11
- data/lib/sequel_core/adapters/oracle.rb +11 -9
- data/lib/sequel_core/adapters/postgres.rb +14 -17
- data/lib/sequel_core/adapters/shared/mssql.rb +6 -15
- data/lib/sequel_core/adapters/shared/mysql.rb +29 -14
- data/lib/sequel_core/adapters/shared/oracle.rb +4 -0
- data/lib/sequel_core/adapters/shared/postgres.rb +30 -35
- data/lib/sequel_core/adapters/shared/progress.rb +4 -0
- data/lib/sequel_core/adapters/shared/sqlite.rb +73 -13
- data/lib/sequel_core/adapters/sqlite.rb +8 -18
- data/lib/sequel_core/adapters/utils/date_format.rb +21 -0
- data/lib/sequel_core/{dataset → adapters/utils}/stored_procedures.rb +0 -0
- data/lib/sequel_core/{dataset → adapters/utils}/unsupported.rb +0 -0
- data/lib/sequel_core/core_ext.rb +1 -1
- data/lib/sequel_core/core_sql.rb +9 -4
- data/lib/sequel_core/database.rb +63 -62
- data/lib/sequel_core/dataset.rb +9 -4
- data/lib/sequel_core/dataset/convenience.rb +10 -9
- data/lib/sequel_core/dataset/prepared_statements.rb +1 -1
- data/lib/sequel_core/dataset/sql.rb +130 -36
- data/lib/sequel_core/schema/sql.rb +2 -2
- data/lib/sequel_core/sql.rb +44 -51
- data/lib/sequel_core/version.rb +1 -1
- data/lib/sequel_model/associations.rb +25 -17
- data/lib/sequel_model/base.rb +35 -7
- data/lib/sequel_model/caching.rb +1 -6
- data/lib/sequel_model/record.rb +23 -5
- data/lib/sequel_model/validations.rb +20 -5
- data/spec/adapters/firebird_spec.rb +6 -1
- data/spec/adapters/mysql_spec.rb +12 -0
- data/spec/adapters/postgres_spec.rb +2 -2
- data/spec/adapters/sqlite_spec.rb +81 -2
- data/spec/integration/dataset_test.rb +2 -2
- data/spec/integration/type_test.rb +12 -2
- data/spec/sequel_core/core_sql_spec.rb +46 -12
- data/spec/sequel_core/database_spec.rb +24 -12
- data/spec/sequel_core/dataset_spec.rb +82 -32
- data/spec/sequel_core/schema_spec.rb +16 -0
- data/spec/sequel_model/associations_spec.rb +89 -0
- data/spec/sequel_model/base_spec.rb +66 -0
- data/spec/sequel_model/eager_loading_spec.rb +32 -0
- data/spec/sequel_model/record_spec.rb +9 -9
- data/spec/sequel_model/spec_helper.rb +3 -0
- data/spec/sequel_model/validations_spec.rb +63 -3
- metadata +41 -4
@@ -69,8 +69,7 @@ module Sequel
|
|
69
69
|
# Defines validations by converting a longhand block into a series of
|
70
70
|
# shorthand definitions. For example:
|
71
71
|
#
|
72
|
-
# class MyClass
|
73
|
-
# include Validation
|
72
|
+
# class MyClass < Sequel::Model
|
74
73
|
# validates do
|
75
74
|
# length_of :name, :minimum => 6
|
76
75
|
# length_of :password, :minimum => 8
|
@@ -78,8 +77,7 @@ module Sequel
|
|
78
77
|
# end
|
79
78
|
#
|
80
79
|
# is equivalent to:
|
81
|
-
# class MyClass
|
82
|
-
# include Validation
|
80
|
+
# class MyClass < Sequel::Model
|
83
81
|
# validates_length_of :name, :minimum => 6
|
84
82
|
# validates_length_of :password, :minimum => 8
|
85
83
|
# end
|
@@ -223,7 +221,7 @@ module Sequel
|
|
223
221
|
# * :minimum - The minimum size allowed for the value (no default)
|
224
222
|
# * :too_long - The message to use use if it the value is too long (default: 'is too long')
|
225
223
|
# * :too_short - The message to use use if it the value is too short (default: 'is too short')
|
226
|
-
# * :
|
224
|
+
# * :within - The array/range that must include the size of the value for it to be valid (no default)
|
227
225
|
# * :wrong_length - The message to use use if it the value is not valid (default: 'is the wrong length')
|
228
226
|
def self.validates_length_of(*atts)
|
229
227
|
opts = {
|
@@ -317,6 +315,23 @@ module Sequel
|
|
317
315
|
o.errors[a] << opts[:message] if v.blank? && v != false
|
318
316
|
end
|
319
317
|
end
|
318
|
+
|
319
|
+
# Validates that an attribute is within a specified range or set of values.
|
320
|
+
#
|
321
|
+
# Possible Options:
|
322
|
+
# * :in - An array or range of values to check for validity (required)
|
323
|
+
# * :message - The message to use (default: 'is not in range or set: <specified range>')
|
324
|
+
def self.validates_inclusion_of(*atts)
|
325
|
+
opts = atts.extract_options!
|
326
|
+
unless opts[:in] && opts[:in].respond_to?(:include?)
|
327
|
+
raise ArgumentError, "The :in parameter is required, and respond to include?"
|
328
|
+
end
|
329
|
+
opts[:message] ||= "is not in range or set: #{opts[:in].inspect}"
|
330
|
+
atts << opts
|
331
|
+
validates_each(*atts) do |o, a, v|
|
332
|
+
o.errors[a] << opts[:message] unless opts[:in].include?(v)
|
333
|
+
end
|
334
|
+
end
|
320
335
|
|
321
336
|
# Validates only if the fields in the model (specified by atts) are
|
322
337
|
# unique in the database. Pass an array of fields instead of multiple
|
@@ -334,6 +334,11 @@ context "A Firebird database" do
|
|
334
334
|
|
335
335
|
@db[:test2].first[:xyz].should == "56.40"
|
336
336
|
end
|
337
|
+
|
338
|
+
specify "should allow us to retrieve the primary key for a table" do
|
339
|
+
@db.create_table!(:test2){primary_key :id}
|
340
|
+
@db.primary_key(:test2).should == ["id"]
|
341
|
+
end
|
337
342
|
end
|
338
343
|
|
339
344
|
context "Postgres::Dataset#insert" do
|
@@ -343,7 +348,7 @@ context "Postgres::Dataset#insert" do
|
|
343
348
|
end
|
344
349
|
|
345
350
|
specify "should using call insert_returning_sql" do
|
346
|
-
@ds.should_receive(:single_value).once.with(:sql=>'INSERT INTO TEST5 (VAL) VALUES (10) RETURNING XID')
|
351
|
+
@ds.should_receive(:single_value).once.with(:sql=>'INSERT INTO TEST5 (VAL) VALUES (10) RETURNING XID', :server=> :default)
|
347
352
|
@ds.insert(:val=>10)
|
348
353
|
end
|
349
354
|
|
data/spec/adapters/mysql_spec.rb
CHANGED
@@ -858,6 +858,7 @@ unless MYSQL_DB.class.adapter_scheme == :do
|
|
858
858
|
|
859
859
|
specify "should be callable on the dataset object" do
|
860
860
|
MYSQL_DB.execute('CREATE PROCEDURE test_sproc(a INTEGER) BEGIN SELECT *, a AS b FROM items; END')
|
861
|
+
MYSQL_DB[:items].delete
|
861
862
|
@d = MYSQL_DB[:items]
|
862
863
|
@d.call_sproc(:select, :test_sproc, 3).should == []
|
863
864
|
@d.insert(:value=>1)
|
@@ -865,5 +866,16 @@ unless MYSQL_DB.class.adapter_scheme == :do
|
|
865
866
|
@d.row_proc = proc{|r| r.keys.each{|k| r[k] *= 2 if r[k].is_a?(Integer)}; r}
|
866
867
|
@d.call_sproc(:select, :test_sproc, 3).should == [{:id=>nil, :value=>2, :b=>6}]
|
867
868
|
end
|
869
|
+
|
870
|
+
specify "should be callable on the dataset object with multiple arguments" do
|
871
|
+
MYSQL_DB.execute('CREATE PROCEDURE test_sproc(a INTEGER, c INTEGER) BEGIN SELECT *, a AS b, c AS d FROM items; END')
|
872
|
+
MYSQL_DB[:items].delete
|
873
|
+
@d = MYSQL_DB[:items]
|
874
|
+
@d.call_sproc(:select, :test_sproc, 3, 4).should == []
|
875
|
+
@d.insert(:value=>1)
|
876
|
+
@d.call_sproc(:select, :test_sproc, 4, 5).should == [{:id=>nil, :value=>1, :b=>4, :d=>5}]
|
877
|
+
@d.row_proc = proc{|r| r.keys.each{|k| r[k] *= 2 if r[k].is_a?(Integer)}; r}
|
878
|
+
@d.call_sproc(:select, :test_sproc, 3, 4).should == [{:id=>nil, :value=>2, :b=>6, :d => 8}]
|
879
|
+
end
|
868
880
|
end
|
869
881
|
end
|
@@ -472,9 +472,9 @@ context "Postgres::Dataset#insert" do
|
|
472
472
|
@ds.insert(:value=>10)
|
473
473
|
end
|
474
474
|
|
475
|
-
specify "should
|
475
|
+
specify "should use INSERT RETURNING if server_version >= 80200" do
|
476
476
|
@ds.meta_def(:server_version){80201}
|
477
|
-
@ds.should_receive(:single_value).once.with(:sql=>'INSERT INTO test5 (value) VALUES (10) RETURNING xid')
|
477
|
+
@ds.should_receive(:single_value).once.with(:server=>:default, :sql=>'INSERT INTO test5 (value) VALUES (10) RETURNING xid')
|
478
478
|
@ds.insert(:value=>10)
|
479
479
|
end
|
480
480
|
|
@@ -456,8 +456,87 @@ context "A SQLite database" do
|
|
456
456
|
@db[:test3].select(:id).all.should == [{:id => 1}, {:id => 3}]
|
457
457
|
end
|
458
458
|
|
459
|
-
specify "should
|
460
|
-
|
459
|
+
specify "should support rename_column operations" do
|
460
|
+
@db[:test2].delete
|
461
|
+
@db.add_column :test2, :xyz, :text
|
462
|
+
@db[:test2] << {:name => 'mmm', :value => 111, :xyz => 'qqqq'}
|
463
|
+
|
464
|
+
@db[:test2].columns.should == [:name, :value, :xyz]
|
465
|
+
@db.rename_column :test2, :xyz, :zyx, :type => :text
|
466
|
+
@db[:test2].columns.should == [:name, :value, :zyx]
|
467
|
+
@db[:test2].first[:zyx].should == 'qqqq'
|
468
|
+
@db[:test2].count.should eql(1)
|
469
|
+
end
|
470
|
+
|
471
|
+
specify "should preserve defaults when dropping or renaming columns" do
|
472
|
+
@db.create_table! :test3 do
|
473
|
+
String :s, :default=>'a'
|
474
|
+
Integer :i
|
475
|
+
end
|
476
|
+
|
477
|
+
@db[:test3].insert
|
478
|
+
@db[:test3].first[:s].should == 'a'
|
479
|
+
@db[:test3].delete
|
480
|
+
@db.drop_column :test3, :i
|
481
|
+
@db[:test3].insert
|
482
|
+
@db[:test3].first[:s].should == 'a'
|
483
|
+
@db[:test3].delete
|
484
|
+
@db.rename_column :test3, :s, :t
|
485
|
+
@db[:test3].insert
|
486
|
+
@db[:test3].first[:t].should == 'a'
|
487
|
+
@db[:test3].delete
|
488
|
+
end
|
489
|
+
|
490
|
+
specify "should handle quoted tables when dropping or renaming columns" do
|
491
|
+
@db.quote_identifiers = true
|
492
|
+
table_name = "T T"
|
493
|
+
@db.drop_table(table_name) rescue nil
|
494
|
+
@db.create_table! table_name do
|
495
|
+
Integer :"s s"
|
496
|
+
Integer :"i i"
|
497
|
+
end
|
498
|
+
|
499
|
+
@db.from(table_name).insert(:"s s"=>1, :"i i"=>2)
|
500
|
+
@db.from(table_name).all.should == [{:"s s"=>1, :"i i"=>2}]
|
501
|
+
@db.drop_column table_name, :"i i"
|
502
|
+
@db.from(table_name).all.should == [{:"s s"=>1}]
|
503
|
+
@db.rename_column table_name, :"s s", :"t t"
|
504
|
+
@db.from(table_name).all.should == [{:"t t"=>1}]
|
505
|
+
end
|
506
|
+
|
507
|
+
specify "should choose a temporary table name that isn't already used when dropping or renaming columns" do
|
508
|
+
@db.create_table! :test3 do
|
509
|
+
Integer :h
|
510
|
+
Integer :i
|
511
|
+
end
|
512
|
+
@db.create_table! :test3_backup0 do
|
513
|
+
Integer :j
|
514
|
+
end
|
515
|
+
@db.create_table! :test3_backup1 do
|
516
|
+
Integer :k
|
517
|
+
end
|
518
|
+
|
519
|
+
@db[:test3].columns.should == [:h, :i]
|
520
|
+
@db[:test3_backup0].columns.should == [:j]
|
521
|
+
@db[:test3_backup1].columns.should == [:k]
|
522
|
+
sqls = @db.drop_column(:test3, :i)
|
523
|
+
sqls.any?{|x| x =~ /test3_backup2/}.should == true
|
524
|
+
sqls.any?{|x| x =~ /test3_backup[01]/}.should == false
|
525
|
+
@db[:test3].columns.should == [:h]
|
526
|
+
@db[:test3_backup0].columns.should == [:j]
|
527
|
+
@db[:test3_backup1].columns.should == [:k]
|
528
|
+
|
529
|
+
@db.create_table! :test3_backup2 do
|
530
|
+
Integer :l
|
531
|
+
end
|
532
|
+
|
533
|
+
sqls = @db.rename_column(:test3, :h, :i)
|
534
|
+
sqls.any?{|x| x =~ /test3_backup3/}.should == true
|
535
|
+
sqls.any?{|x| x =~ /test3_backup[012]/}.should == false
|
536
|
+
@db[:test3].columns.should == [:i]
|
537
|
+
@db[:test3_backup0].columns.should == [:j]
|
538
|
+
@db[:test3_backup1].columns.should == [:k]
|
539
|
+
@db[:test3_backup2].columns.should == [:l]
|
461
540
|
end
|
462
541
|
|
463
542
|
specify "should not support set_column_type operations" do
|
@@ -101,7 +101,7 @@ describe "Dataset UNION, EXCEPT, and INTERSECT" do
|
|
101
101
|
|
102
102
|
specify "should give the correct results for simple UNION, EXCEPT, and INTERSECT" do
|
103
103
|
@ds1.union(@ds2).order(:number).map{|x| x[:number].to_s}.should == %w'10 20 30'
|
104
|
-
unless @ds1.class.ancestors.include?(Sequel::Dataset::UnsupportedIntersectExcept)
|
104
|
+
unless defined?(Sequel::Dataset::UnsupportedIntersectExcept) and @ds1.class.ancestors.include?(Sequel::Dataset::UnsupportedIntersectExcept)
|
105
105
|
@ds1.except(@ds2).order(:number).map{|x| x[:number].to_s}.should == %w'20'
|
106
106
|
@ds1.intersect(@ds2).order(:number).map{|x| x[:number].to_s}.should == %w'10'
|
107
107
|
end
|
@@ -110,7 +110,7 @@ describe "Dataset UNION, EXCEPT, and INTERSECT" do
|
|
110
110
|
specify "should give the correct results for compound UNION, EXCEPT, and INTERSECT" do
|
111
111
|
@ds1.union(@ds2).union(@ds3).order(:number).map{|x| x[:number].to_s}.should == %w'10 20 30 40'
|
112
112
|
@ds1.union(@ds2.union(@ds3)).order(:number).map{|x| x[:number].to_s}.should == %w'10 20 30 40'
|
113
|
-
unless @ds1.class.ancestors.include?(Sequel::Dataset::UnsupportedIntersectExcept)
|
113
|
+
unless defined?(Sequel::Dataset::UnsupportedIntersectExcept) and @ds1.class.ancestors.include?(Sequel::Dataset::UnsupportedIntersectExcept)
|
114
114
|
@ds1.union(@ds2).except(@ds3).order(:number).map{|x| x[:number].to_s}.should == %w'20 30'
|
115
115
|
@ds1.union(@ds2.except(@ds3)).order(:number).map{|x| x[:number].to_s}.should == %w'10 20 30'
|
116
116
|
@ds1.union(@ds2).intersect(@ds3).order(:number).map{|x| x[:number].to_s}.should == %w'10 '
|
@@ -6,6 +6,15 @@ describe "Supported types" do
|
|
6
6
|
INTEGRATION_DB[:items]
|
7
7
|
end
|
8
8
|
|
9
|
+
specify "should support casting correctly" do
|
10
|
+
ds = create_items_table_with_column(:number, Integer)
|
11
|
+
ds.insert(:number => 1)
|
12
|
+
ds.select(:number.cast_string.as(:n)).map(:n).should == %w'1'
|
13
|
+
ds = create_items_table_with_column(:name, String)
|
14
|
+
ds.insert(:name=> '1')
|
15
|
+
ds.select(:name.cast_numeric.as(:n)).map(:n).should == [1]
|
16
|
+
end
|
17
|
+
|
9
18
|
specify "should support NULL correctly" do
|
10
19
|
ds = create_items_table_with_column(:number, Integer)
|
11
20
|
ds.insert(:number => nil)
|
@@ -71,8 +80,9 @@ describe "Supported types" do
|
|
71
80
|
|
72
81
|
specify "should support generic file type" do
|
73
82
|
ds = create_items_table_with_column(:name, File)
|
74
|
-
ds.insert(:name => ("a\0"*300).
|
75
|
-
ds.all.should == [{:name=>("a\0"*300).
|
83
|
+
ds.insert(:name => ("a\0"*300).to_sequel_blob)
|
84
|
+
ds.all.should == [{:name=>("a\0"*300).to_sequel_blob}]
|
85
|
+
ds.first[:name].should be_a_kind_of(::Sequel::SQL::Blob)
|
76
86
|
end
|
77
87
|
|
78
88
|
specify "should support generic boolean type" do
|
@@ -124,12 +124,23 @@ context "String#lit" do
|
|
124
124
|
Sequel::Database.new[:t].update_sql(:stamp => "NOW()".expr).should == \
|
125
125
|
"UPDATE t SET stamp = NOW()"
|
126
126
|
end
|
127
|
+
|
128
|
+
specify "should return a PlaceholderLiteralString object if args are given" do
|
129
|
+
a = 'DISTINCT ?'.lit(:a)
|
130
|
+
a.should be_a_kind_of(Sequel::SQL::PlaceholderLiteralString)
|
131
|
+
ds = MockDatabase.new.dataset
|
132
|
+
ds.literal(a).should == 'DISTINCT a'
|
133
|
+
ds.quote_identifiers = true
|
134
|
+
ds.literal(a).should == 'DISTINCT "a"'
|
135
|
+
end
|
127
136
|
end
|
128
137
|
|
129
|
-
context "String#to_blob" do
|
138
|
+
context "String#to_blob and #to_sequel_blob" do
|
130
139
|
specify "should return a Blob object" do
|
131
140
|
'xyz'.to_blob.should be_a_kind_of(::Sequel::SQL::Blob)
|
132
141
|
'xyz'.to_blob.should == 'xyz'
|
142
|
+
'xyz'.to_sequel_blob.should be_a_kind_of(::Sequel::SQL::Blob)
|
143
|
+
'xyz'.to_sequel_blob.should == 'xyz'
|
133
144
|
end
|
134
145
|
|
135
146
|
specify "should retain binary data" do
|
@@ -206,7 +217,7 @@ context "Column references" do
|
|
206
217
|
@c = Class.new(Sequel::Dataset) do
|
207
218
|
def quoted_identifier(c); "`#{c}`"; end
|
208
219
|
end
|
209
|
-
@ds = @c.new(
|
220
|
+
@ds = @c.new(MockDatabase.new)
|
210
221
|
@ds.quote_identifiers = true
|
211
222
|
end
|
212
223
|
|
@@ -233,15 +244,17 @@ context "Column references" do
|
|
233
244
|
end
|
234
245
|
|
235
246
|
specify "should be quoted properly in a cast function" do
|
236
|
-
@ds.literal(:x.cast_as(:integer)).should == "
|
237
|
-
@ds.literal(:x__y.cast_as('varchar(20)')).should == "
|
247
|
+
@ds.literal(:x.cast_as(:integer)).should == "CAST(`x` AS integer)"
|
248
|
+
@ds.literal(:x__y.cast_as('varchar(20)')).should == "CAST(`x`.`y` AS varchar(20))"
|
238
249
|
end
|
239
250
|
end
|
240
251
|
|
241
252
|
context "Blob" do
|
242
|
-
specify "#to_blob should return self" do
|
253
|
+
specify "#to_blob and #to_sequel_blob should return self" do
|
243
254
|
blob = "x".to_blob
|
244
255
|
blob.to_blob.object_id.should == blob.object_id
|
256
|
+
blob = "x".to_sequel_blob
|
257
|
+
blob.to_sequel_blob.object_id.should == blob.object_id
|
245
258
|
end
|
246
259
|
end
|
247
260
|
|
@@ -339,7 +352,7 @@ end
|
|
339
352
|
|
340
353
|
context "Symbol" do
|
341
354
|
setup do
|
342
|
-
@ds = Sequel::Dataset.new(
|
355
|
+
@ds = Sequel::Dataset.new(MockDatabase.new)
|
343
356
|
end
|
344
357
|
|
345
358
|
specify "should support upper case outer functions" do
|
@@ -353,28 +366,49 @@ context "Symbol" do
|
|
353
366
|
end
|
354
367
|
|
355
368
|
specify "should support cast method and its cast_as alias" do
|
356
|
-
:abc.cast_as(:integer).to_s(@ds).should == "
|
357
|
-
:abc.cast(:integer).to_s(@ds).should == "
|
369
|
+
:abc.cast_as(:integer).to_s(@ds).should == "CAST(abc AS integer)"
|
370
|
+
:abc.cast(:integer).to_s(@ds).should == "CAST(abc AS integer)"
|
358
371
|
end
|
359
372
|
|
360
373
|
specify "should support cast_numeric and cast_string" do
|
361
374
|
x = :abc.cast_numeric
|
362
375
|
x.should be_a_kind_of(Sequel::SQL::NumericExpression)
|
363
|
-
x.to_s(@ds).should == "
|
376
|
+
x.to_s(@ds).should == "CAST(abc AS integer)"
|
364
377
|
|
365
378
|
x = :abc.cast_numeric(:real)
|
366
379
|
x.should be_a_kind_of(Sequel::SQL::NumericExpression)
|
367
|
-
x.to_s(@ds).should == "
|
380
|
+
x.to_s(@ds).should == "CAST(abc AS real)"
|
368
381
|
|
369
382
|
x = :abc.cast_string
|
370
383
|
x.should be_a_kind_of(Sequel::SQL::StringExpression)
|
371
|
-
x.to_s(@ds).should == "
|
384
|
+
x.to_s(@ds).should == "CAST(abc AS varchar(255))"
|
372
385
|
|
373
386
|
x = :abc.cast_string(:varchar)
|
374
387
|
x.should be_a_kind_of(Sequel::SQL::StringExpression)
|
375
|
-
x.to_s(@ds).should == "
|
388
|
+
x.to_s(@ds).should == "CAST(abc AS varchar)"
|
376
389
|
end
|
377
390
|
|
391
|
+
specify "should allow database independent types when casting" do
|
392
|
+
m = MockDatabase.new
|
393
|
+
m.instance_eval do
|
394
|
+
def type_literal_base(column)
|
395
|
+
return :foo if column[:type] == Integer
|
396
|
+
return :bar if column[:type] == String
|
397
|
+
column
|
398
|
+
end
|
399
|
+
end
|
400
|
+
@ds2 = Sequel::Dataset.new(m)
|
401
|
+
:abc.cast_as(Integer).to_s(@ds).should == "CAST(abc AS integer)"
|
402
|
+
:abc.cast_as(Integer).to_s(@ds2).should == "CAST(abc AS foo)"
|
403
|
+
:abc.cast(String).to_s(@ds).should == "CAST(abc AS varchar(255))"
|
404
|
+
:abc.cast(String).to_s(@ds2).should == "CAST(abc AS bar)"
|
405
|
+
:abc.cast(String).to_s(@ds2).should == "CAST(abc AS bar)"
|
406
|
+
:abc.cast_string.to_s(@ds2).should == "CAST(abc AS bar)"
|
407
|
+
:abc.cast_string(Integer).to_s(@ds2).should == "CAST(abc AS foo)"
|
408
|
+
:abc.cast_numeric.to_s(@ds2).should == "CAST(abc AS foo)"
|
409
|
+
:abc.cast_numeric(String).to_s(@ds2).should == "CAST(abc AS bar)"
|
410
|
+
end
|
411
|
+
|
378
412
|
specify "should support subscript access using | operator" do
|
379
413
|
(:abc|1).to_s(@ds).should == 'abc[1]'
|
380
414
|
(:abc|[1]).to_s(@ds).should == 'abc[1]'
|
@@ -55,6 +55,12 @@ context "A new Database" do
|
|
55
55
|
db.quote_identifiers?.should == true
|
56
56
|
end
|
57
57
|
|
58
|
+
specify "should upcase on input and downcase on output by default" do
|
59
|
+
db = Sequel::Database.new
|
60
|
+
db.send(:identifier_input_method_default).should == :upcase
|
61
|
+
db.send(:identifier_output_method_default).should == :downcase
|
62
|
+
end
|
63
|
+
|
58
64
|
specify "should respect the :upcase_identifiers option" do
|
59
65
|
Sequel.upcase_identifiers = false
|
60
66
|
db = Sequel::Database.new(:upcase_identifiers=>false)
|
@@ -78,6 +84,7 @@ context "A new Database" do
|
|
78
84
|
|
79
85
|
specify "should respect the :identifier_input_method option" do
|
80
86
|
Sequel.identifier_input_method = nil
|
87
|
+
Sequel::Database.identifier_input_method.should == ""
|
81
88
|
db = Sequel::Database.new(:identifier_input_method=>nil)
|
82
89
|
db.identifier_input_method.should == nil
|
83
90
|
db.identifier_input_method = :downcase
|
@@ -87,6 +94,7 @@ context "A new Database" do
|
|
87
94
|
db.identifier_input_method = nil
|
88
95
|
db.identifier_input_method.should == nil
|
89
96
|
Sequel.identifier_input_method = :downcase
|
97
|
+
Sequel::Database.identifier_input_method.should == :downcase
|
90
98
|
db = Sequel::Database.new(:identifier_input_method=>nil)
|
91
99
|
db.identifier_input_method.should == nil
|
92
100
|
db.identifier_input_method = :upcase
|
@@ -99,6 +107,7 @@ context "A new Database" do
|
|
99
107
|
|
100
108
|
specify "should respect the :identifier_output_method option" do
|
101
109
|
Sequel.identifier_output_method = nil
|
110
|
+
Sequel::Database.identifier_output_method.should == ""
|
102
111
|
db = Sequel::Database.new(:identifier_output_method=>nil)
|
103
112
|
db.identifier_output_method.should == nil
|
104
113
|
db.identifier_output_method = :downcase
|
@@ -108,6 +117,7 @@ context "A new Database" do
|
|
108
117
|
db.identifier_output_method = nil
|
109
118
|
db.identifier_output_method.should == nil
|
110
119
|
Sequel.identifier_output_method = :downcase
|
120
|
+
Sequel::Database.identifier_output_method.should == :downcase
|
111
121
|
db = Sequel::Database.new(:identifier_output_method=>nil)
|
112
122
|
db.identifier_output_method.should == nil
|
113
123
|
db.identifier_output_method = :upcase
|
@@ -197,6 +207,13 @@ context "A new Database" do
|
|
197
207
|
db.should be_a_kind_of(Sequel::Database)
|
198
208
|
db.opts[:uri].should == 'jdbc:test://host/db_name'
|
199
209
|
end
|
210
|
+
|
211
|
+
specify "should just use a :uri option for do with the full connection string" do
|
212
|
+
Sequel::Database.should_receive(:adapter_class).once.with(:do).and_return(Sequel::Database)
|
213
|
+
db = Sequel.connect('do:test://host/db_name')
|
214
|
+
db.should be_a_kind_of(Sequel::Database)
|
215
|
+
db.opts[:uri].should == 'do:test://host/db_name'
|
216
|
+
end
|
200
217
|
end
|
201
218
|
|
202
219
|
context "Database#disconnect" do
|
@@ -228,6 +245,10 @@ context "Database#uri" do
|
|
228
245
|
specify "should return the connection URI for the database" do
|
229
246
|
@db.uri.should == 'mau://user:pass@localhost:9876/maumau'
|
230
247
|
end
|
248
|
+
|
249
|
+
specify "should be aliased as #url" do
|
250
|
+
@db.url.should == 'mau://user:pass@localhost:9876/maumau'
|
251
|
+
end
|
231
252
|
end
|
232
253
|
|
233
254
|
context "Database.adapter_scheme" do
|
@@ -1153,24 +1174,15 @@ end
|
|
1153
1174
|
|
1154
1175
|
context "Database#typecast_value" do
|
1155
1176
|
setup do
|
1156
|
-
@db = Sequel::Database.new
|
1177
|
+
@db = Sequel::Database.new
|
1157
1178
|
end
|
1158
|
-
specify "should raise InvalidValue when
|
1179
|
+
specify "should raise an Error::InvalidValue when given an invalid value" do
|
1159
1180
|
proc{@db.typecast_value(:integer, "13a")}.should raise_error(Sequel::Error::InvalidValue)
|
1160
|
-
end
|
1161
|
-
specify "should raise InvalidValue when setting invalid float" do
|
1162
1181
|
proc{@db.typecast_value(:float, "4.e2")}.should raise_error(Sequel::Error::InvalidValue)
|
1163
|
-
end
|
1164
|
-
specify "should raise InvalidValue when setting invalid decimal" do
|
1165
1182
|
proc{@db.typecast_value(:decimal, :invalid_value)}.should raise_error(Sequel::Error::InvalidValue)
|
1166
|
-
end
|
1167
|
-
specify "should raise InvalidValue when setting invalid date" do
|
1168
1183
|
proc{@db.typecast_value(:date, Object.new)}.should raise_error(Sequel::Error::InvalidValue)
|
1169
|
-
|
1170
|
-
specify "should raise InvalidValue when setting invalid time" do
|
1184
|
+
proc{@db.typecast_value(:date, 'a')}.should raise_error(Sequel::Error::InvalidValue)
|
1171
1185
|
proc{@db.typecast_value(:time, Date.new)}.should raise_error(Sequel::Error::InvalidValue)
|
1172
|
-
end
|
1173
|
-
specify "should raise InvalidValue when setting invalid datetime" do
|
1174
1186
|
proc{@db.typecast_value(:datetime, 4)}.should raise_error(Sequel::Error::InvalidValue)
|
1175
1187
|
end
|
1176
1188
|
end
|