sequel 3.2.0 → 3.3.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.
Files changed (50) hide show
  1. data/CHANGELOG +40 -0
  2. data/Rakefile +1 -1
  3. data/doc/opening_databases.rdoc +7 -0
  4. data/doc/release_notes/3.3.0.txt +192 -0
  5. data/lib/sequel/adapters/ado.rb +34 -39
  6. data/lib/sequel/adapters/ado/mssql.rb +30 -0
  7. data/lib/sequel/adapters/jdbc.rb +27 -4
  8. data/lib/sequel/adapters/jdbc/h2.rb +14 -3
  9. data/lib/sequel/adapters/jdbc/mssql.rb +51 -0
  10. data/lib/sequel/adapters/mysql.rb +28 -12
  11. data/lib/sequel/adapters/odbc.rb +36 -30
  12. data/lib/sequel/adapters/odbc/mssql.rb +44 -0
  13. data/lib/sequel/adapters/shared/mssql.rb +185 -10
  14. data/lib/sequel/adapters/shared/mysql.rb +9 -9
  15. data/lib/sequel/adapters/shared/sqlite.rb +45 -47
  16. data/lib/sequel/connection_pool.rb +8 -5
  17. data/lib/sequel/core.rb +2 -8
  18. data/lib/sequel/database.rb +9 -10
  19. data/lib/sequel/database/schema_sql.rb +3 -2
  20. data/lib/sequel/dataset.rb +1 -0
  21. data/lib/sequel/dataset/sql.rb +15 -6
  22. data/lib/sequel/extensions/schema_dumper.rb +7 -7
  23. data/lib/sequel/model/associations.rb +16 -14
  24. data/lib/sequel/model/base.rb +25 -7
  25. data/lib/sequel/plugins/association_proxies.rb +41 -0
  26. data/lib/sequel/plugins/many_through_many.rb +0 -1
  27. data/lib/sequel/sql.rb +8 -11
  28. data/lib/sequel/version.rb +1 -1
  29. data/spec/adapters/mysql_spec.rb +42 -38
  30. data/spec/adapters/sqlite_spec.rb +0 -4
  31. data/spec/core/database_spec.rb +22 -1
  32. data/spec/core/dataset_spec.rb +37 -12
  33. data/spec/core/expression_filters_spec.rb +5 -0
  34. data/spec/core/schema_spec.rb +15 -8
  35. data/spec/extensions/association_proxies_spec.rb +47 -0
  36. data/spec/extensions/caching_spec.rb +2 -2
  37. data/spec/extensions/hook_class_methods_spec.rb +6 -6
  38. data/spec/extensions/many_through_many_spec.rb +13 -0
  39. data/spec/extensions/schema_dumper_spec.rb +12 -4
  40. data/spec/extensions/validation_class_methods_spec.rb +3 -3
  41. data/spec/integration/dataset_test.rb +47 -17
  42. data/spec/integration/prepared_statement_test.rb +5 -5
  43. data/spec/integration/schema_test.rb +111 -34
  44. data/spec/model/associations_spec.rb +128 -11
  45. data/spec/model/hooks_spec.rb +7 -6
  46. data/spec/model/model_spec.rb +54 -4
  47. data/spec/model/record_spec.rb +2 -3
  48. data/spec/model/validations_spec.rb +4 -4
  49. metadata +109 -101
  50. data/spec/adapters/ado_spec.rb +0 -93
@@ -288,7 +288,13 @@ module Sequel
288
288
  @dataset_methods.each{|meth, block| @dataset.meta_def(meth, &block)} if @dataset_methods
289
289
  end
290
290
  @dataset.model = self if @dataset.respond_to?(:model=)
291
- @db_schema = (inherited ? superclass.db_schema : get_db_schema) rescue nil
291
+ begin
292
+ @db_schema = (inherited ? superclass.db_schema : get_db_schema)
293
+ rescue Sequel::DatabaseConnectionError
294
+ raise
295
+ rescue
296
+ nil
297
+ end
292
298
  self
293
299
  end
294
300
  alias dataset= set_dataset
