sequel 2.12.0 → 3.0.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 (91) hide show
  1. data/CHANGELOG +62 -0
  2. data/README.rdoc +3 -3
  3. data/Rakefile +7 -0
  4. data/doc/advanced_associations.rdoc +44 -0
  5. data/doc/release_notes/3.0.0.txt +221 -0
  6. data/lib/sequel/adapters/amalgalite.rb +208 -0
  7. data/lib/sequel/adapters/db2.rb +3 -0
  8. data/lib/sequel/adapters/dbi.rb +9 -0
  9. data/lib/sequel/adapters/do.rb +0 -4
  10. data/lib/sequel/adapters/firebird.rb +16 -18
  11. data/lib/sequel/adapters/informix.rb +5 -3
  12. data/lib/sequel/adapters/jdbc.rb +24 -20
  13. data/lib/sequel/adapters/jdbc/h2.rb +15 -4
  14. data/lib/sequel/adapters/mysql.rb +4 -8
  15. data/lib/sequel/adapters/odbc.rb +0 -4
  16. data/lib/sequel/adapters/oracle.rb +0 -4
  17. data/lib/sequel/adapters/shared/mssql.rb +16 -5
  18. data/lib/sequel/adapters/shared/mysql.rb +87 -86
  19. data/lib/sequel/adapters/shared/oracle.rb +92 -3
  20. data/lib/sequel/adapters/shared/postgres.rb +85 -29
  21. data/lib/sequel/adapters/shared/progress.rb +8 -3
  22. data/lib/sequel/adapters/shared/sqlite.rb +53 -23
  23. data/lib/sequel/adapters/sqlite.rb +4 -7
  24. data/lib/sequel/adapters/utils/unsupported.rb +3 -3
  25. data/lib/sequel/connection_pool.rb +18 -25
  26. data/lib/sequel/core.rb +2 -21
  27. data/lib/sequel/database.rb +60 -44
  28. data/lib/sequel/database/schema_generator.rb +26 -31
  29. data/lib/sequel/database/schema_methods.rb +8 -3
  30. data/lib/sequel/database/schema_sql.rb +114 -28
  31. data/lib/sequel/dataset.rb +14 -41
  32. data/lib/sequel/dataset/convenience.rb +31 -54
  33. data/lib/sequel/dataset/graph.rb +7 -13
  34. data/lib/sequel/dataset/sql.rb +43 -54
  35. data/lib/sequel/extensions/inflector.rb +0 -5
  36. data/lib/sequel/extensions/schema_dumper.rb +238 -0
  37. data/lib/sequel/metaprogramming.rb +0 -20
  38. data/lib/sequel/model.rb +1 -2
  39. data/lib/sequel/model/base.rb +18 -16
  40. data/lib/sequel/model/inflections.rb +6 -9
  41. data/lib/sequel/plugins/caching.rb +0 -6
  42. data/lib/sequel/plugins/hook_class_methods.rb +1 -1
  43. data/lib/sequel/sql.rb +2 -0
  44. data/lib/sequel/version.rb +2 -2
  45. data/spec/adapters/firebird_spec.rb +35 -8
  46. data/spec/adapters/mysql_spec.rb +173 -266
  47. data/spec/adapters/oracle_spec.rb +13 -0
  48. data/spec/adapters/postgres_spec.rb +127 -227
  49. data/spec/adapters/sqlite_spec.rb +13 -171
  50. data/spec/core/connection_pool_spec.rb +15 -4
  51. data/spec/core/core_sql_spec.rb +14 -170
  52. data/spec/core/database_spec.rb +50 -132
  53. data/spec/core/dataset_spec.rb +47 -930
  54. data/spec/core/expression_filters_spec.rb +12 -0
  55. data/spec/core/schema_generator_spec.rb +37 -45
  56. data/spec/core/schema_spec.rb +26 -16
  57. data/spec/core/spec_helper.rb +0 -25
  58. data/spec/extensions/inflector_spec.rb +0 -3
  59. data/spec/extensions/schema_dumper_spec.rb +292 -0
  60. data/spec/extensions/serialization_spec.rb +9 -0
  61. data/spec/extensions/single_table_inheritance_spec.rb +6 -1
  62. data/spec/extensions/spec_helper.rb +1 -3
  63. data/spec/extensions/validation_helpers_spec.rb +4 -4
  64. data/spec/integration/database_test.rb +18 -0
  65. data/spec/integration/dataset_test.rb +112 -1
  66. data/spec/integration/eager_loader_test.rb +70 -9
  67. data/spec/integration/prepared_statement_test.rb +2 -2
  68. data/spec/integration/schema_test.rb +76 -27
  69. data/spec/integration/spec_helper.rb +0 -14
  70. data/spec/integration/transaction_test.rb +27 -0
  71. data/spec/model/associations_spec.rb +0 -36
  72. data/spec/model/base_spec.rb +18 -123
  73. data/spec/model/hooks_spec.rb +2 -235
  74. data/spec/model/inflector_spec.rb +15 -115
  75. data/spec/model/model_spec.rb +0 -120
  76. data/spec/model/plugins_spec.rb +0 -70
  77. data/spec/model/record_spec.rb +35 -93
  78. data/spec/model/spec_helper.rb +0 -27
  79. data/spec/model/validations_spec.rb +0 -931
  80. metadata +9 -14
  81. data/lib/sequel/deprecated.rb +0 -593
  82. data/lib/sequel/deprecated_migration.rb +0 -91
  83. data/lib/sequel/model/deprecated.rb +0 -204
  84. data/lib/sequel/model/deprecated_hooks.rb +0 -103
  85. data/lib/sequel/model/deprecated_inflector.rb +0 -335
  86. data/lib/sequel/model/deprecated_validations.rb +0 -388
  87. data/spec/core/core_ext_spec.rb +0 -156
  88. data/spec/core/migration_spec.rb +0 -263
  89. data/spec/core/pretty_table_spec.rb +0 -58
  90. data/spec/model/caching_spec.rb +0 -217
  91. data/spec/model/schema_spec.rb +0 -92
