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.
- checksums.yaml +4 -4
- data/.travis.yml +3 -0
- data/README.md +7 -5
- data/lib/miguel/importer.rb +44 -38
- data/lib/miguel/migrator.rb +2 -2
- data/lib/miguel/schema.rb +29 -6
- data/miguel.gemspec +4 -1
- data/test/data/db.yml +17 -0
- data/test/data/schema.rb +3 -2
- data/test/data/schema.txt +24 -23
- data/test/data/schema_bare.txt +128 -0
- data/test/data/schema_change.txt +132 -0
- data/test/data/schema_down.txt +32 -0
- data/test/data/schema_full.txt +166 -0
- data/test/data/seq_0.rb +18 -0
- data/test/data/seq_0.txt +17 -0
- data/test/data/seq_1.rb +33 -0
- data/test/data/seq_1.txt +60 -0
- data/test/data/seq_2.rb +38 -0
- data/test/data/seq_2.txt +51 -0
- data/test/data/simple.txt +5 -5
- data/test/helper.rb +24 -0
- data/test/test_importer.rb +66 -0
- data/test/test_migrator.rb +53 -0
- data/test/test_schema.rb +473 -8
- metadata +57 -2
data/test/data/seq_0.rb
ADDED
data/test/data/seq_0.txt
ADDED
@@ -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
|
data/test/data/seq_1.rb
ADDED
@@ -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 #
|
data/test/data/seq_1.txt
ADDED
@@ -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
|
data/test/data/seq_2.rb
ADDED
@@ -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 #
|
data/test/data/seq_2.txt
ADDED
@@ -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
|
2
|
+
primary_key :id, :null => false, :unsigned => false
|
3
3
|
String :name, :null => false
|
4
|
-
integer :parent_id, :null => false, :key => [:id], :unsigned => false
|
5
|
-
timestamp :create_time, :null => false, :default => "
|
6
|
-
timestamp :update_time, :null => false, :default => "
|
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
|
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
|
-
|
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
|
11
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|