miguel 0.1.0.pre4 → 0.1.0.pre5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ # Migration test.
2
+
3
+ Miguel::Schema.define do
4
+
5
+ table :a do
6
+ Integer :a
7
+ end
8
+
9
+ table :b do
10
+ primary_key :id
11
+ String :t
12
+ Unsigned? :u
13
+ Signed :s
14
+ end
15
+
16
+ end
17
+
18
+ # EOF #
@@ -0,0 +1,17 @@
1
+ Sequel.migration do
2
+ up do
3
+ create_table :a do
4
+ Integer :a, :null => false
5
+ end
6
+ create_table :b do
7
+ primary_key :id, :null => false, :unsigned => false
8
+ String :t, :null => false
9
+ integer :u, :null => true, :unsigned => true
10
+ integer :s, :null => false, :unsigned => false
11
+ end
12
+ end
13
+ down do
14
+ drop_table :a
15
+ drop_table :b
16
+ end
17
+ end
@@ -0,0 +1,33 @@
1
+ # Migration test.
2
+
3
+ Miguel::Schema.define do
4
+
5
+ table :a do
6
+ primary_key :id
7
+ Float :a
8
+ foreign_key :fk, :c
9
+ end
10
+
11
+ table :b do
12
+ primary_key :id
13
+ Text :t
14
+ Unsigned :u, default: 123
15
+ Signed? :s
16
+ timestamps
17
+ foreign_key :fk, :a
18
+ unique :u
19
+ end
20
+
21
+ table :c do
22
+ primary_key :id
23
+ String? :s
24
+ end
25
+
26
+ table :d do
27
+ Integer :a
28
+ Integer :b
29
+ end
30
+
31
+ end
32
+
33
+ # EOF #
@@ -0,0 +1,60 @@
1
+ Sequel.migration do
2
+ up do
3
+ alter_table :a do
4
+ set_column_type :a, Float, :null => false
5
+ add_primary_key :id, :null => false, :unsigned => false
6
+ add_column :fk, :integer, :default => 0, :null => false, :key => [:id], :unsigned => false
7
+ end
8
+ alter_table :b do
9
+ set_column_type :t, String, :null => false, :text => true
10
+ set_column_default :u, 123
11
+ set_column_not_null :u
12
+ set_column_allow_null :s
13
+ set_column_default :s, nil
14
+ add_column :create_time, :timestamp, :default => "2000-01-01 00:00:00", :null => false
15
+ add_column :update_time, :timestamp, :default => "2000-01-01 00:00:00", :null => false
16
+ add_column :fk, :integer, :default => 0, :null => false, :key => [:id], :unsigned => false
17
+ add_index [:u], :unique => true
18
+ end
19
+ create_table :c do
20
+ primary_key :id, :null => false, :unsigned => false
21
+ String :s, :null => true
22
+ end
23
+ create_table :d do
24
+ Integer :a, :null => false
25
+ Integer :b, :null => false
26
+ end
27
+ alter_table :a do
28
+ add_foreign_key [:fk], :c, :on_update => :no_action, :on_delete => :no_action, :key => [:id]
29
+ end
30
+ alter_table :b do
31
+ add_foreign_key [:fk], :a, :on_update => :no_action, :on_delete => :no_action, :key => [:id]
32
+ end
33
+ end
34
+ down do
35
+ alter_table :a do
36
+ drop_foreign_key [:fk] # :c, :on_update => :no_action, :on_delete => :no_action, :key => [:id]
37
+ end
38
+ alter_table :b do
39
+ drop_foreign_key [:fk] # :a, :on_update => :no_action, :on_delete => :no_action, :key => [:id]
40
+ end
41
+ drop_table :c
42
+ drop_table :d
43
+ alter_table :a do
44
+ drop_column :id # :primary_key, :null => false, :unsigned => false
45
+ drop_column :fk # :integer, :null => false, :key => [:id], :unsigned => false
46
+ set_column_type :a, Integer, :null => false
47
+ end
48
+ alter_table :b do
49
+ drop_index [:u] # :unique => true
50
+ drop_column :create_time # :timestamp, :null => false, :default => "2000-01-01 00:00:00"
51
+ drop_column :update_time # :timestamp, :null => false, :default => "2000-01-01 00:00:00"
52
+ drop_column :fk # :integer, :null => false, :key => [:id], :unsigned => false
53
+ set_column_type :t, String, :null => false
54
+ set_column_allow_null :u
55
+ set_column_default :u, nil
56
+ set_column_default :s, 0
57
+ set_column_not_null :s
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,38 @@
1
+ # Migration test.
2
+
3
+ Miguel::Schema.define do
4
+
5
+ table :a do
6
+ primary_key :id
7
+ Float :a
8
+ foreign_key :fk, :c
9
+ end
10
+
11
+ table :b do
12
+ primary_key :id
13
+ Text :t
14
+ Unsigned :u, default: 123
15
+ Signed? :s
16
+ timestamps
17
+ foreign_key :fk, :c
18
+ unique :u
19
+ index :create_time
20
+ end
21
+
22
+ table :c do
23
+ primary_key :id
24
+ String? :s
25
+ Text :t
26
+ end
27
+
28
+ table :d do
29
+ Integer :a
30
+ Integer :b
31
+ primary_key [:a,:b]
32
+ end
33
+
34
+ join_table :left_id, :a, :right_id, :b
35
+
36
+ end
37
+
38
+ # EOF #
@@ -0,0 +1,51 @@
1
+ Sequel.migration do
2
+ up do
3
+ alter_table :b do
4
+ drop_foreign_key [:fk] # :a, :on_update => :no_action, :on_delete => :no_action, :key => [:id]
5
+ end
6
+ alter_table :b do
7
+ add_index [:create_time], :unique => false
8
+ end
9
+ alter_table :c do
10
+ add_column :t, String, :default => "", :null => false, :text => true
11
+ end
12
+ alter_table :d do
13
+ add_primary_key [:a, :b], :null => false, :unsigned => false
14
+ end
15
+ create_table :a_b do
16
+ integer :left_id, :null => false, :key => [:id], :unsigned => false
17
+ integer :right_id, :null => false, :key => [:id], :unsigned => false
18
+ primary_key [:left_id, :right_id], :null => false, :unsigned => false
19
+ index [:right_id, :left_id], :null => false, :unique => true
20
+ end
21
+ alter_table :b do
22
+ add_foreign_key [:fk], :c, :on_update => :no_action, :on_delete => :no_action, :key => [:id]
23
+ end
24
+ alter_table :a_b do
25
+ add_foreign_key [:left_id], :a, :on_update => :no_action, :on_delete => :no_action, :key => [:id]
26
+ add_foreign_key [:right_id], :b, :on_update => :no_action, :on_delete => :no_action, :key => [:id]
27
+ end
28
+ end
29
+ down do
30
+ alter_table :b do
31
+ drop_foreign_key [:fk] # :c, :on_update => :no_action, :on_delete => :no_action, :key => [:id]
32
+ end
33
+ alter_table :a_b do
34
+ drop_foreign_key [:left_id] # :a, :on_update => :no_action, :on_delete => :no_action, :key => [:id]
35
+ drop_foreign_key [:right_id] # :b, :on_update => :no_action, :on_delete => :no_action, :key => [:id]
36
+ end
37
+ drop_table :a_b
38
+ alter_table :b do
39
+ drop_index [:create_time] # :unique => false
40
+ end
41
+ alter_table :c do
42
+ drop_column :t # String, :null => false, :text => true
43
+ end
44
+ alter_table :d do
45
+ drop_constraint [:a, :b], :type => :primary_key # :null => false, :unsigned => false
46
+ end
47
+ alter_table :b do
48
+ add_foreign_key [:fk], :a, :on_update => :no_action, :on_delete => :no_action, :key => [:id]
49
+ end
50
+ end
51
+ end
data/test/data/simple.txt CHANGED
@@ -1,10 +1,10 @@
1
1
  table :items do
