wineskins 0.2.2
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/.gitignore +9 -0
- data/LICENSE.txt +18 -0
- data/README.markdown +235 -0
- data/Rakefile +7 -0
- data/bin/wskins +5 -0
- data/lib/wineskins.rb +269 -0
- data/lib/wineskins/record_methods.rb +25 -0
- data/lib/wineskins/runner.rb +132 -0
- data/lib/wineskins/schema_methods.rb +100 -0
- data/lib/wineskins/transcript.rb +24 -0
- data/lib/wineskins/utils.rb +19 -0
- data/lib/wineskins/version.rb +3 -0
- data/lib/wineskins_cli.rb +3 -0
- data/test/helper.rb +128 -0
- data/test/helpers/transfer_assertions.rb +102 -0
- data/test/suite.rb +3 -0
- data/test/test_transfer_callbacks.rb +52 -0
- data/test/test_transfer_run_table.rb +172 -0
- data/test/test_transfer_run_tables.rb +131 -0
- data/todo.yml +10 -0
- data/wineskins.gemspec +25 -0
- metadata +98 -0
data/test/suite.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require File.expand_path('helper', File.dirname(__FILE__))
|
2
|
+
require File.expand_path('../lib/wineskins', File.dirname(__FILE__))
|
3
|
+
|
4
|
+
TEST_DB.source_connect = 'sqlite://test/fixtures/db/source.sqlite3'
|
5
|
+
TEST_DB.dest_connect = 'sqlite://test/fixtures/db/dest.sqlite3'
|
6
|
+
|
7
|
+
describe 'Transfer#run callbacks, functional' do
|
8
|
+
|
9
|
+
subject { Wineskins::Transfer.new(source,dest) }
|
10
|
+
let(:source) { TEST_DB.source }
|
11
|
+
let(:dest) { TEST_DB.dest }
|
12
|
+
|
13
|
+
before do
|
14
|
+
TEST_DB.setup_source :users
|
15
|
+
TEST_DB.setup_dest
|
16
|
+
spy = []
|
17
|
+
subject.define do
|
18
|
+
table :users
|
19
|
+
|
20
|
+
after { spy << :after }
|
21
|
+
after { spy << source[:users].count }
|
22
|
+
after_create_tables { spy << :after_create_tables }
|
23
|
+
after_create_indexes { spy << :after_create_indexes }
|
24
|
+
after_create_fk_constraints { spy << :after_create_fk_constraints }
|
25
|
+
after_insert_records { spy << :after_insert_records }
|
26
|
+
before_insert_records { spy << :before_insert_records }
|
27
|
+
before_create_indexes { spy << :before_create_indexes }
|
28
|
+
before_create_tables { spy << :before_create_tables }
|
29
|
+
before_create_fk_constraints { spy << :before_create_fk_constraints }
|
30
|
+
before { spy << :before }
|
31
|
+
|
32
|
+
end.run
|
33
|
+
@spy = spy
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should trigger callbacks in order' do
|
37
|
+
exp = [:before,
|
38
|
+
:before_create_tables,
|
39
|
+
:after_create_tables,
|
40
|
+
:before_create_indexes,
|
41
|
+
:after_create_indexes,
|
42
|
+
:before_create_fk_constraints,
|
43
|
+
:after_create_fk_constraints,
|
44
|
+
:before_insert_records,
|
45
|
+
:after_insert_records,
|
46
|
+
:after,
|
47
|
+
source[:users].count
|
48
|
+
]
|
49
|
+
assert_equal exp, @spy
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,172 @@
|
|
1
|
+
require File.expand_path('helper', File.dirname(__FILE__))
|
2
|
+
require File.expand_path('helpers/transfer_assertions', File.dirname(__FILE__))
|
3
|
+
require File.expand_path('../lib/wineskins', File.dirname(__FILE__))
|
4
|
+
|
5
|
+
TEST_DB.source_connect = 'sqlite://test/fixtures/db/source.sqlite3'
|
6
|
+
TEST_DB.dest_connect = 'sqlite://test/fixtures/db/dest.sqlite3'
|
7
|
+
|
8
|
+
describe 'Transfer#run, functional' do
|
9
|
+
|
10
|
+
subject { Wineskins::Transfer.new(source,dest) }
|
11
|
+
let(:source) { TEST_DB.source }
|
12
|
+
let(:dest) { TEST_DB.dest }
|
13
|
+
|
14
|
+
#------------------------------------------
|
15
|
+
describe 'single table, default options' do
|
16
|
+
include TransferAssertions
|
17
|
+
|
18
|
+
before do
|
19
|
+
TEST_DB.setup_source :users, :test_categories, :tests
|
20
|
+
TEST_DB.setup_dest :users, :test_categories
|
21
|
+
subject.define do
|
22
|
+
table :tests
|
23
|
+
end.run
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should create a table in dest' do
|
27
|
+
assert_includes dest.tables, :tests
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should match schema specs in source' do
|
31
|
+
assert_columns_match(:tests)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should match index specs in source' do
|
35
|
+
assert_indexes_match(:tests)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should match foreign key specs in source' do
|
39
|
+
assert_fk_match(:tests)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should have the same number of records as in source' do
|
43
|
+
assert_equal source[:tests].count, dest[:tests].count
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should have the same range of primary keys as in source' do
|
47
|
+
assert_equal source[:tests].get{max(id)}, dest[:tests].get{max(id)}
|
48
|
+
assert_equal source[:tests].get{min(id)}, dest[:tests].get{min(id)}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
#------------------------------------------
|
53
|
+
describe 'multiple tables, default options' do
|
54
|
+
include TransferAssertions
|
55
|
+
|
56
|
+
before do
|
57
|
+
TEST_DB.setup_source :users, :test_categories, :tests
|
58
|
+
TEST_DB.setup_dest
|
59
|
+
subject.define do
|
60
|
+
table :test_categories
|
61
|
+
table :users
|
62
|
+
table :tests
|
63
|
+
end.run
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should create tables in dest' do
|
67
|
+
assert_includes dest.tables, :test_categories
|
68
|
+
assert_includes dest.tables, :users
|
69
|
+
assert_includes dest.tables, :tests
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should match schema specs in source' do
|
73
|
+
assert_columns_match(:test_categories)
|
74
|
+
assert_columns_match(:users)
|
75
|
+
assert_columns_match(:tests)
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should match index specs in source' do
|
79
|
+
assert_indexes_match(:test_categories)
|
80
|
+
assert_indexes_match(:users)
|
81
|
+
assert_indexes_match(:tests)
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'should match foreign key specs in source' do
|
85
|
+
assert_fk_match(:test_categories)
|
86
|
+
assert_fk_match(:users)
|
87
|
+
assert_fk_match(:tests)
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'each table should have the same number of records as in source' do
|
91
|
+
assert_equal source[:test_categories].count, dest[:test_categories].count
|
92
|
+
assert_equal source[:users].count, dest[:users].count
|
93
|
+
assert_equal source[:tests].count, dest[:tests].count
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'each table should have the same range of primary keys as in source' do
|
97
|
+
assert_equal source[:test_categories].get{max(id)}, dest[:test_categories].get{max(id)}
|
98
|
+
assert_equal source[:test_categories].get{min(id)}, dest[:test_categories].get{min(id)}
|
99
|
+
|
100
|
+
assert_equal source[:users].get{max(uid)}, dest[:users].get{max(uid)}
|
101
|
+
assert_equal source[:users].get{min(uid)}, dest[:users].get{min(uid)}
|
102
|
+
|
103
|
+
assert_equal source[:tests].get{max(id)}, dest[:tests].get{max(id)}
|
104
|
+
assert_equal source[:tests].get{min(id)}, dest[:tests].get{min(id)}
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
#------------------------------------------
|
110
|
+
describe 'single table, rename columns with hash' do
|
111
|
+
include TransferAssertions
|
112
|
+
|
113
|
+
before do
|
114
|
+
TEST_DB.setup_source :users, :test_categories, :tests
|
115
|
+
TEST_DB.setup_dest :users, :test_categories
|
116
|
+
subject.define do
|
117
|
+
table :tests do
|
118
|
+
rename :user_id => :uid, :name => :testname
|
119
|
+
end
|
120
|
+
end.run
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'should match schema specs in source, with renamed columns' do
|
124
|
+
assert_column_matches(:tests, [:user_id, :uid])
|
125
|
+
assert_column_matches(:tests, [:name, :testname])
|
126
|
+
[:score, :taken_at, :cat_id].each do |col|
|
127
|
+
assert_column_matches(:tests, col)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'should match index specs in source, with renamed columns' do
|
132
|
+
assert_index_matches(:tests, [:name], {:name => :testname})
|
133
|
+
assert_index_matches(:tests, [:score])
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'should match foreign key specs in source, with renamed columns' do
|
137
|
+
assert_fk_matches(:tests, [:user_id], {:user_id => :uid})
|
138
|
+
assert_fk_matches(:tests, [:cat_id])
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
142
|
+
|
143
|
+
#------------------------------------------
|
144
|
+
describe 'single table, alternative column options passed for existing columns' do
|
145
|
+
include TransferAssertions
|
146
|
+
|
147
|
+
before do
|
148
|
+
TEST_DB.setup_source :users, :test_categories, :tests
|
149
|
+
TEST_DB.setup_dest :users, :test_categories
|
150
|
+
subject.define do
|
151
|
+
table :tests do
|
152
|
+
column :id, :integer
|
153
|
+
column :name, :text, :null => false, :default => 'unknown'
|
154
|
+
end
|
155
|
+
end.run
|
156
|
+
end
|
157
|
+
|
158
|
+
it 'should match passed specs for alternate columns, and source specs for other columns' do
|
159
|
+
assert_column_matches(:tests, :id,
|
160
|
+
{:allow_null => true, :primary_key => false, :default => nil}
|
161
|
+
)
|
162
|
+
assert_column_matches(:tests, :name,
|
163
|
+
{:allow_null => false, :primary_key => false, :default => "'unknown'"}
|
164
|
+
)
|
165
|
+
[:score, :taken_at, :cat_id].each do |col|
|
166
|
+
assert_column_matches(:tests, col)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
171
|
+
|
172
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require File.expand_path('helper', File.dirname(__FILE__))
|
2
|
+
require File.expand_path('helpers/transfer_assertions', File.dirname(__FILE__))
|
3
|
+
require File.expand_path('../lib/wineskins', File.dirname(__FILE__))
|
4
|
+
|
5
|
+
TEST_DB.source_connect = 'sqlite://test/fixtures/db/source.sqlite3'
|
6
|
+
TEST_DB.dest_connect = 'sqlite://test/fixtures/db/dest.sqlite3'
|
7
|
+
|
8
|
+
describe 'Transfer#run, functional' do
|
9
|
+
|
10
|
+
subject { Wineskins::Transfer.new(source,dest) }
|
11
|
+
let(:source) { TEST_DB.source }
|
12
|
+
let(:dest) { TEST_DB.dest }
|
13
|
+
|
14
|
+
#------------------------------------------
|
15
|
+
describe 'tables, none specified, default options' do
|
16
|
+
|
17
|
+
before do
|
18
|
+
TEST_DB.setup_source :users, :test_categories, :tests
|
19
|
+
TEST_DB.setup_dest
|
20
|
+
subject.define do
|
21
|
+
tables
|
22
|
+
end.run
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should create all tables in dest' do
|
26
|
+
assert_equal source.tables.sort, dest.tables.sort
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should match number of records in all tables in dest' do
|
30
|
+
[:users, :test_categories, :tests].each do |tbl|
|
31
|
+
assert_equal source[tbl].count, dest[tbl].count
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
#------------------------------------------
|
38
|
+
describe 'tables, some specified, some with table rename, default options' do
|
39
|
+
|
40
|
+
before do
|
41
|
+
TEST_DB.setup_source :users, :test_categories, :tests
|
42
|
+
TEST_DB.setup_dest
|
43
|
+
subject.define do
|
44
|
+
tables :users, [:test_categories, :categories_of_tests]
|
45
|
+
end.run
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should create all specified tables in dest' do
|
49
|
+
assert_equal [:categories_of_tests, :users], dest.tables.sort
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should match number of records in all tables in dest' do
|
53
|
+
[[:users, :users],
|
54
|
+
[:test_categories, :categories_of_tests]
|
55
|
+
].each do |(src_tbl, dst_tbl)|
|
56
|
+
assert_equal source[src_tbl].count, dest[dst_tbl].count
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
#------------------------------------------
|
63
|
+
# these next tests don't really belong here, but to stick them somewhere for now
|
64
|
+
#------------------------------------------
|
65
|
+
|
66
|
+
describe 'tables, some specified with options' do
|
67
|
+
|
68
|
+
before do
|
69
|
+
TEST_DB.setup_source :users, :test_categories, :tests
|
70
|
+
TEST_DB.setup_dest
|
71
|
+
subject.define do
|
72
|
+
tables :users, :test_categories, :create_fk_constraints => false
|
73
|
+
table :tests
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should have passed option for all tables specified with option' do
|
78
|
+
subject.table_defs[0..1].each do |t|
|
79
|
+
assert_equal false, t.create_fk_constraints?
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'should have default option for all tables not specified with option' do
|
84
|
+
subject.table_defs[2..2].each do |t|
|
85
|
+
assert_equal true, t.create_fk_constraints?
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
describe 'schema_only option' do
|
92
|
+
before do
|
93
|
+
TEST_DB.setup_source :users, :test_categories, :tests
|
94
|
+
TEST_DB.setup_dest
|
95
|
+
subject.define do
|
96
|
+
tables :users, :test_categories, :schema_only => true
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'should have create tables, indexes, fk constraints options true, and insert records option false' do
|
101
|
+
subject.table_defs.each do |t|
|
102
|
+
assert_equal true, t.create_table?
|
103
|
+
assert_equal true, t.create_indexes?
|
104
|
+
assert_equal true, t.create_fk_constraints?
|
105
|
+
assert_equal false, t.insert_records?
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
describe 'records_only option' do
|
112
|
+
before do
|
113
|
+
TEST_DB.setup_source :users, :test_categories, :tests
|
114
|
+
TEST_DB.setup_dest :users, :test_categories
|
115
|
+
subject.define do
|
116
|
+
tables :users, :test_categories, :records_only => true
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'should have create tables, indexes, fk constraints options false, and insert records option true' do
|
121
|
+
subject.table_defs.each do |t|
|
122
|
+
assert_equal false, t.create_table?
|
123
|
+
assert_equal false, t.create_indexes?
|
124
|
+
assert_equal false, t.create_fk_constraints?
|
125
|
+
assert_equal true, t.insert_records?
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
data/todo.yml
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
Todo
|
2
|
+
-------
|
3
|
+
DSL:
|
4
|
+
- implement table.exclude, table.include
|
5
|
+
- add insert_records filtering
|
6
|
+
- regex and/or proc -based field and table renaming
|
7
|
+
|
8
|
+
Other:
|
9
|
+
- set up test environment to easily test vs different adapters
|
10
|
+
- add default validations of imported data + ability to define custom validations, possibly via minitest
|
data/wineskins.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require File.expand_path("lib/wineskins/version", File.dirname(__FILE__))
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = "wineskins"
|
5
|
+
s.version = Wineskins::VERSION
|
6
|
+
s.authors = ["Eric Gjertsen"]
|
7
|
+
s.email = ["ericgj72@gmail.com"]
|
8
|
+
s.homepage = ""
|
9
|
+
s.summary = %q{Simple database transfer utility using Sequel}
|
10
|
+
s.description = %q{Simple database transfer utility using Sequel}
|
11
|
+
|
12
|
+
s.rubyforge_project = ""
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.test_files = `git ls-files -- test/*`.split("\n")
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
s.executables << 'wskins'
|
18
|
+
|
19
|
+
s.requirements << "ruby >= 1.8.7"
|
20
|
+
s.requirements << "progressbar gem (optional)"
|
21
|
+
|
22
|
+
s.add_runtime_dependency 'sequel', '~> 3.0'
|
23
|
+
|
24
|
+
s.add_development_dependency 'minitest'
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: wineskins
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Eric Gjertsen
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-09-06 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: sequel
|
16
|
+
requirement: &7365860 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '3.0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *7365860
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: minitest
|
27
|
+
requirement: &7365460 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *7365460
|
36
|
+
description: Simple database transfer utility using Sequel
|
37
|
+
email:
|
38
|
+
- ericgj72@gmail.com
|
39
|
+
executables:
|
40
|
+
- wskins
|
41
|
+
extensions: []
|
42
|
+
extra_rdoc_files: []
|
43
|
+
files:
|
44
|
+
- .gitignore
|
45
|
+
- LICENSE.txt
|
46
|
+
- README.markdown
|
47
|
+
- Rakefile
|
48
|
+
- bin/wskins
|
49
|
+
- lib/wineskins.rb
|
50
|
+
- lib/wineskins/record_methods.rb
|
51
|
+
- lib/wineskins/runner.rb
|
52
|
+
- lib/wineskins/schema_methods.rb
|
53
|
+
- lib/wineskins/transcript.rb
|
54
|
+
- lib/wineskins/utils.rb
|
55
|
+
- lib/wineskins/version.rb
|
56
|
+
- lib/wineskins_cli.rb
|
57
|
+
- test/helper.rb
|
58
|
+
- test/helpers/transfer_assertions.rb
|
59
|
+
- test/suite.rb
|
60
|
+
- test/test_transfer_callbacks.rb
|
61
|
+
- test/test_transfer_run_table.rb
|
62
|
+
- test/test_transfer_run_tables.rb
|
63
|
+
- todo.yml
|
64
|
+
- wineskins.gemspec
|
65
|
+
homepage: ''
|
66
|
+
licenses: []
|
67
|
+
post_install_message:
|
68
|
+
rdoc_options: []
|
69
|
+
require_paths:
|
70
|
+
- lib
|
71
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
none: false
|
79
|
+
requirements:
|
80
|
+
- - ! '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
requirements:
|
84
|
+
- ruby >= 1.8.7
|
85
|
+
- progressbar gem (optional)
|
86
|
+
rubyforge_project: ''
|
87
|
+
rubygems_version: 1.8.10
|
88
|
+
signing_key:
|
89
|
+
specification_version: 3
|
90
|
+
summary: Simple database transfer utility using Sequel
|
91
|
+
test_files:
|
92
|
+
- test/helper.rb
|
93
|
+
- test/helpers/transfer_assertions.rb
|
94
|
+
- test/suite.rb
|
95
|
+
- test/test_transfer_callbacks.rb
|
96
|
+
- test/test_transfer_run_table.rb
|
97
|
+
- test/test_transfer_run_tables.rb
|
98
|
+
has_rdoc:
|