sequel 2.10.0 → 2.11.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 +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
|