@@ -390,7 +396,15 @@ module Sequel
390
396
  ds_opts = dataset.opts
391
397
  single_table = ds_opts[:from] && (ds_opts[:from].length == 1) \
392
398
  && !ds_opts.include?(:join) && !ds_opts.include?(:sql)
393
- get_columns = proc{columns rescue []}
399
+ get_columns = proc do
400
+ begin
401
+ columns
402
+ rescue Sequel::DatabaseConnectionError
403
+ raise
404
+ rescue
405
+ []
406
+ end
407
+ end
394
408
  if single_table && (schema_array = (db.schema(table_name, :reload=>reload) rescue nil))
395
409
  schema_array.each{|k,v| schema_hash[k] = v}
396
410
  if ds_opts.include?(:select)
@@ -405,9 +419,12 @@ module Sequel
405
419
  # returned by the schema.
406
420
  cols = schema_array.collect{|k,v| k}
407
421
  set_columns(cols)
408
- # Set the primary key(s) based on the schema information
409
- pks = schema_array.collect{|k,v| k if v[:primary_key]}.compact
410
- pks.length > 0 ? set_primary_key(*pks) : no_primary_key
422
+ # Set the primary key(s) based on the schema information,
423
+ # if the schema information includes primary key information
424
+ if schema_array.all?{|k,v| v.has_key?(:primary_key)}
425
+ pks = schema_array.collect{|k,v| k if v[:primary_key]}.compact
426
+ pks.length > 0 ? set_primary_key(*pks) : no_primary_key
427
+ end
411
428
  # Also set the columns for the dataset, so the dataset
412
429
  # doesn't have to do a query to get them.
413
430
  dataset.instance_variable_set(:@columns, cols)
@@ -819,13 +836,14 @@ module Sequel
819
836
  else
820
837
  return save_failure(:update) if before_update == false
821
838
  if columns.empty?
822
- @columns_updated = opts[:changed] ? @values.reject{|k,v| !changed_columns.include?(k)} : @values
839
+ @columns_updated = opts[:changed] ? @values.reject{|k,v| !changed_columns.include?(k)} : @values.dup
823
840
  changed_columns.clear
824
841
  else # update only the specified columns
825
842
  @columns_updated = @values.reject{|k, v| !columns.include?(k)}
826
843
  changed_columns.reject!{|c| columns.include?(c)}
827
844
  end
828
- this.update(@columns_updated)
845
+ Array(primary_key).each{|x| @columns_updated.delete(x)}
846
+ this.update(@columns_updated) unless @columns_updated.empty?
829
847
  after_update
830
848
  after_save
831
849
  @columns_updated = nil
@@ -0,0 +1,41 @@
1
+ module Sequel
2
+ module Plugins
3
+ # Sequel by default does not use proxies for associations. The association
4
+ # method for *_to_many associations returns an array, and the association_dataset
5
+ # method returns a dataset. This plugin makes the association method return a proxy
6
+ # that will load the association and call a method on the association array if sent
7
+ # an array method, and otherwise send the method to the association's dataset.
8
+ module AssociationProxies
9
+ # A proxy for the association. Calling an array method will load the
10
+ # associated objects and call the method on the associated object array.
11
+ # Calling any other method will call that method on the association's dataset.
12
+ class AssociationProxy < BasicObject
13
+ # Empty array used to check if an array responds to the given method.
14
+ ARRAY = []
15
+
16
+ # Set the association reflection to use, and whether the association should be
17
+ # reloaded if an array method is called.
18
+ def initialize(instance, reflection, reload=nil)
19
+ @instance = instance
20
+ @reflection = reflection
21
+ @reload = reload
22
+ end
23
+
24
+ # Call the method given on the array of associated objects if the method
25
+ # is an array method, otherwise call the method on the association's dataset.
26
+ def method_missing(meth, *args, &block)
27
+ (ARRAY.respond_to?(meth) ? @instance.send(:load_associated_objects, @reflection, @reload) : @instance.send(@reflection.dataset_method)).
28
+ send(meth, *args, &block)
29
+ end
30
+ end
31
+
32
+ module ClassMethods
33
+ # Changes the association method to return a proxy instead of the associated objects
34
+ # directly.
35
+ def def_association_method(opts)
36
+ opts.returns_array? ? association_module_def(opts.association_method){|*r| AssociationProxy.new(self, opts, r[0])} : super
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -125,7 +125,6 @@ module Sequel
125
125
  name = opts[:name]