2
- primary_key :id, :null => false, :unsigned => false, :type => :integer
2
+ primary_key :id, :null => false, :unsigned => false
3
3
  String :name, :null => false
4
- integer :parent_id, :null => false, :key => [:id], :unsigned => false, :type => :integer
5
- timestamp :create_time, :null => false, :default => "0000-00-00 00:00:00"
6
- timestamp :update_time, :null => false, :default => "0000-00-00 00:00:00"
4
+ integer :parent_id, :null => false, :key => [:id], :unsigned => false
5
+ timestamp :create_time, :null => false, :default => "2000-01-01 00:00:00"
6
+ timestamp :update_time, :null => false, :default => "2000-01-01 00:00:00"
7
7
  index [:name], :null => false, :unique => true
8
8
  index [:parent_id], :null => false
9
- foreign_key [:parent_id], :items, :null => false, :key => [:id], :unsigned => false, :type => :integer
9
+ foreign_key [:parent_id], :items, :null => false, :key => [:id], :unsigned => false
10
10
  end
data/test/helper.rb CHANGED
@@ -8,4 +8,28 @@ begin
8
8
  rescue LoadError
9
9
  end
10
10
 
11
+ # Setup helpers.
12
+
13
+ DATA_DIR = File.expand_path( "#{__FILE__}/../data" )
14
+
15
+ SEQ_COUNT = Dir[ "#{DATA_DIR}/seq_*.rb" ].count
16
+
17
+ class Bacon::Context
18
+
19
+ def data( name )
20
+ "#{DATA_DIR}/#{name}"
21
+ end
22
+
23
+ def lines( s )
24
+ s.to_s.lines.map.with_index{ |l, i| "#{i}:#{l.strip}" }
25
+ end
26
+
27
+ def match( a, b )
28
+ for a, b in lines( a ).zip( lines( b ) )
29
+ a.should == b
30
+ end
31
+ end
32
+
33
+ end
34
+
11
35
  # EOF #
