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.
- data/CHANGELOG +62 -0
- data/README.rdoc +3 -3
- data/Rakefile +7 -0
- data/doc/advanced_associations.rdoc +44 -0
- data/doc/release_notes/3.0.0.txt +221 -0
- data/lib/sequel/adapters/amalgalite.rb +208 -0
- data/lib/sequel/adapters/db2.rb +3 -0
- data/lib/sequel/adapters/dbi.rb +9 -0
- data/lib/sequel/adapters/do.rb +0 -4
- data/lib/sequel/adapters/firebird.rb +16 -18
- data/lib/sequel/adapters/informix.rb +5 -3
- data/lib/sequel/adapters/jdbc.rb +24 -20
- data/lib/sequel/adapters/jdbc/h2.rb +15 -4
- data/lib/sequel/adapters/mysql.rb +4 -8
- data/lib/sequel/adapters/odbc.rb +0 -4
- data/lib/sequel/adapters/oracle.rb +0 -4
- data/lib/sequel/adapters/shared/mssql.rb +16 -5
- data/lib/sequel/adapters/shared/mysql.rb +87 -86
- data/lib/sequel/adapters/shared/oracle.rb +92 -3
- data/lib/sequel/adapters/shared/postgres.rb +85 -29
- data/lib/sequel/adapters/shared/progress.rb +8 -3
- data/lib/sequel/adapters/shared/sqlite.rb +53 -23
- data/lib/sequel/adapters/sqlite.rb +4 -7
- data/lib/sequel/adapters/utils/unsupported.rb +3 -3
- data/lib/sequel/connection_pool.rb +18 -25
- data/lib/sequel/core.rb +2 -21
- data/lib/sequel/database.rb +60 -44
- data/lib/sequel/database/schema_generator.rb +26 -31
- data/lib/sequel/database/schema_methods.rb +8 -3
- data/lib/sequel/database/schema_sql.rb +114 -28
- data/lib/sequel/dataset.rb +14 -41
- data/lib/sequel/dataset/convenience.rb +31 -54
- data/lib/sequel/dataset/graph.rb +7 -13
- data/lib/sequel/dataset/sql.rb +43 -54
- data/lib/sequel/extensions/inflector.rb +0 -5
- data/lib/sequel/extensions/schema_dumper.rb +238 -0
- data/lib/sequel/metaprogramming.rb +0 -20
- data/lib/sequel/model.rb +1 -2
- data/lib/sequel/model/base.rb +18 -16
- data/lib/sequel/model/inflections.rb +6 -9
- data/lib/sequel/plugins/caching.rb +0 -6
- data/lib/sequel/plugins/hook_class_methods.rb +1 -1
- data/lib/sequel/sql.rb +2 -0
- data/lib/sequel/version.rb +2 -2
- data/spec/adapters/firebird_spec.rb +35 -8
- data/spec/adapters/mysql_spec.rb +173 -266
- data/spec/adapters/oracle_spec.rb +13 -0
- data/spec/adapters/postgres_spec.rb +127 -227
- data/spec/adapters/sqlite_spec.rb +13 -171
- data/spec/core/connection_pool_spec.rb +15 -4
- data/spec/core/core_sql_spec.rb +14 -170
- data/spec/core/database_spec.rb +50 -132
- data/spec/core/dataset_spec.rb +47 -930
- data/spec/core/expression_filters_spec.rb +12 -0
- data/spec/core/schema_generator_spec.rb +37 -45
- data/spec/core/schema_spec.rb +26 -16
- data/spec/core/spec_helper.rb +0 -25
- data/spec/extensions/inflector_spec.rb +0 -3
- data/spec/extensions/schema_dumper_spec.rb +292 -0
- data/spec/extensions/serialization_spec.rb +9 -0
- data/spec/extensions/single_table_inheritance_spec.rb +6 -1
- data/spec/extensions/spec_helper.rb +1 -3
- data/spec/extensions/validation_helpers_spec.rb +4 -4
- data/spec/integration/database_test.rb +18 -0
- data/spec/integration/dataset_test.rb +112 -1
- data/spec/integration/eager_loader_test.rb +70 -9
- data/spec/integration/prepared_statement_test.rb +2 -2
- data/spec/integration/schema_test.rb +76 -27
- data/spec/integration/spec_helper.rb +0 -14
- data/spec/integration/transaction_test.rb +27 -0
- data/spec/model/associations_spec.rb +0 -36
- data/spec/model/base_spec.rb +18 -123
- data/spec/model/hooks_spec.rb +2 -235
- data/spec/model/inflector_spec.rb +15 -115
- data/spec/model/model_spec.rb +0 -120
- data/spec/model/plugins_spec.rb +0 -70
- data/spec/model/record_spec.rb +35 -93
- data/spec/model/spec_helper.rb +0 -27
- data/spec/model/validations_spec.rb +0 -931
- metadata +9 -14
- data/lib/sequel/deprecated.rb +0 -593
- data/lib/sequel/deprecated_migration.rb +0 -91
- data/lib/sequel/model/deprecated.rb +0 -204
- data/lib/sequel/model/deprecated_hooks.rb +0 -103
- data/lib/sequel/model/deprecated_inflector.rb +0 -335
- data/lib/sequel/model/deprecated_validations.rb +0 -388
- data/spec/core/core_ext_spec.rb +0 -156
- data/spec/core/migration_spec.rb +0 -263
- data/spec/core/pretty_table_spec.rb +0 -58
- data/spec/model/caching_spec.rb +0 -217
- 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.
|
18
|
+
@columns, @indexes, @constraints = @generator.columns, @generator.indexes, @generator.constraints
|
19
19
|
end
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
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
|
28
|
-
@columns.size.should ==
|
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[
|
52
|
-
@columns[
|
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[
|
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
|
-
@
|
70
|
-
@
|
71
|
-
@
|
66
|
+
@constraints[0][:name].should == nil
|
67
|
+
@constraints[0][:type].should == :check
|
68
|
+
@constraints[0][:check].should == ['price > 100']
|
72
69
|
|
73
|
-
@
|
74
|
-
@
|
75
|
-
@
|
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
|
-
@
|
78
|
-
@
|
79
|
-
@
|
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
|
-
@
|
83
|
-
@
|
84
|
-
@
|
85
|
-
@
|
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, :
|
130
|
+
{:op => :add_constraint, :type => :check, :name => :con1, :check => ['fred > 100']},
|
134
131
|
{:op => :drop_constraint, :name => :con2},
|
135
|
-
{:op => :add_constraint, :type => :
|
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 => :
|
139
|
-
{:op => :add_constraint, :type => :
|
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
|
-
|
146
|
-
|
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
|
data/spec/core/schema_spec.rb
CHANGED
@@ -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}]]
|
data/spec/core/spec_helper.rb
CHANGED
@@ -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
|