126
126
  model = self
127
127
  opts[:read_only] = true
128
- opts[:class_name] ||= camelize(singularize(name))
129
128
  opts[:after_load].unshift(:array_uniq!) if opts[:uniq]
130
129
  opts[:cartesian_product_number] ||= 2
131
130
  opts[:through] = opts[:through].map do |e|
data/lib/sequel/sql.rb CHANGED
@@ -1,4 +1,10 @@
1
1
  module Sequel
2
+ if RUBY_VERSION < '1.9.0'
3
+ class BasicObject
4
+ (instance_methods - %w"__id__ __send__ instance_eval == equal?").each{|m| undef_method(m)}
5
+ end
6
+ end
7
+
2
8
  class LiteralString < ::String
3
9
  end
4
10
 
@@ -776,15 +782,6 @@ module Sequel
776
782
  to_s_method :subscript_sql
777
783
  end
778
784
 
779
- if RUBY_VERSION >= '1.9.0'
780
- class VirtualRow < BasicObject
781
- end
782
- else
783
- class VirtualRow
784
- (instance_methods - %w"__id__ __send__ instance_eval == equal?").each{|m| undef_method(m)}
785
- end
786
- end
787
-
788
785
  # The purpose of this class is to allow the easy creation of SQL identifiers and functions
789
786
  # without relying on methods defined on Symbol. This is useful if another library defines
790
787
  # the methods defined by Sequel, or if you are running on ruby 1.9.
@@ -830,7 +827,7 @@ module Sequel
830
827
  # ds.select{rank(:over){}} # SELECT rank() OVER () FROM t
831
828
  # ds.select{count(:over, :*=>true){}} # SELECT count(*) OVER () FROM t
832
829
  # ds.select{sum(:over, :args=>col1, :partition=>col2, :order=>col3){}} # SELECT sum(col1) OVER (PARTITION BY col2 ORDER BY col3) FROM t
833
- class VirtualRow
830
+ class VirtualRow < BasicObject
834
831
  WILDCARD = LiteralString.new('*').freeze
835
832
  QUESTION_MARK = LiteralString.new('?').freeze
836
833
  COMMA_SEPARATOR = LiteralString.new(', ').freeze
@@ -888,7 +885,7 @@ module Sequel
888
885
  end
889
886
 
890
887
  # A WindowFunction is a grouping of a function with a window over which it operates.
891
- class WindowFunction < Expression
888
+ class WindowFunction < GenericExpression
892
889
  # The function to use, should be an SQL::Function.
893
890
  attr_reader :function
894
891
 
@@ -1,6 +1,6 @@
1
1
  module Sequel
2
2
  MAJOR = 3
3
- MINOR = 2
3
+ MINOR = 3
4
4
  TINY = 0
5
5
 
6
6
  VERSION = [MAJOR, MINOR, TINY].join('.')
@@ -65,48 +65,52 @@ context "MySQL", '#create_table' do
65
65
  end
66
66
 
67
67
  context "A MySQL database" do
68
- before do
69
- @db = MYSQL_DB
70
- @db.create_table(:booltest){TrueClass :value}
71
- end
72
- after do
73
- Sequel.convert_tinyint_to_bool = true
74
- @db.drop_table(:booltest)
75
- end
76
-
77
68
  specify "should provide the server version" do
78
- @db.server_version.should >= 40000
69
+ MYSQL_DB.server_version.should >= 40000
79
70
  end
71
+ end
80
72
 