@@ -0,0 +1,66 @@
1
+ # Test Importer.
2
+
3
+ require_relative 'helper'
4
+ require 'miguel/importer'
5
+ require 'miguel/migrator'
6
+
7
+ require 'yaml'
8
+
9
+ describe Miguel::Importer do
10
+
11
+ def database_options( db )
12
+ case db.database_type
13
+ when :mysql
14
+ [
15
+ {},
16
+ { unsigned_keys: true },
17
+ { mysql_timestamps: true },
18
+ ]
19
+ when :postgres
20
+ [ signed_unsigned: true ]
21
+ else
22
+ [ {} ]
23
+ end
24
+ end
25
+
26
+ def load( name, opts = {} )
27
+ Miguel::Schema.load( data( name ), opts )
28
+ end
29
+
30
+ def get_changes( db, schema )
31
+ importer = Miguel::Importer.new( db )
32
+ Miguel::Migrator.new.changes( importer.schema, schema ).to_s
33
+ end
34
+
35
+ def apply_schema( db, schema )
36
+ changes = get_changes( db, schema )
37
+ db.instance_eval( changes )
38
+ end
39
+
40
+ def databases
41
+ YAML.load_file( data( 'db.yml' ) ).map do |env, config|
42
+ Sequel.connect( config )
43
+ end
44
+ end
45
+
46
+ should 'correctly import schema from each supported database' do
47
+ empty = Miguel::Schema.new
48
+ for db in databases
49
+ for opts in database_options( db )
50
+ schema = load( 'schema.rb', opts )
51
+ apply_schema( db, empty )
52
+ get_changes( db, empty ).should.be.empty
53
+ get_changes( db, schema ).should.not.be.empty
54
+ apply_schema( db, schema )
55
+ get_changes( db, schema ).should.be.empty
56
+ get_changes( db, empty ).should.not.be.empty
57
+ apply_schema( db, empty )
58
+ get_changes( db, empty ).should.be.empty
59
+ get_changes( db, schema ).should.not.be.empty
60
+ end
61
+ end
62
+ end
63
+
64
+ end
65
+
66
+ # EOF #
@@ -0,0 +1,53 @@
1
+ # Test Migrator.
2
+
3
+ require_relative 'helper'
4
+ require 'miguel/migrator'
5
+
6
+ describe Miguel::Migrator do
7
+
8
+ def load( name )
9
+ Miguel::Schema.load( data( name ) )
10
+ end
11
+
12
+ def match_file( data, name )
13
+ match( data, File.read( data( name ) ) )
14
+ end
15
+
16
+ should 'create changes needed to create schema' do
17
+ schema = load( 'schema.rb' )
18
+ changes = Miguel::Migrator.new.changes( Miguel::Schema.new, schema )
19
+ match_file( changes, 'schema_bare.txt' )
20
+ end
21
+
22
+ should 'create changes needed to destroy schema' do
23
+ schema = load( 'schema.rb' )
24
+ changes = Miguel::Migrator.new.changes( schema, Miguel::Schema.new )
25
+ match_file( changes, 'schema_down.txt' )
26
+ end
27
+
28
+ should 'create Sequel change migration' do
29
+ schema = load( 'schema.rb' )
30
+ migration = Miguel::Migrator.new.change_migration( Miguel::Schema.new, schema )
31
+ match_file( migration, 'schema_change.txt' )
32
+ end
33
+
34
+ should 'create Sequel up/down migration' do
35
+ schema = load( 'schema.rb' )
36
+ migration = Miguel::Migrator.new.full_migration( Miguel::Schema.new, schema )
37
+ match_file( migration, 'schema_full.txt' )
38
+ end
39
+
40
+ should 'create migrations to migrate from one schema to another' do
41
+ m = Miguel::Migrator.new
42
+ schema = Miguel::Schema.new
43
+ SEQ_COUNT.times do |i|
44
+ new_schema = load( "seq_#{i}.rb" )
45
+ migration = m.full_migration( schema, new_schema )
46
+ match_file( migration, "seq_#{i}.txt" )
47
+ schema = new_schema
48
+ end
49
+ end
50
+
51
+ end
52
+
53
+ # EOF #
data/test/test_schema.rb CHANGED
@@ -5,24 +5,31 @@ require 'miguel/schema'
5
5
 