@@ -202,6 +202,12 @@ context "Blockless Ruby Filters" do
202
202
  @d.l(:x => nil, :y => [1,2,3])[1...-1].split(' AND ').sort.should == ['(x IS NULL)', '(y IN (1, 2, 3))']
203
203
  end
204
204
 
205
+ it "should support sql_expr on hashes" do
206
+ @d.l({:x => 100, :y => 'a'}.sql_expr)[1...-1].split(' AND ').sort.should == ['(x = 100)', '(y = \'a\')']
207
+ @d.l({:x => true, :y => false}.sql_expr)[1...-1].split(' AND ').sort.should == ['(x IS TRUE)', '(y IS FALSE)']
208
+ @d.l({:x => nil, :y => [1,2,3]}.sql_expr)[1...-1].split(' AND ').sort.should == ['(x IS NULL)', '(y IN (1, 2, 3))']
209
+ end
210
+
205
211
  it "should support sql_negate on hashes" do
206
212
  @d.l({:x => 100, :y => 'a'}.sql_negate)[1...-1].split(' AND ').sort.should == ['(x != 100)', '(y != \'a\')']
207
213
  @d.l({:x => true, :y => false}.sql_negate)[1...-1].split(' AND ').sort.should == ['(x IS NOT TRUE)', '(y IS NOT FALSE)']
@@ -226,6 +232,12 @@ context "Blockless Ruby Filters" do
226
232
  @d.l([[:x, nil], [:y, [1,2,3]]]).should == '((x IS NULL) AND (y IN (1, 2, 3)))'
227
233
  end
228
234
 
235
+ it "should support sql_expr on arrays with all two pairs" do
236
+ @d.l([[:x, 100],[:y, 'a']].sql_expr).should == '((x = 100) AND (y = \'a\'))'
237
+ @d.l([[:x, true], [:y, false]].sql_expr).should == '((x IS TRUE) AND (y IS FALSE))'
238
+ @d.l([[:x, nil], [:y, [1,2,3]]].sql_expr).should == '((x IS NULL) AND (y IN (1, 2, 3)))'
239
+ end
240
+
229
241
  it "should support sql_negate on arrays with all two pairs" do
230
242
  @d.l([[:x, 100],[:y, 'a']].sql_negate).should == '((x != 100) AND (y != \'a\'))'
231
243
  @d.l([[:x, true], [:y, false]].sql_negate).should == '((x IS NOT TRUE) AND (y IS NOT FALSE))'