81
- specify "should correctly parse the schema" do
82
- @db.schema(:booltest, :reload=>true).should == [[:value, {:type=>:boolean, :allow_null=>true, :primary_key=>false, :default=>nil, :ruby_default=>nil, :db_type=>"tinyint(4)"}]]
83
-
84
- Sequel.convert_tinyint_to_bool = false
85
- @db.schema(:booltest, :reload=>true).should == [[:value, {:type=>:integer, :allow_null=>true, :primary_key=>false, :default=>nil, :ruby_default=>nil, :db_type=>"tinyint(4)"}]]
86
- end
87
-
88
- specify "should accept and return tinyints as bools or integers when configured to do so" do
89
- MYSQL_DB[:booltest].delete
90
- MYSQL_DB[:booltest] << {:value=>true}
91
- MYSQL_DB[:booltest].all.should == [{:value=>true}]
92
- MYSQL_DB[:booltest].delete
93
- MYSQL_DB[:booltest] << {:value=>false}
94
- MYSQL_DB[:booltest].all.should == [{:value=>false}]
73
+ if MYSQL_DB.class.adapter_scheme == :mysql
74
+ context "Sequel::MySQL.convert_tinyint_to_bool" do
75
+ before do
76
+ @db = MYSQL_DB
77
+ @db.create_table(:booltest){column :b, 'tinyint(1)'; column :i, 'tinyint(4)'}
78
+ @ds = @db[:booltest]
79
+ end
80
+ after do
81
+ Sequel::MySQL.convert_tinyint_to_bool = true
82
+ @db.drop_table(:booltest)
83
+ end
95
84
 
96
- Sequel.convert_tinyint_to_bool = false
97
- MYSQL_DB[:booltest].delete
98
- MYSQL_DB[:booltest] << {:value=>true}
99
- MYSQL_DB[:booltest].all.should == [{:value=>1}]
100
- MYSQL_DB[:booltest].delete
101
- MYSQL_DB[:booltest] << {:value=>false}
102
- MYSQL_DB[:booltest].all.should == [{:value=>0}]
85
+ specify "should consider tinyint(1) datatypes as boolean if set, but not larger tinyints" do
86
+ @db.schema(:booltest, :reload=>true).should == [[:b, {:type=>:boolean, :allow_null=>true, :primary_key=>false, :default=>nil, :ruby_default=>nil, :db_type=>"tinyint(1)"}, ], [:i, {:type=>:integer, :allow_null=>true, :primary_key=>false, :default=>nil, :ruby_default=>nil, :db_type=>"tinyint(4)"}, ]]
87
+ Sequel::MySQL.convert_tinyint_to_bool = false
88
+ @db.schema(:booltest, :reload=>true).should == [[:b, {:type=>:integer, :allow_null=>true, :primary_key=>false, :default=>nil, :ruby_default=>nil, :db_type=>"tinyint(1)"}, ], [:i, {:type=>:integer, :allow_null=>true, :primary_key=>false, :default=>nil, :ruby_default=>nil, :db_type=>"tinyint(4)"}, ]]
89
+ end
103
90
 
104
- MYSQL_DB[:booltest].delete
105
- MYSQL_DB[:booltest] << {:value=>1}
106
- MYSQL_DB[:booltest].all.should == [{:value=>1}]
107
- MYSQL_DB[:booltest].delete
108
- MYSQL_DB[:booltest] << {:value=>0}
109
- MYSQL_DB[:booltest].all.should == [{:value=>0}]
91
+ specify "should return tinyints as bools when set" do
92
+ @ds.delete
93
+ @ds << {:b=>true, :i=>10}
94
+ @ds.all.should == [{:b=>true, :i=>true}]
95
+ @ds.delete
96
+ @ds << {:b=>false, :i=>0}
97
+ @ds.all.should == [{:b=>false, :i=>false}]
98
+
99
+ Sequel::MySQL.convert_tinyint_to_bool = false
100
+ @ds.delete
101
+ @ds << {:b=>true, :i=>10}
102
+ @ds.all.should == [{:b=>1, :i=>10}]
103
+ @ds.delete
104
+ @ds << {:b=>false, :i=>0}
105
+ @ds.all.should == [{:b=>0, :i=>0}]
106
+
107
+ @ds.delete
108
+ @ds << {:b=>1, :i=>10}
109
+ @ds.all.should == [{:b=>1, :i=>10}]
110
+ @ds.delete
111
+ @ds << {:b=>0, :i=>0}
112
+ @ds.all.should == [{:b=>0, :i=>0}]
113
+ end
110
114
  end