6
6
  describe Miguel::Schema do
7
7
 
8
- DATA_DIR = File.expand_path( "#{__FILE__}/../data" )
8
+ after do
9
+ Miguel::Schema.default_options = nil
10
+ end
11
+
12
+ def match_file( schema, name )
13
+ match( schema.dump, File.read( data( name ) ) )
14
+ end
9
15
 
10
- def data( name )
11
- "#{DATA_DIR}/#{name}"
16
+ def match_schema( text, opts = {}, &block )
17
+ schema = Miguel::Schema.new( opts ).define( &block )
18
+ match( schema.dump, text )
12
19
  end
13
20
 
14
21
  should 'load and dump schema properly' do
15
22
  schema = Miguel::Schema.load( data( 'schema.rb' ) )
16
- schema.dump.to_s.should == File.read( data( 'schema.txt' ) )
23
+ match_file( schema, 'schema.txt' )
17
24
  end
18
25
 
19
26
  should 'allow changing default schema options temporarily' do
20
27
  schema = Miguel::Schema.load( data( 'simple.rb' ), unsigned_keys: true, mysql_timestamps: true )
21
- schema.dump.to_s.should == File.read( data( 'simple_mysql.txt' ) )
28
+ match_file( schema, 'simple_mysql.txt' )
22
29
  Miguel::Schema.new.opts.should.be.empty
23
30
 
24
31
  schema = Miguel::Schema.load( data( 'simple.rb' ) )
25
- schema.dump.to_s.should == File.read( data( 'simple.txt' ) )
32
+ match_file( schema, 'simple.txt' )
26
33
  end
27
34
 
28
35
  should 'allow changing default schema options permanently' do
@@ -33,14 +40,472 @@ describe Miguel::Schema do
33
40
  Miguel::Schema.default_options.should == { unsigned_keys: true, mysql_timestamps: true }
34
41
 
35
42
  schema = Miguel::Schema.load( data( 'simple.rb' ) )
36
- schema.dump.to_s.should == File.read( data( 'simple_mysql.txt' ) )
43
+ match_file( schema, 'simple_mysql.txt' )
37
44
 
38
45
  Miguel::Schema.default_options = nil
39
46
  Miguel::Schema.default_options.should == {}
40
47
  Miguel::Schema.new.opts.should.be.empty
41
48
 
42
49
  schema = Miguel::Schema.load( data( 'simple.rb' ) )