@@ -10,30 +10,27 @@ describe Sequel::Schema::Generator do
10
10
  check 'price > 100'
11
11
  constraint(:xxx) {:yyy == :zzz}
12
12
  index :title
13
- index [:title, :body]
13
+ index [:title, :body], :unique => true
14
14
  foreign_key :node_id, :nodes
15
15
  primary_key [:title, :parent_id], :name => :cpk
16
16
  foreign_key [:node_id, :prop_id], :nodes_props, :name => :cfk
17
17
  end
18
- @columns, @indexes = @generator.create_info
18
+ @columns, @indexes, @constraints = @generator.columns, @generator.indexes, @generator.constraints
19
19
  end
20
20
 
21
- {:name => :id, :primary_key => true}.each do |column, expected|
22
- it "uses default primary key #{column}" do
23
- @columns.first[column].should == expected
24
- end
21
+ it "should primary key column first" do
22
+ @columns.first[:name].should == :id
23
+ @columns.first[:primary_key].should == true
24
+ @columns[3][:name].should == :parent_id
25
+ @columns[3][:primary_key].should == nil
25
26
  end
26
27
 
27
- it "counts primary key, column and constraint definitions as columns" do
28
- @columns.size.should == 9
28
+ it "counts definitions correctly" do
29
+ @columns.size.should == 5
30
+ @indexes.size.should == 2
31
+ @constraints.size.should == 4
29
32
  end
30
33
 
31
- it "places primary key first" do
32
- @columns[0][:primary_key].should be_true
33
- @columns[1][:primary_key].should_not be_true
34
- @columns[2][:primary_key].should_not be_true
35
- end
36
-
37
34
  it "retrieves primary key name" do
38
35
  @generator.primary_key_name.should == :id
39
36
  end
@@ -48,14 +45,14 @@ describe Sequel::Schema::Generator do
48
45
  it "creates foreign key column" do
49
46
  @columns[3][:name].should == :parent_id
50
47
  @columns[3][:type].should == Integer
51
- @columns[6][:name].should == :node_id
52
- @columns[6][:type].should == Integer
48
+ @columns[4][:name].should == :node_id
49
+ @columns[4][:type].should == Integer
53
50
  end
54
51
 
55
52
  it "uses table for foreign key columns, if specified" do
56
- @columns[6][:table].should == :nodes
57
53
  @columns[3][:table].should == nil
58
- @columns[8][:table].should == :nodes_props
54
+ @columns[4][:table].should == :nodes
55
+ @constraints[3][:table].should == :nodes_props
59
56
  end
60
57
 
61
58
  it "finds columns" do
@@ -66,24 +63,22 @@ describe Sequel::Schema::Generator do
66
63
  end
67
64
 
68
65
  it "creates constraints" do
69
- @columns[4][:name].should == nil
70
- @columns[4][:type].should == :check
71
- @columns[4][:check].should == ['price > 100']
66
+ @constraints[0][:name].should == nil
67
+ @constraints[0][:type].should == :check
68
+ @constraints[0][:check].should == ['price > 100']
72
69
 
73
- @columns[5][:name].should == :xxx
74
- @columns[5][:type].should == :check
75
- @columns[5][:check].should be_a_kind_of(Proc)
70
+ @constraints[1][:name].should == :xxx
71
+ @constraints[1][:type].should == :check
72
+ @constraints[1][:check].should be_a_kind_of(Proc)
76
73
 
77
- @columns[7][:name].should == :cpk
78
- @columns[7][:type].should == :check
79
- @columns[7][:constraint_type].should == :primary_key
80
- @columns[7][:columns].should == [ :title, :parent_id ]
74
+ @constraints[2][:name].should == :cpk
75
+ @constraints[2][:type].should == :primary_key
76
+ @constraints[2][:columns].should == [ :title, :parent_id ]
81
77
 
82
- @columns[8][:name].should == :cfk
83
- @columns[8][:type].should == :check
84
- @columns[8][:constraint_type].should == :foreign_key
85
- @columns[8][:columns].should == [ :node_id, :prop_id ]
86
- @columns[8][:table].should == :nodes_props
78
+ @constraints[3][:name].should == :cfk
79
+ @constraints[3][:type].should == :foreign_key
80
+ @constraints[3][:columns].should == [ :node_id, :prop_id ]
81
+ @constraints[3][:table].should == :nodes_props
87
82
  end