111
115
  end
112
116
 
@@ -411,7 +415,7 @@ context "A MySQL database" do
411
415
 
412
416
  specify "should support defaults for boolean columns" do
413
417
  @db.create_table(:items){TrueClass :active1, :default=>true; FalseClass :active2, :default => false}
414
- @db.sqls.should == ["CREATE TABLE items (active1 tinyint DEFAULT 1, active2 tinyint DEFAULT 0)"]
418
+ @db.sqls.should == ["CREATE TABLE items (active1 tinyint(1) DEFAULT 1, active2 tinyint(1) DEFAULT 0)"]
415
419
  end
416
420
 
417
421
  specify "should correctly format CREATE TABLE statements with foreign keys" do
@@ -377,10 +377,6 @@ context "A SQLite database" do
377
377
  @db[:test3_backup2].columns.should == [:l]
378
378
  end
379
379
 
380
- specify "should not support set_column_type operations" do
381
- proc {@db.set_column_type :test2, :value, :integer}.should raise_error(Sequel::Error)
382
- end
383
-
384
380
  specify "should support add_index" do
385
381
  @db.add_index :test2, :value, :unique => true
386
382
  @db.add_index :test2, [:name, :value]
@@ -839,13 +839,34 @@ context "A Database adapter with a scheme" do
839
839
  end
840
840
 
841
841
  specify "should be accessible through Sequel.connect with URL parameters" do
842
- c = Sequel.connect 'ccc://localhost/db?host=/tmp&user=test'
842
+ c = Sequel.connect 'ccc:///db?host=/tmp&user=test'
843
843
  c.should be_a_kind_of(CCC)
844
844
  c.opts[:host].should == '/tmp'
845
845
  c.opts[:database].should == 'db'
846
846
  c.opts[:user].should == 'test'
847
847
  end
848
+
849
+ specify "should have URL parameters take precedence over fixed URL parts" do
850
+ c = Sequel.connect 'ccc://localhost/db?host=a&database=b'
851
+ c.should be_a_kind_of(CCC)
852
+ c.opts[:host].should == 'a'
853
+ c.opts[:database].should == 'b'
854
+ end
855
+
856
+ specify "should have hash options take predence over URL parameters or parts" do
857
+ c = Sequel.connect 'ccc://localhost/db?host=/tmp', :host=>'a', :database=>'b', :user=>'c'
858
+ c.should be_a_kind_of(CCC)
859
+ c.opts[:host].should == 'a'
860
+ c.opts[:database].should == 'b'
861
+ c.opts[:user].should == 'c'
862
+ end
848
863
 
864
+ specify "should unescape values of URL parameters and parts" do
865
+ c = Sequel.connect 'ccc:///d%5bb%5d?host=domain%5cinstance'
866
+ c.should be_a_kind_of(CCC)
867
+ c.opts[:database].should == 'd[b]'
868
+ c.opts[:host].should == 'domain\\instance'
869
+ end
849
870
  end
850
871
 
851
872
  context "Sequel::Database.connect" do
@@ -92,6 +92,16 @@ context "Dataset" do
92
92
  @dataset.identifier_output_method = :reverse
93
93
  @dataset.send(:output_identifier, "at_b_C").should == :C_b_ta
94
94
  end
95
+
96
+ specify "should have output_identifier handle empty identifiers" do
97
+ @dataset.send(:output_identifier, "").should == :untitled
98
+ @dataset.identifier_output_method = :upcase
99
+ @dataset.send(:output_identifier, "").should == :UNTITLED
100
+ @dataset.identifier_output_method = :downcase
101
+ @dataset.send(:output_identifier, "").should == :untitled
102
+ @dataset.identifier_output_method = :reverse
103
+ @dataset.send(:output_identifier, "").should == :deltitnu
104
+ end
95
105
  end
96
106
 
97
107
  context "Dataset#clone" do