43
- schema.dump.to_s.should == File.read( data( 'simple.txt' ) )
50
+ match_file( schema, 'simple.txt' )
51
+ end
52
+
53
+ should 'support plain sequel types' do
54
+ match_schema <<-EOT, use_defaults: false do
55
+ table :sequel_types do
56
+ Integer :a0
57
+ String :a1
58
+ String :a2, :size => 50
59
+ String :a3, :fixed => true
60
+ String :a4, :fixed => true, :size => 50
61
+ String :a5, :text => true
62
+ File :b
63
+ Fixnum :c
64
+ Bignum :d
65
+ Float :e
66
+ BigDecimal :f
67
+ BigDecimal :f2, :size => 10
68
+ BigDecimal :f3, :size => [10, 2]
69
+ Date :g
70
+ DateTime :h
71
+ Time :i
72
+ Time :i2, :only_time => true
73
+ Numeric :j
74
+ TrueClass :k
75
+ FalseClass :l
76
+ end
77
+ EOT
78
+ table :sequel_types do
79
+ Integer :a0 # integer
80
+ String :a1 # varchar(255)
81
+ String :a2, :size=>50 # varchar(50)
82
+ String :a3, :fixed=>true # char(255)
83
+ String :a4, :fixed=>true, :size=>50 # char(50)
84
+ String :a5, :text=>true # text
85
+ File :b # blob
86
+ Fixnum :c # integer
87
+ Bignum :d # bigint
88
+ Float :e # double precision
89
+ BigDecimal :f # numeric
90
+ BigDecimal :f2, :size=>10 # numeric(10)
91
+ BigDecimal :f3, :size=>[10, 2] # numeric(10, 2)
92
+ Date :g # date
93
+ DateTime :h # timestamp or datetime
94
+ Time :i # timestamp or datetime
95
+ Time :i2, :only_time=>true # time
96
+ Numeric :j # numeric
97
+ TrueClass :k # boolean
98
+ FalseClass :l # boolean
99
+ end
100
+ end
101
+ end
102
+
103
+ should 'support default miguel types' do
104
+ match_schema <<-EOT do
105
+ table :miguel_types do
106
+ integer :key, :null => false, :unsigned => false
107
+ String :string, :null => false
108
+ String :text, :null => false, :text => true
109
+ File :blob, :null => false
110
+ Integer :int, :null => false
111
+ integer :signed, :null => false, :unsigned => false
112
+ integer :unsigned, :null => false, :unsigned => true
113
+ Float :float, :null => false
114
+ TrueClass :bool, :null => false
115
+ TrueClass :true, :null => false, :default => true
116
+ TrueClass :false, :null => false, :default => false
117
+ timestamp :time, :null => false, :default => "2000-01-01 00:00:00"
118
+ end
119
+ EOT
120
+ table :miguel_types do
121
+ Key :key
122
+ String :string
123
+ Text :text
124
+ File :blob
125
+ Integer :int
126
+ Signed :signed
127
+ Unsigned :unsigned
128
+ Float :float
129
+ Bool :bool
130
+ True :true
131
+ False :false
132
+ Time :time
133
+ end
134
+ end
135
+ end
136
+
137
+ should 'support custom types' do
138
+ match_schema <<-EOT do
139
+ table :custom_types do
140
+ String :custom, :null => false, :fixed => true, :size => 3
141
+ datetime :time, :null => false
142
+ datetime :time2, :null => true, :default => nil
143
+ end
144
+ EOT
145
+ set_defaults :Custom, :String, fixed: true, size: 3
146
+ set_defaults :Time, :datetime
147
+ set_defaults :Time?, :datetime, default: nil
148
+ table :custom_types do
149
+ Custom :custom
150
+ Time :time
151
+ Time? :time2
152
+ end
153
+ end
154
+ end
155
+
156
+ should 'support native types' do
157
+ match_schema <<-EOT do
158
+ table :native_types do
159
+ date :date, :null => false, :default => "2000-12-31"
160
+ time :time, :null => false, :default => "23:59:59"
161
+ datetime :datetime, :null => false, :default => "2037-12-31 23:59:59"
162
+ timestamp :timestamp, :null => false, :default => "1970-01-02 00:00:00"
163
+ end
164
+ EOT
165
+ table :native_types do
166
+ date :date, default: '2000-12-31'
167
+ time :time, default: '23:59:59'
168
+ datetime :datetime, default: '2037-12-31 23:59:59'
169
+ timestamp :timestamp, default: '1970-01-02 00:00:00'
170
+ end
171
+ end
172
+ end
173
+
174
+ should 'support enums' do
175
+ match_schema <<-EOT do
176
+ table :enum do
177
+ enum :error, :null => false, :elements => ["none", "invalid", "expired", "declined", "other"], :default => "none"
178
+ end
179
+ EOT
180
+ table :enum do
181
+ enum :error, elements: %w[ none invalid expired declined other ], default: 'none'
182
+ end
183
+ end
184
+ end
185
+
186
+ should 'support sets' do
187
+ match_schema <<-EOT do
188
+ table :set do
189
+ set :permissions, :null => false, :elements => ["read", "write", "create", "delete"], :default => "read"
190
+ end
191
+ EOT
192
+ table :set do
193
+ set :permissions, elements: %w[ read write create delete ], default: 'read'
194
+ end
195
+ end
196
+ end
197
+
198
+ should 'support generic timestamps' do
199
+ match_schema <<-EOT do
200
+ table :timestamps do
201
+ timestamp :t1, :null => false, :default => "2000-01-01 00:00:00"
202
+ timestamp :t2, :null => true, :default => nil
203
+ timestamp :create_time, :null => false, :default => "2000-01-01 00:00:00"
204
+ timestamp :update_time, :null => false, :default => "2000-01-01 00:00:00"
205
+ end
206
+ EOT
207
+ table :timestamps do
208
+ Time :t1
209
+ Time? :t2
210
+ timestamps
211
+ end
212
+ end
213
+ end
214
+
215
+ should 'support MySQL timestamps' do
216
+ match_schema <<-EOT, mysql_timestamps: true do
217
+ table :timestamps do
218
+ timestamp :t1, :null => false, :default => "0000-00-00 00:00:00"
219
+ timestamp :t2, :null => true, :default => nil
220
+ timestamp :create_time, :null => false, :default => "0000-00-00 00:00:00"
221
+ timestamp :update_time, :null => false, :default => Sequel.lit("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
222
+ end
223
+ EOT
224
+ table :timestamps do
225
+ Time :t1
226
+ Time? :t2
227
+ timestamps
228
+ end
229
+ end
230
+ end
231
+
232
+ should 'support auto-incrementing primary keys' do
233
+ match_schema <<-EOT do
234
+ table :pk do
235
+ primary_key :id, :null => false, :unsigned => false
236
+ end
237
+ EOT
238
+ table :pk do
239
+ primary_key :id
240
+ end
241
+ end
242
+ end
243
+
244
+ should 'support non-incrementing primary keys' do
245
+ match_schema <<-EOT do
246
+ table :pk do
247
+ integer :id, :null => false, :unsigned => false, :primary_key => true
248
+ end
249
+ EOT
250
+ table :pk do
251
+ Key :id, primary_key: true
252
+ end
253
+ end
254
+ end
255
+
256
+ should 'support compound primary keys' do
257
+ match_schema <<-EOT do
258
+ table :pk do
259
+ Integer :a, :null => false
260
+ Integer :b, :null => false
261
+ primary_key [:a, :b], :null => false, :unsigned => false
262
+ end
263
+ EOT
264
+ table :pk do
265
+ Integer :a
266
+ Integer :b
267
+ primary_key [:a, :b]
268
+ end
269
+ end
270
+ end
271
+
272
+ should 'support foreign keys' do
273
+ match_schema <<-EOT do
274
+ table :fk do
275
+ integer :user_id, :null => false, :key => [:id], :unsigned => false
276
+ foreign_key [:user_id], :users, :null => false, :key => [:id], :unsigned => false
277
+ end
278
+ EOT
279
+ table :fk do
280
+ foreign_key :user_id, :users
281
+ end
282
+ end
283
+ end
284
+
285
+ should 'support reused foreign keys' do
286
+ match_schema <<-EOT do
287
+ table :fk do
288
+ primary_key :user_id, :null => false, :unsigned => false
289
+ foreign_key [:user_id], :users, :null => false, :key => [:id], :unsigned => false
290
+ end
291
+ EOT
292
+ table :fk do
293
+ primary_key :user_id
294
+ foreign_key [:user_id], :users
295
+ end
296
+ end
297
+ end
298
+
299
+ should 'support compound foreign keys' do
300
+ match_schema <<-EOT do
301
+ table :fk do
302
+ Integer :x, :null => false
303
+ Integer :y, :null => false
304
+ foreign_key [:x, :y], :pk, :null => false, :key => [:a, :b], :unsigned => false
305
+ end
306
+ EOT
307
+ table :fk do
308
+ Integer :x
309
+ Integer :y
310
+ foreign_key [:x, :y], :pk, key: [:a, :b]
311
+ end
312
+ end
313
+ end
314
+
315
+ should 'support unsigned keys' do
316
+ match_schema <<-EOT, unsigned_keys: true do
317
+ table :pk do
318
+ primary_key :id, :null => false, :unsigned => true, :type => :integer
319
+ end
320
+ table :pk2 do
321
+ integer :id, :null => false, :unsigned => true, :primary_key => true
322
+ end
323
+ table :pk3 do
324
+ Integer :a, :null => false
325
+ Integer :b, :null => false
326
+ primary_key [:a, :b], :null => false, :unsigned => true
327
+ end
328
+ table :fk do
329
+ integer :user_id, :null => false, :key => [:id], :unsigned => true, :type => :integer
330
+ foreign_key [:user_id], :users, :null => false, :key => [:id], :unsigned => true, :type => :integer
331
+ end
332
+ table :fk2 do
333
+ primary_key :user_id, :null => false, :unsigned => true, :type => :integer
334
+ foreign_key [:user_id], :users, :null => false, :key => [:id], :unsigned => true
335
+ end
336
+ table :fk3 do
337
+ Integer :x, :null => false
338
+ Integer :y, :null => false
339
+ foreign_key [:x, :y], :pk, :null => false, :key => [:a, :b], :unsigned => true
340
+ end
341
+ EOT
342
+ table :pk do
343
+ primary_key :id
344
+ end
345
+ table :pk2 do
346
+ Key :id, primary_key: true
347
+ end
348
+ table :pk3 do
349
+ Integer :a
350
+ Integer :b
351
+ primary_key [:a, :b]
352
+ end
353
+ table :fk do
354
+ foreign_key :user_id, :users
355
+ end
356
+ table :fk2 do
357
+ primary_key :user_id
358
+ foreign_key [:user_id], :users
359
+ end
360
+ table :fk3 do
361
+ Integer :x
362
+ Integer :y
363
+ foreign_key [:x, :y], :pk, key: [:a, :b]
364
+ end
365
+ end
366
+ end
367
+
368
+ should 'support indexes' do
369
+ match_schema <<-EOT do
370
+ table :index do
371
+ Integer :a, :null => false
372
+ Integer :b, :null => false
373
+ String :s, :null => false
374
+ index [:a], :null => false
375
+ index [:b], :null => false, :unique => true
376
+ index [:a, :b], :null => false
377
+ index [:a, :b, :c], :null => false, :unique => true
378
+ end
379
+ EOT
380
+ table :index do
381
+ Integer :a
382
+ Integer :b
383
+ String :s
384
+ index :a
385
+ unique :b
386
+ index [:a, :b]
387
+ unique [:a, :b, :c]
388
+ end
389
+ end
390
+ end
391
+
392
+ should 'support null columns' do
393
+ match_schema <<-EOT do
394
+ table :null do
395
+ String :string, :null => true
396
+ String :text, :null => true, :text => true
397
+ File :blob, :null => true
398
+ Integer :int, :null => true
399
+ integer :signed, :null => true, :unsigned => false
400
+ integer :unsigned, :null => true, :unsigned => true
401
+ Float :float, :null => true
402
+ TrueClass :bool, :null => true
403
+ TrueClass :true, :null => true, :default => true
404
+ TrueClass :false, :null => true, :default => false
405
+ timestamp :time, :null => true, :default => nil
406
+ integer :user_id, :null => true, :key => [:id], :unsigned => false
407
+ foreign_key [:user_id], :users, :null => true, :key => [:id], :unsigned => false
408
+ end
409
+ EOT
410
+ table :null do
411
+ String? :string
412
+ Text? :text
413
+ File? :blob
414
+ Integer? :int
415
+ Signed? :signed
416
+ Unsigned? :unsigned
417
+ Float? :float
418
+ Bool? :bool
419
+ True? :true
420
+ False? :false
421
+ Time? :time
422
+ foreign_key? :user_id, :users
423
+ end
424
+ end
425
+ end
426
+
427
+ should 'support default values' do
428
+ match_schema <<-EOT do
429
+ table :defaults do
430
+ String :string, :null => false, :default => "abc"
431
+ Integer :int, :null => false, :default => 10
432
+ integer :signed, :null => false, :unsigned => false, :default => -1
433
+ integer :unsigned, :null => false, :unsigned => true, :default => 1000
434
+ Float :float, :null => false, :default => 3.14
435
+ TrueClass :bool, :null => false, :default => true
436
+ timestamp :time, :null => false, :default => "2037-12-31 23:59:59"
437
+ end
438
+ EOT
439
+ table :defaults do
440
+ String :string, default: 'abc'
441
+ Integer :int, default: 10
442
+ Signed :signed, default: -1
443
+ Unsigned :unsigned, default: 1000
444
+ Float :float, default: 3.14
445
+ Bool :bool, default: true
446
+ Time :time, default: '2037-12-31 23:59:59'
447
+ end
448
+ end
449
+ end
450
+
451
+ should 'support arbitrary types and options' do
452
+ match_schema <<-EOT do
453
+ table :whatever do
454
+ Foo :foo, :null => false, :abc => :xyz, :data => ["x", 2, 3.5, :bar], :opts => {:none => true}
455
+ end
456
+ EOT
457
+ table :whatever do
458
+ Foo :foo, abc: :xyz, data: ["x", 2, 3.5, :bar], opts: { none: true }
459
+ end
460
+ end
461
+ end
462
+
463
+ should 'create join tables' do
464
+ match_schema <<-EOT do
465
+ table :left_right do
466
+ integer :left_id, :null => false, :key => [:id], :unsigned => false
467
+ integer :right_id, :null => false, :key => [:id], :unsigned => false
468
+ primary_key [:left_id, :right_id], :null => false, :unsigned => false
469
+ index [:right_id, :left_id], :null => false, :unique => true
470
+ foreign_key [:left_id], :left, :null => false, :key => [:id], :unsigned => false
471
+ foreign_key [:right_id], :right, :null => false, :key => [:id], :unsigned => false
472
+ end
473
+ EOT
474
+ join_table :left_id, :left, :right_id, :right
475
+ end
476
+ end
477
+
478
+ should 'create join tables with custom name' do
479
+ match_schema <<-EOT do
480
+ table :custom_name do
481
+ integer :left_id, :null => false, :key => [:id], :unsigned => false
482
+ integer :right_id, :null => false, :key => [:id], :unsigned => false
483
+ primary_key [:left_id, :right_id], :null => false, :unsigned => false
484
+ index [:right_id, :left_id], :null => false, :unique => true
485
+ foreign_key [:left_id], :left, :null => false, :key => [:id], :unsigned => false
486
+ foreign_key [:right_id], :right, :null => false, :key => [:id], :unsigned => false
487
+ end
488
+ EOT
489
+ join_table :left_id, :left, :right_id, :right, :custom_name
490
+ end
491
+ end
492
+
493
+ should 'create join tables with additional columns' do
494
+ match_schema <<-EOT do
495
+ table :left_right do
496
+ integer :left_id, :null => false, :key => [:id], :unsigned => false
497
+ integer :right_id, :null => false, :key => [:id], :unsigned => false
498
+ primary_key [:left_id, :right_id], :null => false, :unsigned => false
499
+ String :name, :null => false
500
+ index [:right_id, :left_id], :null => false, :unique => true
501
+ foreign_key [:left_id], :left, :null => false, :key => [:id], :unsigned => false
502
+ foreign_key [:right_id], :right, :null => false, :key => [:id], :unsigned => false
503
+ end
504
+ EOT
505
+ join_table :left_id, :left, :right_id, :right do
506
+ String :name
507
+ end
508
+ end
44
509
  end
45
510
 
46
511
  end