88
83
 
89
84
  it "creates indexes" do
@@ -103,6 +98,7 @@ describe Sequel::Schema::AlterTableGenerator do
103
98
  set_column_default :eee, 1
104
99
  add_index [:fff, :ggg]
105
100
  drop_index :hhh
101
+ drop_index :hhh, :name=>:blah_blah
106
102
  add_full_text_index :blah
107
103
  add_spatial_index :geom
108
104
  add_index :blah, :type => :hash
@@ -126,24 +122,25 @@ describe Sequel::Schema::AlterTableGenerator do
126
122
  {:op => :set_column_default, :name => :eee, :default => 1},
127
123
  {:op => :add_index, :columns => [:fff, :ggg]},
128
124
  {:op => :drop_index, :columns => [:hhh]},
125
+ {:op => :drop_index, :columns => [:hhh], :name=>:blah_blah},
129
126
  {:op => :add_index, :columns => [:blah], :type => :full_text},
130
127
  {:op => :add_index, :columns => [:geom], :type => :spatial},
131
128
  {:op => :add_index, :columns => [:blah], :type => :hash},
132
129
  {:op => :add_index, :columns => [:blah], :where => {:something => true}},
133
- {:op => :add_constraint, :type => :check, :constraint_type => :check, :name => :con1, :check => ['fred > 100']},
130
+ {:op => :add_constraint, :type => :check, :name => :con1, :check => ['fred > 100']},
134
131
  {:op => :drop_constraint, :name => :con2},
135
- {:op => :add_constraint, :type => :check, :constraint_type => :unique, :name => :con3, :columns => [:aaa, :bbb, :ccc]},
132
+ {:op => :add_constraint, :type => :unique, :name => :con3, :columns => [:aaa, :bbb, :ccc]},
136
133
  {:op => :add_column, :name => :id, :type => Integer, :primary_key=>true, :auto_increment=>true},
137
134
  {:op => :add_column, :name => :node_id, :type => Integer, :table=>:nodes},
138
- {:op => :add_constraint, :type => :check, :constraint_type => :primary_key, :columns => [:aaa, :bbb]},
139
- {:op => :add_constraint, :type => :check, :constraint_type => :foreign_key, :columns => [:node_id, :prop_id], :table => :nodes_props}
135
+ {:op => :add_constraint, :type => :primary_key, :columns => [:aaa, :bbb]},
136
+ {:op => :add_constraint, :type => :foreign_key, :columns => [:node_id, :prop_id], :table => :nodes_props}
140
137
  ]
141
138
  end
142
139
  end
143
140
 
144
141
  describe "Sequel::Schema::Generator generic type methods" do
145
- before do
146
- @generator = Sequel::Schema::Generator.new(SchemaDummyDatabase.new) do
142
+ it "should store the type class in :type for each column" do
143
+ Sequel::Schema::Generator.new(SchemaDummyDatabase.new) do
147
144
  String :a
148
145
  Integer :b
149
146
  Fixnum :c
@@ -157,11 +154,6 @@ describe "Sequel::Schema::Generator generic type methods" do
157
154
  File :k
158
155
  TrueClass :l
159
156
  FalseClass :m
160
- end
161
- @columns, @indexes = @generator.create_info
162
- end
163
-
164
- it "should store the type class in :type for each column" do
165
- @columns.map{|c| c[:type]}.should == [String, Integer, Fixnum, Bignum, Float, BigDecimal, Date, DateTime, Time, Numeric, File, TrueClass, FalseClass]
157
+ end.columns.map{|c| c[:type]}.should == [String, Integer, Fixnum, Bignum, Float, BigDecimal, Date, DateTime, Time, Numeric, File, TrueClass, FalseClass]
166
158
  end
167
159
  end
@@ -61,6 +61,21 @@ context "DB#create_table" do
61
61
  @db.sqls.should == ['CREATE TABLE cats (o varchar(255) PRIMARY KEY AUTOINCREMENT, a varchar(255), b integer, c integer, d bigint, e double precision, f numeric, g date, h timestamp, i timestamp, j numeric, k blob, l boolean, m boolean, n integer, p date REFERENCES f)']
62
62
  end
63
63
 