@@ -1008,24 +1018,20 @@ context "Dataset#order" do
1008
1018
  end
1009
1019
 
1010
1020
  context "Dataset#unfiltered" do
1011
- before do
1012
- @dataset = Sequel::Dataset.new(nil).from(:test)
1013
- end
1014
-
1015
1021
  specify "should remove filtering from the dataset" do
1016
- @dataset.filter(:score=>1).unfiltered.sql.should ==
1017
- 'SELECT * FROM test'
1022
+ Sequel::Dataset.new(nil).from(:test).filter(:score=>1).unfiltered.sql.should == 'SELECT * FROM test'
1018
1023
  end
1019
1024
  end
1020
1025
 
1021
- context "Dataset#unordered" do
1022
- before do
1023
- @dataset = Sequel::Dataset.new(nil).from(:test)
1026
+ context "Dataset#unlimited" do
1027
+ specify "should remove limit and offset from the dataset" do
1028
+ Sequel::Dataset.new(nil).from(:test).limit(1, 2).unlimited.sql.should == 'SELECT * FROM test'
1024
1029
  end
1025
-
1030
+ end
1031
+
1032
+ context "Dataset#unordered" do
1026
1033
  specify "should remove ordering from the dataset" do
1027
- @dataset.order(:name).unordered.sql.should ==
1028
- 'SELECT * FROM test'
1034
+ Sequel::Dataset.new(nil).from(:test).order(:name).unordered.sql.should == 'SELECT * FROM test'
1029
1035
  end
1030
1036
  end
1031
1037
 
@@ -1389,6 +1395,25 @@ context "Dataset#empty?" do
1389
1395
  end
1390
1396
  end
1391
1397
 
1398
+ context "Dataset#from_self" do
1399
+ before do
1400
+ @ds = Sequel::Dataset.new(nil).from(:test).select(:name).limit(1)
1401
+ end
1402
+ specify "should set up a default alias" do
1403
+ @ds.from_self.sql.should == 'SELECT * FROM (SELECT name FROM test LIMIT 1) AS t1'
1404
+ end
1405
+ specify "should modify only the new dataset" do
1406
+ @ds.from_self.select(:bogus).sql.should == 'SELECT bogus FROM (SELECT name FROM test LIMIT 1) AS t1'
1407
+ end
1408
+ specify "should use the user-specified alias" do
1409
+ @ds.from_self(:alias=>:some_name).sql.should == 'SELECT * FROM (SELECT name FROM test LIMIT 1) AS some_name'
1410
+ end
1411
+ specify "should use the user-specified alias for joins" do
1412
+ @ds.from_self(:alias=>:some_name).inner_join(:posts, :alias=>:name).sql.should == \
1413
+ 'SELECT * FROM (SELECT name FROM test LIMIT 1) AS some_name INNER JOIN posts ON (posts.alias = some_name.name)'
1414
+ end
1415
+ end
1416
+
1392
1417
  context "Dataset#join_table" do
1393
1418
  before do
1394
1419
  @d = MockDataset.new(nil).from(:items)
@@ -520,6 +520,10 @@ context Sequel::SQL::VirtualRow do
520
520
  @d.l{rank(:over, :frame=>:rows){}}.should == 'rank() OVER (ROWS UNBOUNDED PRECEDING)'
521
521
  end
522
522
 
523
+ it "should raise an error if an invalid :frame option is used" do
524
+ proc{@d.l{rank(:over, :frame=>:blah){}}}.should raise_error(Sequel::Error)
525
+ end
526
+
523
527
  it "should support all these options together" do
524
528
  @d.l{count(:over, :* =>true, :partition=>a, :order=>b, :window=>:win, :frame=>:rows){}}.should == 'count(*) OVER ("win" PARTITION BY "a" ORDER BY "b" ROWS UNBOUNDED PRECEDING)'
525
529
  end
@@ -527,5 +531,6 @@ context Sequel::SQL::VirtualRow do
527
531
  it "should raise an error if window functions are not supported" do
528
532
  @d.meta_def(:supports_window_functions?){false}
529
533
  proc{@d.l{count(:over, :* =>true, :partition=>a, :order=>b, :window=>:win, :frame=>:rows){}}}.should raise_error(Sequel::Error)
534
+ proc{Sequel::Dataset.new(nil).filter{count(:over, :* =>true, :partition=>a, :order=>b, :window=>:win, :frame=>:rows){}}.sql}.should raise_error(Sequel::Error)
530
535
  end
531
536
  end
@@ -107,16 +107,18 @@ context "DB#create_table" do
107
107
  @db.create_table(:cats) do
108
108
  integer :id
109
109
  text :name, :null => false
110
+ text :name2, :allow_null => false
110
111
  end
111
- @db.sqls.should == ["CREATE TABLE cats (id integer, name text NOT NULL)"]
112
+ @db.sqls.should == ["CREATE TABLE cats (id integer, name text NOT NULL, name2 text NOT NULL)"]
112
113
  end
113
114
 
114
115
  specify "should accept null definition" do
115
116
  @db.create_table(:cats) do
116
117
  integer :id
117
118
  text :name, :null => true
119
+ text :name2, :allow_null => true
118
120
  end
119
- @db.sqls.should == ["CREATE TABLE cats (id integer, name text NULL)"]
121
+ @db.sqls.should == ["CREATE TABLE cats (id integer, name text NULL, name2 text NULL)"]
120
122
  end
121
123
 
122
124
  specify "should accept unique definition" do
@@ -744,9 +746,6 @@ context "Schema Parser" do
744
746
  @sqls = []
745
747
  @db = Sequel::Database.new
746
748
  end
747
- after do
748
- Sequel.convert_tinyint_to_bool = true
749
- end
750
749
 
751
750
  specify "should raise an error if there are no columns" do
752
751
  @db.meta_def(:schema_parse_table) do |t, opts|
@@ -788,9 +787,7 @@ context "Schema Parser" do
788
787
  @db.meta_def(:schema_parse_table) do |t, opts|
789
788
  [[:x, {:type=>schema_column_type(t.to_s)}]]
790
789
  end
791
- @db.schema(:tinyint).first.last[:type].should == :boolean
792
- Sequel.convert_tinyint_to_bool = false
793
- @db.schema(:tinyint, :reload=>true).first.last[:type].should == :integer
790
+ @db.schema(:tinyint).first.last[:type].should == :integer
794
791
  @db.schema(:interval).first.last[:type].should == :interval
795
792
  @db.schema(:int).first.last[:type].should == :integer
796
793
  @db.schema(:integer).first.last[:type].should == :integer
@@ -810,6 +807,7 @@ context "Schema Parser" do
810
807
  @db.schema(:"time with time zone").first.last[:type].should == :time
811
808
  @db.schema(:"time without time zone").first.last[:type].should == :time
812
809
  @db.schema(:boolean).first.last[:type].should == :boolean
810
+ @db.schema(:bit).first.last[:type].should == :boolean
813
811
  @db.schema(:real).first.last[:type].should == :float
814
812
  @db.schema(:float).first.last[:type].should == :float
815
813
  @db.schema(:double).first.last[:type].should == :float
@@ -818,5 +816,14 @@ context "Schema Parser" do
818
816
  @db.schema(:decimal).first.last[:type].should == :decimal
819
817
  @db.schema(:money).first.last[:type].should == :decimal
820
818
  @db.schema(:bytea).first.last[:type].should == :blob
819
+ @db.schema(:blob).first.last[:type].should == :blob
820
+ @db.schema(:image).first.last[:type].should == :blob
821
+ @db.schema(:nchar).first.last[:type].should == :string
822
+ @db.schema(:nvarchar).first.last[:type].should == :string
823
+ @db.schema(:ntext).first.last[:type].should == :string
824
+ @db.schema(:smalldatetime).first.last[:type].should == :datetime
825
+ @db.schema(:smallmoney).first.last[:type].should == :decimal
826
+ @db.schema(:binary).first.last[:type].should == :blob
827
+ @db.schema(:varbinary).first.last[:type].should == :blob
821
828
  end
822
829
  end