64
+ specify "should allow the use of modifiers with ruby class types" do
65
+ @db.create_table(:cats) do
66
+ String :a, :size=>50
67
+ String :b, :text=>true
68
+ String :c, :fixed=>true, :size=>40
69
+ Time :d, :only_time=>true
70
+ BigDecimal :e, :size=>[11,2]
71
+ end
72
+ @db.sqls.should == ['CREATE TABLE cats (a varchar(50), b text, c char(40), d time, e numeric(11, 2))']
73
+ end
74
+
75
+ specify "should raise an error if you use a ruby class that isn't handled" do
76
+ proc{@db.create_table(:cats){column :a, Class}}.should raise_error(Sequel::Error)
77
+ end
78
+
64
79
  specify "should accept primary key definition" do
65
80
  @db.create_table(:cats) do
66
81
  primary_key :id
@@ -404,6 +419,10 @@ context "DB#create_table" do
404
419
  @db.sqls.should == ["CREATE TABLE cats (CONSTRAINT blah_blah CHECK ((x > 0) AND (y < 1)))"]
405
420
  end
406
421
 
422
+ specify "should raise an error if an invalid constraint type is used" do
423
+ proc{@db.create_table(:cats){unique [:a, :b], :type=>:bb}}.should raise_error(Sequel::Error)
424
+ end
425
+
407
426
  specify "should accept composite primary keys" do
408
427
  @db.create_table(:cats) do
409
428
  integer :a
@@ -646,6 +665,13 @@ context "DB#alter_table" do
646
665
  @db.sqls.should == ["DROP INDEX cats_name_index"]
647
666
  end
648
667
 
668
+ specify "should support drop_index with a given name" do
669
+ @db.alter_table(:cats) do
670
+ drop_index :name, :name=>:blah_blah
671
+ end
672
+ @db.sqls.should == ["DROP INDEX blah_blah"]
673
+ end
674
+
649
675
  specify "should support rename_column" do
650
676
  @db.alter_table(:cats) do
651
677
  rename_column :name, :old_name
@@ -710,22 +736,6 @@ context "Schema Parser" do
710
736
  @sqls.should == ['x', 'x']
711
737
  end
712
738
 
713
- deprec_specify "should parse the schema correctly for all tables" do
714
- sqls = @sqls
715
- proc{@db.schema}.should raise_error(Sequel::Error)
716
- @db.meta_def(:tables){[:x]}
717
- @db.meta_def(:schema_parse_table) do |t, opts|
718
- sqls << t
719
- [[:x, {:db_type=>t.to_s}]]
720
- end
721
- @db.schema.should == {'x'=>[[:x, {:db_type=>"x"}]]}
722
- @sqls.should == ['x']
723
- @db.schema.should == {'x'=>[[:x, {:db_type=>"x"}]]}
724
- @sqls.should == ['x']
725
- @db.schema(nil, :reload=>true).should == {'x'=>[[:x, {:db_type=>"x"}]]}
726
- @sqls.should == ['x', 'x']
727
- end
728
-
729
739
  specify "should convert various types of table name arguments" do
730
740
  @db.meta_def(:schema_parse_table) do |t, opts|
731
741
  [[t, {:db_type=>t}]]
@@ -6,31 +6,6 @@ end
6
6
 
7
7
  Sequel.virtual_row_instance_eval = true
8
8
 
9
- module Spec::Example::ExampleMethods
10
- def deprec
11
- output = Sequel::Deprecation.output = nil
12
- begin
13
- yield
14
- ensure
15
- Sequel::Deprecation.output = output
16
- end
17
- end
18
- end
19
-
20
- module Spec::Example::ExampleGroupMethods
21
- def deprec_specify(*args, &block)
22
- specify(*args) do
23
- output = Sequel::Deprecation.output
24
- Sequel::Deprecation.output = nil
25
- begin
26
- instance_eval(&block)
27
- ensure
28
- Sequel::Deprecation.output = output
29
- end
30
- end
31
- end
32
- end
33
-
34
9
  class MockDataset < Sequel::Dataset
35
10
  def insert(*args)
36
11
  @db.execute insert_sql(*args)
@@ -86,9 +86,6 @@ describe String::Inflections do
86
86
  String.inflections.plurals.replace(@plurals)
87
87
  String.inflections.singulars.replace(@singulars)
88
88
  String.inflections.uncountables.replace(@uncountables)
89
- Sequel.inflections.plurals.replace(@plurals)
90
- Sequel.inflections.singulars.replace(@singulars)
91
- Sequel.inflections.uncountables.replace(@uncountables)
92
89
  end
93
90
 
94
91
  it "should be possible to clear the list of singulars, plurals, and uncountables" do
@@ -0,0 +1,292 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe "Sequel::Schema::Generator dump methods" do
4
+ before do
5
+ @d = Sequel::Database.new
6
+ @g = Sequel::Schema::Generator
7
+ end
8
+
9
+ it "should allow the same table information to be converted to a string for evaling inside of another instance with the same result" do
10
+ g = @g.new(@d) do
11
+ Integer :a
12
+ varchar :b
13
+ column :dt, DateTime
14
+ column :vc, :varchar
15
+ primary_key :c
16
+ foreign_key :d, :a
17
+ foreign_key :e
18
+ foreign_key [:d, :e], :name=>:cfk
19
+ constraint :blah, "a=1"
20
+ check :a=>1
21
+ unique [:e]
22
+ index :a
23
+ index [:c, :e]
24
+ index [:b, :c], :type=>:hash
25
+ index [:d], :unique=>true
26
+ spatial_index :a
27
+ full_text_index [:b, :c]
28
+ end
29
+ g2 = @g.new(@d) do
30
+ instance_eval(g.dump_columns, __FILE__, __LINE__)
31
+ instance_eval(g.dump_constraints, __FILE__, __LINE__)
32
+ instance_eval(g.dump_indexes, __FILE__, __LINE__)
33
+ end
34
+ g.columns.should == g2.columns
35
+ g.constraints.should == g2.constraints
36
+ g.indexes.should == g2.indexes
37
+ end
38
+
39
+ it "should allow dumping indexes as separate add_index and drop_index methods" do
40
+ g = @g.new(@d) do
41
+ index :a
42
+ index [:c, :e], :name=>:blah
43
+ index [:b, :c], :unique=>true
44
+ end
45
+
46
+ t = <<END_CODE
47
+ add_index :t, [:a]
48
+ add_index :t, [:c, :e], :name=>:blah
49
+ add_index :t, [:b, :c], :unique=>true
50
+ END_CODE
51
+ g.dump_indexes(:add_index=>:t).should == t.strip
52
+
53
+ t = <<END_CODE
54
+ drop_index :t, [:a]
55
+ drop_index :t, [:c, :e], :name=>:blah
56
+ drop_index :t, [:b, :c], :unique=>true
57
+ END_CODE
58
+ g.dump_indexes(:drop_index=>:t).should == t.strip
59
+ end
60
+
61
+ it "should raise an error if you try to dump a Generator that uses a constraint with a proc" do
62
+ proc{@g.new(@d){check{a>1}}.dump_constraints}.should raise_error(Sequel::Error)
63
+ end
64
+ end
65
+
66
+ describe "Sequel::Database dump methods" do
67
+ before do
68
+ @d = Sequel::Database.new
69
+ @d.meta_def(:tables){[:t1, :t2]}
70
+ @d.meta_def(:schema) do |t, *o|
71
+ case t
72
+ when :t1
73
+ [[:c1, {:db_type=>'integer', :primary_key=>true, :allow_null=>false}],
74
+ [:c2, {:db_type=>'varchar(20)', :allow_null=>true}]]
75
+ when :t2
76
+ [[:c1, {:db_type=>'integer', :primary_key=>true, :allow_null=>false}],
77
+ [:c2, {:db_type=>'numeric', :primary_key=>true, :allow_null=>false}]]
78
+ when :t3
79
+ [[:c1, {:db_type=>'date', :default=>"'now()'", :allow_null=>true}],
80
+ [:c2, {:db_type=>'datetime', :allow_null=>false}]]
81
+ when :t4
82
+ [[:c1, {:db_type=>'boolean', :default=>"false", :allow_null=>true}],
83
+ [:c2, {:db_type=>'boolean', :default=>"true", :allow_null=>true}],
84
+ [:c3, {:db_type=>'varchar', :default=>"'blah'", :allow_null=>true}],
85
+ [:c4, {:db_type=>'integer', :default=>"35", :allow_null=>true}]]
86
+ when :t5
87
+ [[:c1, {:db_type=>'blahblah', :allow_null=>true}]]
88
+ end
89
+ end
90
+ end
91
+
92
+ it "should support dumping table schemas as create_table method calls" do
93
+ @d.dump_table_schema(:t1).should == "create_table(:t1) do\n primary_key :c1\n String :c2, :size=>20\nend"
94
+ end
95
+
96
+ it "should use a composite primary_key calls if there is a composite primary key" do
97
+ @d.dump_table_schema(:t2).should == "create_table(:t2) do\n Integer :c1, :null=>false\n BigDecimal :c2, :null=>false\n \n primary_key [:c1, :c2]\nend"
98
+ end
99
+
100
+ it "should include index information if available" do
101
+ @d.meta_def(:indexes) do |t|
102
+ {:i1=>{:columns=>[:c1], :unique=>false},
103
+ :t1_c2_c1_index=>{:columns=>[:c2, :c1], :unique=>true}}
104
+ end
105
+ @d.dump_table_schema(:t1).should == "create_table(:t1) do\n primary_key :c1\n String :c2, :size=>20\n \n index [:c1], :name=>:i1\n index [:c2, :c1], :unique=>true\nend"
106
+ end
107
+
108
+ it "should support dumping the whole database as a migration" do
109
+ @d.dump_schema_migration.should == <<-END_MIG
110
+ Class.new(Sequel::Migration) do
111
+ def up
112
+ create_table(:t1) do
113
+ primary_key :c1
114
+ String :c2, :size=>20
115
+ end
116
+
117
+ create_table(:t2) do
118
+ Integer :c1, :null=>false
119
+ BigDecimal :c2, :null=>false
120
+
121
+ primary_key [:c1, :c2]
122
+ end
123
+ end
124
+
125
+ def down
126
+ drop_table(:t1, :t2)
127
+ end
128
+ end
129
+ END_MIG
130
+ end
131
+
132
+ it "should honor the :same_db option to not convert types" do
133
+ @d.dump_table_schema(:t1, :same_db=>true).should == "create_table(:t1) do\n primary_key :c1\n column :c2, \"varchar(20)\"\nend"
134
+ @d.dump_schema_migration(:same_db=>true).should == <<-END_MIG
135
+ Class.new(Sequel::Migration) do
136
+ def up
137
+ create_table(:t1) do
138
+ primary_key :c1
139
+ column :c2, "varchar(20)"
140
+ end
141
+
142
+ create_table(:t2) do
143
+ column :c1, "integer", :null=>false
144
+ column :c2, "numeric", :null=>false
145
+
146
+ primary_key [:c1, :c2]
147
+ end
148
+ end
149
+
150
+ def down
151
+ drop_table(:t1, :t2)
152
+ end
153
+ end
154
+ END_MIG
155
+ end
156
+
157
+ it "should honor the :indexes => false option to not include indexes" do
158
+ @d.meta_def(:indexes) do |t|
159
+ {:i1=>{:columns=>[:c1], :unique=>false},
160
+ :t1_c2_c1_index=>{:columns=>[:c2, :c1], :unique=>true}}
161
+ end
162
+ @d.dump_table_schema(:t1, :indexes=>false).should == "create_table(:t1) do\n primary_key :c1\n String :c2, :size=>20\nend"
163
+ @d.dump_schema_migration(:indexes=>false).should == <<-END_MIG
164
+ Class.new(Sequel::Migration) do
165
+ def up
166
+ create_table(:t1) do
167
+ primary_key :c1
168
+ String :c2, :size=>20
169
+ end
170
+
171
+ create_table(:t2) do
172
+ Integer :c1, :null=>false
173
+ BigDecimal :c2, :null=>false
174
+
175
+ primary_key [:c1, :c2]
176
+ end
177
+ end
178
+
179
+ def down
180
+ drop_table(:t1, :t2)
181
+ end
182
+ end
183
+ END_MIG
184
+ end
185
+
186
+ it "should support dumping just indexes as a migration" do
187
+ @d.meta_def(:tables){[:t1]}
188
+ @d.meta_def(:indexes) do |t|
189
+ {:i1=>{:columns=>[:c1], :unique=>false},
190
+ :t1_c2_c1_index=>{:columns=>[:c2, :c1], :unique=>true}}
191
+ end
192
+ @d.dump_indexes_migration.should == <<-END_MIG
193
+ Class.new(Sequel::Migration) do
194
+ def up
195
+ add_index :t1, [:c1], :name=>:i1
196
+ add_index :t1, [:c2, :c1], :unique=>true
197
+ end
198
+
199
+ def down
200
+ drop_index :t1, [:c1], :name=>:i1
201
+ drop_index :t1, [:c2, :c1], :unique=>true
202
+ end
203
+ end
204
+ END_MIG
205
+ end
206
+
207
+ it "should handle not null values and defaults" do
208
+ @d.dump_table_schema(:t3).should == "create_table(:t3) do\n Date :c1, :default=>\"'now()'\".lit\n DateTime :c2, :null=>false\nend"
209
+ end
210
+
211
+ it "should handle converting common defaults" do
212
+ @d.dump_table_schema(:t4).should == "create_table(:t4) do\n TrueClass :c1, :default=>false\n TrueClass :c2, :default=>true\n String :c3, :default=>\"'blah'\".lit\n Integer :c4, :default=>35\nend"
213
+ end
214
+
215
+ it "should convert unknown database types to strings" do
216
+ @d.dump_table_schema(:t5).should == "create_table(:t5) do\n String :c1\nend"
217
+ end
218
+
219
+ it "should convert many database types to ruby types" do
220
+ types = %w"mediumint smallint int integer mediumint(6) smallint(7) int(8) integer(9)
221
+ tinyint tinyint(1) bigint bigint(20) real float double boolean tinytext mediumtext
222
+ longtext text clob date datetime timestamp time char character
223
+ varchar varchar(255) varchar(30) bpchar string money
224
+ decimal decimal(10,2) numeric numeric(15,3) number bytea tinyblob mediumblob longblob
225
+ blob varbinary varbinary(10) binary binary(20) year" +
226
+ ["double precision", "timestamp with time zone", "timestamp without time zone",
227
+ "time with time zone", "time without time zone", "character varying(20)"]
228
+ @d.meta_def(:schema) do |t, *o|
229
+ i = 0
230
+ types.map{|x| [:"c#{i+=1}", {:db_type=>x, :allow_null=>true}]}
231
+ end
232
+ table = <<END_MIG
233
+ create_table(:x) do
234
+ Integer :c1
235
+ Integer :c2
236
+ Integer :c3
237
+ Integer :c4
238
+ Integer :c5
239
+ Integer :c6
240
+ Integer :c7
241
+ Integer :c8
242
+ TrueClass :c9
243
+ TrueClass :c10
244
+ Bignum :c11
245
+ Bignum :c12
246
+ Float :c13
247
+ Float :c14
248
+ Float :c15
249
+ TrueClass :c16
250
+ String :c17, :text=>true
251
+ String :c18, :text=>true
252
+ String :c19, :text=>true
253
+ String :c20, :text=>true
254
+ String :c21, :text=>true
255
+ Date :c22
256
+ DateTime :c23
257
+ DateTime :c24
258
+ Time :c25, :only_time=>true
259
+ String :c26, :fixed=>true
260
+ String :c27, :fixed=>true
261
+ String :c28
262
+ String :c29
263
+ String :c30, :size=>30
264
+ String :c31
265
+ String :c32
266
+ BigDecimal :c33, :size=>[19, 2]
267
+ BigDecimal :c34
268
+ BigDecimal :c35, :size=>[10, 2]
269
+ BigDecimal :c36
270
+ BigDecimal :c37, :size=>[15, 3]
271
+ BigDecimal :c38
272
+ File :c39
273
+ File :c40
274
+ File :c41
275
+ File :c42
276
+ File :c43
277
+ File :c44
278
+ File :c45, :size=>10
279
+ File :c46
280
+ File :c47, :size=>20
281
+ Integer :c48
282
+ Float :c49
283
+ DateTime :c50
284
+ DateTime :c51
285
+ Time :c52, :only_time=>true
286
+ Time :c53, :only_time=>true
287
+ String :c54, :size=>20
288
+ end
289
+ END_MIG
290
+ @d.dump_table_schema(:x).should == table.chomp
291
+ end
292
+ end