data_migrater 0.2.0 → 0.3.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +93 -3
- data/lib/data_migrater.rb +3 -1
- data/lib/data_migrater/collection.rb +3 -1
- data/lib/data_migrater/csv.rb +47 -0
- data/lib/data_migrater/logger.rb +19 -13
- data/lib/data_migrater/migration.rb +2 -0
- data/lib/data_migrater/migrator.rb +2 -0
- data/lib/data_migrater/version.rb +3 -1
- data/lib/data_migration.rb +2 -0
- data/lib/generators/data_migrater/create_generator.rb +3 -1
- data/lib/generators/data_migrater/install_generator.rb +3 -1
- data/lib/generators/data_migrater/templates/config/initializers/data_migrater.rb +2 -0
- data/lib/generators/data_migrater/templates/db/migrate/create_data_migrations.rb +2 -0
- data/spec/collection_spec.rb +7 -7
- data/spec/csv/converters_spec.rb +36 -0
- data/spec/csv/csv_path_spec.rb +82 -0
- data/spec/csv/csv_spec.rb +30 -0
- data/spec/csv/options_spec.rb +30 -0
- data/spec/data_migration_spec.rb +7 -5
- data/spec/logger/data_logger_spec.rb +20 -22
- data/spec/logger/logger_path_spec.rb +82 -0
- data/spec/migrater_spec.rb +11 -11
- data/spec/migration_spec.rb +8 -6
- data/spec/spec_helper.rb +2 -0
- data/spec/support/common.rb +2 -0
- data/spec/support/csv/dummy.csv +3 -0
- data/spec/support/database_cleaner.rb +2 -0
- data/spec/support/local/dummy.csv +3 -0
- data/spec/support/migrate.rb +2 -0
- metadata +40 -15
- data/spec/csv/data_csv_spec.rb +0 -31
- data/spec/support/methods.rb +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d18ad057ff627de12fb89e183f32f399fc5982bf
|
4
|
+
data.tar.gz: 71d9bc74af6bedeb81e810512584b20649d26aa0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: acd8775f066a903ed373309b4c06c934301aaa76ec1a41bcfe769271d3d2c33c69d8f0559bc7d35bdfb91921978e17bf909bfaa7c0de831acd35391759443988
|
7
|
+
data.tar.gz: 7b8c18ec30448b76280a87bca602a335133d11f11b09d2aa4344ae98a0eda6824a0d49620b4883df1574721fc9bebee4f6ecc9560a08f10b3c62cc28543dc0a4
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -28,9 +28,9 @@ rails g data_migrater:create name
|
|
28
28
|
```
|
29
29
|
|
30
30
|
Check your `db/data_migrate` folder, the data migration will be there.
|
31
|
-
Next time your application run, all pending data migration will be
|
31
|
+
Next time your application run, all pending data migration will be executed.
|
32
32
|
|
33
|
-
##
|
33
|
+
## Logger
|
34
34
|
|
35
35
|
You can send your log to a file including the module `DataMigrater::Logger`.
|
36
36
|
|
@@ -60,7 +60,97 @@ end
|
|
60
60
|
|
61
61
|
#### Options
|
62
62
|
|
63
|
-
`
|
63
|
+
- `dir`: Directory where log will be;
|
64
|
+
- `file`: File name;
|
65
|
+
- `path`: Composition of `dir/file` when you want give a fully qualified path. Default: `log/class_name.log`.
|
66
|
+
|
67
|
+
## CSV
|
68
|
+
|
69
|
+
You can parse CSV on the fly using the module `DataMigrater::CSV`.
|
70
|
+
|
71
|
+
```
|
72
|
+
class MyDataMigration
|
73
|
+
include DataMigrater::CSV
|
74
|
+
|
75
|
+
def execute
|
76
|
+
# parsed from `db/data_migrate/support/csv/my_data_migration.csv`
|
77
|
+
csv.each do |line|
|
78
|
+
Object.create! line
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
```
|
83
|
+
|
84
|
+
By default, the class name is used and the file is parsed from `db/data_migrate/support/csv` folder. You can change it:
|
85
|
+
|
86
|
+
```
|
87
|
+
class MyDataMigration
|
88
|
+
include DataMigrater::CSV
|
89
|
+
|
90
|
+
data_csv path: "/tmp/objects.csv"
|
91
|
+
|
92
|
+
def execute
|
93
|
+
# parsed from `/tmp/objects.csv`
|
94
|
+
csv.each do |line|
|
95
|
+
Object.create! line
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
```
|
100
|
+
|
101
|
+
You can process a batch of items using the `chunk_size`:
|
102
|
+
|
103
|
+
```
|
104
|
+
class MyDataMigration
|
105
|
+
include DataMigrater::CSV
|
106
|
+
|
107
|
+
data_csv chunk_size: 2
|
108
|
+
|
109
|
+
def execute
|
110
|
+
csv.each do |line|
|
111
|
+
# line:
|
112
|
+
#
|
113
|
+
# [
|
114
|
+
# { first_name: 'Washington', last_name: 'Botelho' },
|
115
|
+
# { first_name: 'Lucas' , last_name: 'Souza' }
|
116
|
+
# ]
|
117
|
+
|
118
|
+
Object.create! line
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
```
|
123
|
+
|
124
|
+
You can rename the keys inside the iterated data using the option `key_mapping`:
|
125
|
+
|
126
|
+
```
|
127
|
+
class MyDataMigration
|
128
|
+
include DataMigrater::CSV
|
129
|
+
|
130
|
+
data_csv key_mapping: { first_name: :first }
|
131
|
+
|
132
|
+
def execute
|
133
|
+
csv.each do |line|
|
134
|
+
Object.create! line # { first: 'Washington', last_name: 'Botelho' }
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
```
|
139
|
+
|
140
|
+
#### Options
|
141
|
+
|
142
|
+
- `dir`: Directory where CSV is located;
|
143
|
+
- `file`: File name;
|
144
|
+
- `path`: Composition of `dir/file` when you want give a fully qualified path. Default: `db/data_migrate/support/csv/class_name.csv`.
|
145
|
+
|
146
|
+
---
|
147
|
+
|
148
|
+
##### CSV Options:
|
149
|
+
|
150
|
+
- `chunk_size`: Batch parse size;
|
151
|
+
- `key_mapping`: Key name alias.
|
152
|
+
|
153
|
+
For more CSV options, check the project [Smarter CSV](https://github.com/tilo/smarter_csv):
|
64
154
|
|
65
155
|
## Test
|
66
156
|
|
data/lib/data_migrater.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DataMigrater
|
2
4
|
end
|
3
5
|
|
4
6
|
require 'data_migration'
|
5
7
|
|
6
8
|
require 'data_migrater/collection'
|
7
|
-
|
9
|
+
require 'data_migrater/csv'
|
8
10
|
require 'data_migrater/logger'
|
9
11
|
require 'data_migrater/migration'
|
10
12
|
require 'data_migrater/migrator'
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DataMigrater
|
2
4
|
class Collection
|
3
5
|
def initialize(path = "#{Rails.root}/db/data_migrate")
|
@@ -14,7 +16,7 @@ module DataMigrater
|
|
14
16
|
|
15
17
|
def migration_for(file)
|
16
18
|
if file =~ migration_pattern
|
17
|
-
DataMigrater::Migration.new
|
19
|
+
DataMigrater::Migration.new Regexp.last_match(1).to_i, Regexp.last_match(2), "#{Regexp.last_match(1)}_#{Regexp.last_match(2)}"
|
18
20
|
end
|
19
21
|
end
|
20
22
|
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DataMigrater
|
4
|
+
module CSV
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
require 'smarter_csv'
|
8
|
+
|
9
|
+
included do
|
10
|
+
def csv
|
11
|
+
result = ::SmarterCSV.process(csv_path, csv_options)
|
12
|
+
|
13
|
+
result
|
14
|
+
end
|
15
|
+
|
16
|
+
def csv_path
|
17
|
+
return csv_options[:path] if csv_options[:path].present?
|
18
|
+
|
19
|
+
[csv_dir, csv_file].join '/'
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def csv_dir
|
25
|
+
csv_options.delete(:dir) || 'db/data_migrate/support/csv'
|
26
|
+
end
|
27
|
+
|
28
|
+
def csv_file
|
29
|
+
csv_options.delete(:file) || "#{self.class.name.underscore}.csv"
|
30
|
+
end
|
31
|
+
|
32
|
+
def csv_options
|
33
|
+
self.class.csv_options
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
module ClassMethods
|
38
|
+
def data_csv(options = {})
|
39
|
+
@options = options
|
40
|
+
end
|
41
|
+
|
42
|
+
def csv_options
|
43
|
+
@options || {}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/data_migrater/logger.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DataMigrater
|
2
4
|
module Logger
|
3
5
|
extend ActiveSupport::Concern
|
@@ -6,43 +8,47 @@ module DataMigrater
|
|
6
8
|
def logger
|
7
9
|
return @logger if @logger
|
8
10
|
|
9
|
-
@logger = ::Logger.new(
|
11
|
+
@logger = ::Logger.new(logger_path)
|
10
12
|
|
11
13
|
@logger.formatter = formatter
|
12
14
|
|
13
15
|
@logger
|
14
16
|
end
|
15
17
|
|
16
|
-
|
18
|
+
def logger_path
|
19
|
+
return logger_options[:path] if logger_options[:path].present?
|
17
20
|
|
18
|
-
|
19
|
-
"log/#{self.class.name.underscore}.log"
|
21
|
+
[logger_dir, logger_file].join '/'
|
20
22
|
end
|
21
23
|
|
24
|
+
private
|
25
|
+
|
22
26
|
def formatter
|
23
|
-
|
27
|
+
lambda do |severity, datetime, _progname, message|
|
24
28
|
"[#{datetime}] #{severity} #{self.class.name}: #{message}\n"
|
25
29
|
end
|
26
30
|
end
|
27
31
|
|
28
|
-
def
|
29
|
-
|
32
|
+
def logger_dir
|
33
|
+
logger_options.delete(:dir) || :log
|
30
34
|
end
|
31
35
|
|
32
|
-
def
|
33
|
-
|
36
|
+
def logger_file
|
37
|
+
logger_options.delete(:file) || "#{self.class.name.underscore}.log"
|
38
|
+
end
|
34
39
|
|
35
|
-
|
40
|
+
def logger_options
|
41
|
+
self.class.logger_options
|
36
42
|
end
|
37
43
|
end
|
38
44
|
|
39
|
-
|
45
|
+
module ClassMethods
|
40
46
|
def data_logger(options = {})
|
41
47
|
@options = options
|
42
48
|
end
|
43
49
|
|
44
|
-
def
|
45
|
-
@options
|
50
|
+
def logger_options
|
51
|
+
@options || {}
|
46
52
|
end
|
47
53
|
end
|
48
54
|
end
|
data/lib/data_migration.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DataMigrater
|
2
4
|
class CreateGenerator < Rails::Generators::Base
|
3
5
|
source_root File.expand_path('../templates', __FILE__)
|
4
6
|
|
5
7
|
argument :name, type: :string
|
6
8
|
|
7
|
-
desc
|
9
|
+
desc 'create a skeleton data migration.'
|
8
10
|
|
9
11
|
def create_migrate_file
|
10
12
|
tmpl = 'db/data_migrate/data_migrate.rb.erb'
|
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module DataMigrater
|
2
4
|
class InstallGenerator < Rails::Generators::Base
|
3
5
|
source_root File.expand_path('../templates', __FILE__)
|
4
6
|
|
5
|
-
desc
|
7
|
+
desc 'creates an initializer and copy necessary files.'
|
6
8
|
|
7
9
|
def create_data_folder
|
8
10
|
FileUtils.mkdir_p 'db/data_migrate'
|
data/spec/collection_spec.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe DataMigrater::Collection do
|
@@ -9,17 +11,15 @@ describe DataMigrater::Collection do
|
|
9
11
|
allow(Rails).to receive(:root) { '.' }
|
10
12
|
end
|
11
13
|
|
12
|
-
after
|
13
|
-
FileUtils.rm_rf 'db'
|
14
|
-
end
|
14
|
+
after { FileUtils.rm_rf 'db' }
|
15
15
|
|
16
16
|
describe '.migrations' do
|
17
|
-
let(:file_1) { '20151205090800_add_column' }
|
18
|
-
let(:file_2) { '20151205090801_rename_column' }
|
19
|
-
let(:file_3) { 'invalid_20151205090802_remove_column' }
|
20
|
-
|
21
17
|
subject { described_class.new path }
|
22
18
|
|
19
|
+
let!(:file_1) { '20151205090800_add_column' }
|
20
|
+
let!(:file_2) { '20151205090801_rename_column' }
|
21
|
+
let!(:file_3) { 'invalid_20151205090802_remove_column' }
|
22
|
+
|
23
23
|
before do
|
24
24
|
FileUtils.touch "#{path}/#{file_1}.rb"
|
25
25
|
FileUtils.touch "#{path}/#{file_2}.rb"
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe '#converters' do
|
6
|
+
before do
|
7
|
+
stub_const 'Dummy', Class.new
|
8
|
+
|
9
|
+
Dummy.class_eval { include DataMigrater::CSV }
|
10
|
+
Dummy.class_eval { data_csv dir: 'spec/support/csv', value_converters: { birthday: DateConverter } }
|
11
|
+
end
|
12
|
+
|
13
|
+
class DateConverter
|
14
|
+
def self.convert(value)
|
15
|
+
Date.strptime value, '%d/%m/%y'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'returns an array of hash' do
|
20
|
+
expect(Dummy.new.csv).to eq [
|
21
|
+
{
|
22
|
+
first_name: 'Washington',
|
23
|
+
last_name: 'Botelho',
|
24
|
+
username: 'wbotelhos',
|
25
|
+
age: 32,
|
26
|
+
birthday: Date.strptime('23/10/1984', '%d/%m/%y')
|
27
|
+
},
|
28
|
+
|
29
|
+
{
|
30
|
+
first_name: 'Lucas',
|
31
|
+
last_name: 'Souza',
|
32
|
+
username: 'lucasas'
|
33
|
+
}
|
34
|
+
]
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe '#csv_path' do
|
6
|
+
context 'with :path' do
|
7
|
+
before do
|
8
|
+
stub_const 'Dummy', Class.new
|
9
|
+
|
10
|
+
Dummy.class_eval { include DataMigrater::CSV }
|
11
|
+
Dummy.class_eval { data_csv path: '/tmp/custom.csv' }
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'uses the given one' do
|
15
|
+
expect(Dummy.new.csv_path).to eq '/tmp/custom.csv'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'with :dir' do
|
20
|
+
before do
|
21
|
+
stub_const 'Dummy', Class.new
|
22
|
+
|
23
|
+
Dummy.class_eval { include DataMigrater::CSV }
|
24
|
+
Dummy.class_eval { data_csv dir: :dir }
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'uses the given :dir on path' do
|
28
|
+
expect(Dummy.new.csv_path).to eq 'dir/dummy.csv'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'with :file' do
|
33
|
+
before do
|
34
|
+
stub_const 'Dummy', Class.new
|
35
|
+
|
36
|
+
Dummy.class_eval { include DataMigrater::CSV }
|
37
|
+
Dummy.class_eval { data_csv file: 'file.odd' }
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'uses the given :file on path' do
|
41
|
+
expect(Dummy.new.csv_path).to eq 'db/data_migrate/support/csv/file.odd'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'with :dir and :file' do
|
46
|
+
before do
|
47
|
+
stub_const 'Dummy', Class.new
|
48
|
+
|
49
|
+
Dummy.class_eval { include DataMigrater::CSV }
|
50
|
+
Dummy.class_eval { data_csv dir: :dir, file: 'file.odd' }
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'uses the given :dir and :file as path' do
|
54
|
+
expect(Dummy.new.csv_path).to eq 'dir/file.odd'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'with not :dir nor :file' do
|
59
|
+
before do
|
60
|
+
stub_const 'Dummy', Class.new
|
61
|
+
|
62
|
+
Dummy.class_eval { include DataMigrater::CSV }
|
63
|
+
Dummy.class_eval { data_csv }
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'uses the default :dir and :file as path' do
|
67
|
+
expect(Dummy.new.csv_path).to eq 'db/data_migrate/support/csv/dummy.csv'
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'with no callback options method' do
|
72
|
+
before do
|
73
|
+
stub_const 'Dummy', Class.new
|
74
|
+
|
75
|
+
Dummy.class_eval { include DataMigrater::CSV }
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'uses the default :dir and :file as path' do
|
79
|
+
expect(Dummy.new.csv_path).to eq 'db/data_migrate/support/csv/dummy.csv'
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe '#data_csv' do
|
6
|
+
before do
|
7
|
+
stub_const 'Dummy', Class.new
|
8
|
+
|
9
|
+
Dummy.class_eval { include DataMigrater::CSV }
|
10
|
+
Dummy.class_eval { data_csv dir: 'spec/support/csv' }
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'returns an array of hash' do
|
14
|
+
expect(Dummy.new.csv).to eq [
|
15
|
+
{
|
16
|
+
first_name: 'Washington',
|
17
|
+
last_name: 'Botelho',
|
18
|
+
username: 'wbotelhos',
|
19
|
+
age: 32,
|
20
|
+
birthday: '23/10/1984'
|
21
|
+
},
|
22
|
+
|
23
|
+
{
|
24
|
+
first_name: 'Lucas',
|
25
|
+
last_name: 'Souza',
|
26
|
+
username: 'lucasas'
|
27
|
+
}
|
28
|
+
]
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe '#options' do
|
6
|
+
before do
|
7
|
+
stub_const 'Dummy', Class.new
|
8
|
+
|
9
|
+
Dummy.class_eval { include DataMigrater::CSV }
|
10
|
+
Dummy.class_eval { data_csv dir: 'spec/support/csv', chunk_size: 1, key_mapping: { first_name: :first } }
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'applies the options on csv gem' do
|
14
|
+
expect(Dummy.new.csv).to eq [
|
15
|
+
[{
|
16
|
+
first: 'Washington',
|
17
|
+
last_name: 'Botelho',
|
18
|
+
username: 'wbotelhos',
|
19
|
+
age: 32,
|
20
|
+
birthday: '23/10/1984'
|
21
|
+
}],
|
22
|
+
|
23
|
+
[{
|
24
|
+
first: 'Lucas',
|
25
|
+
last_name: 'Souza',
|
26
|
+
username: 'lucasas'
|
27
|
+
}]
|
28
|
+
]
|
29
|
+
end
|
30
|
+
end
|
data/spec/data_migration_spec.rb
CHANGED
@@ -1,15 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe DataMigration do
|
4
6
|
let(:version) { '19841023113000' }
|
5
7
|
|
6
|
-
it { expect(
|
8
|
+
it { expect(described_class.new(version: version)).to be_valid }
|
7
9
|
|
8
10
|
it 'validates uniqueness' do
|
9
|
-
|
11
|
+
described_class.create! version: version
|
10
12
|
|
11
|
-
expect
|
12
|
-
|
13
|
-
|
13
|
+
expect do
|
14
|
+
described_class.create! version: version
|
15
|
+
end.to raise_error ActiveRecord::RecordInvalid
|
14
16
|
end
|
15
17
|
end
|
@@ -1,32 +1,30 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe '#data_logger' do
|
6
|
+
context 'with :path' do
|
5
7
|
before do
|
6
|
-
stub_const
|
8
|
+
stub_const 'Dummy', Class.new
|
7
9
|
|
8
10
|
Dummy.class_eval { include DataMigrater::Logger }
|
9
|
-
Dummy.class_eval { data_logger path:
|
10
|
-
end
|
11
|
-
|
12
|
-
after :suite do
|
13
|
-
delete :dummy
|
11
|
+
Dummy.class_eval { data_logger path: 'custom.log' }
|
14
12
|
end
|
15
13
|
|
16
14
|
subject { Dummy.new }
|
17
15
|
|
18
|
-
it
|
19
|
-
subject.logger.info
|
16
|
+
it 'logs on the given path file with right content' do
|
17
|
+
subject.logger.info 'done!'
|
20
18
|
|
21
19
|
result = /\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} -\d{4}\] INFO Dummy: done!\n/
|
22
20
|
|
23
|
-
expect(File.readlines(
|
21
|
+
expect(File.readlines('custom.log').last).to match result
|
24
22
|
end
|
25
23
|
end
|
26
24
|
|
27
|
-
context
|
25
|
+
context 'with no :path' do
|
28
26
|
before do
|
29
|
-
stub_const
|
27
|
+
stub_const 'Dummy', Class.new
|
30
28
|
|
31
29
|
Dummy.class_eval { include DataMigrater::Logger }
|
32
30
|
Dummy.class_eval { data_logger }
|
@@ -34,30 +32,30 @@ RSpec.describe "#data_logger" do
|
|
34
32
|
|
35
33
|
subject { Dummy.new }
|
36
34
|
|
37
|
-
it
|
38
|
-
subject.logger.info
|
35
|
+
it 'logs on log folder with class name with right content' do
|
36
|
+
subject.logger.info 'done!'
|
39
37
|
|
40
38
|
result = /\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} -\d{4}\] INFO Dummy: done!\n/
|
41
39
|
|
42
|
-
expect(File.readlines(
|
40
|
+
expect(File.readlines('log/dummy.log').last).to match result
|
43
41
|
end
|
44
42
|
end
|
45
43
|
|
46
|
-
context
|
44
|
+
context 'with no :data_logger' do
|
47
45
|
before do
|
48
|
-
stub_const
|
46
|
+
stub_const 'Dummy', Class.new
|
49
47
|
|
50
48
|
Dummy.class_eval { include DataMigrater::Logger }
|
51
49
|
end
|
52
50
|
|
53
51
|
subject { Dummy.new }
|
54
52
|
|
55
|
-
it
|
56
|
-
subject.logger.info
|
53
|
+
it 'logs on log folder with class name with right content' do
|
54
|
+
subject.logger.info 'done!'
|
57
55
|
|
58
56
|
result = /\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} -\d{4}\] INFO Dummy: done!\n/
|
59
57
|
|
60
|
-
expect(File.readlines(
|
58
|
+
expect(File.readlines('log/dummy.log').last).to match result
|
61
59
|
end
|
62
60
|
end
|
63
61
|
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe '#logger_path' do
|
6
|
+
context 'with :path' do
|
7
|
+
before do
|
8
|
+
stub_const 'Dummy', Class.new
|
9
|
+
|
10
|
+
Dummy.class_eval { include DataMigrater::Logger }
|
11
|
+
Dummy.class_eval { data_logger path: '/tmp/custom.log' }
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'uses the given one' do
|
15
|
+
expect(Dummy.new.logger_path).to eq '/tmp/custom.log'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'with :dir' do
|
20
|
+
before do
|
21
|
+
stub_const 'Dummy', Class.new
|
22
|
+
|
23
|
+
Dummy.class_eval { include DataMigrater::Logger }
|
24
|
+
Dummy.class_eval { data_logger dir: :dir }
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'uses the given :dir on path' do
|
28
|
+
expect(Dummy.new.logger_path).to eq 'dir/dummy.log'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'with :file' do
|
33
|
+
before do
|
34
|
+
stub_const 'Dummy', Class.new
|
35
|
+
|
36
|
+
Dummy.class_eval { include DataMigrater::Logger }
|
37
|
+
Dummy.class_eval { data_logger file: 'file.odd' }
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'uses the given :file on path' do
|
41
|
+
expect(Dummy.new.logger_path).to eq 'log/file.odd'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'with :dir and :file' do
|
46
|
+
before do
|
47
|
+
stub_const 'Dummy', Class.new
|
48
|
+
|
49
|
+
Dummy.class_eval { include DataMigrater::Logger }
|
50
|
+
Dummy.class_eval { data_logger dir: :dir, file: 'file.odd' }
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'uses the given :dir and :file as path' do
|
54
|
+
expect(Dummy.new.logger_path).to eq 'dir/file.odd'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'with not :dir nor :file' do
|
59
|
+
before do
|
60
|
+
stub_const 'Dummy', Class.new
|
61
|
+
|
62
|
+
Dummy.class_eval { include DataMigrater::Logger }
|
63
|
+
Dummy.class_eval { data_logger }
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'uses the default :dir and :file as path' do
|
67
|
+
expect(Dummy.new.logger_path).to eq 'log/dummy.log'
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'with no callback options method' do
|
72
|
+
before do
|
73
|
+
stub_const 'Dummy', Class.new
|
74
|
+
|
75
|
+
Dummy.class_eval { include DataMigrater::Logger }
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'uses the default :dir and :file as path' do
|
79
|
+
expect(Dummy.new.logger_path).to eq 'log/dummy.log'
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
data/spec/migrater_spec.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe DataMigrater::Migrator do
|
@@ -22,14 +24,14 @@ describe DataMigrater::Migrator do
|
|
22
24
|
let(:data_migrations) { [data_migration] }
|
23
25
|
let(:insert) { "insert into data_migrations(version) values('21161023010203')" }
|
24
26
|
let(:select) { 'select version from data_migrations' }
|
25
|
-
let(:version) {
|
27
|
+
let(:version) { -> { connection.select_one(select)['version'] } }
|
26
28
|
|
27
|
-
before
|
28
|
-
connection.insert_sql insert
|
29
|
-
end
|
29
|
+
before { connection.insert insert }
|
30
30
|
|
31
31
|
context 'when has no pending migration' do
|
32
32
|
context 'when data migration table does not exists' do
|
33
|
+
subject { described_class.new collection }
|
34
|
+
|
33
35
|
let(:data_migration) { double }
|
34
36
|
let(:collection) { double migrations: [data_migration] }
|
35
37
|
|
@@ -37,10 +39,8 @@ describe DataMigrater::Migrator do
|
|
37
39
|
allow(DataMigration).to receive(:table_exists?) { false }
|
38
40
|
end
|
39
41
|
|
40
|
-
subject { described_class.new collection }
|
41
|
-
|
42
42
|
it 'does not executes data migration' do
|
43
|
-
expect(data_migration).
|
43
|
+
expect(data_migration).not_to receive :execute
|
44
44
|
|
45
45
|
subject.migrate
|
46
46
|
end
|
@@ -48,11 +48,11 @@ describe DataMigrater::Migrator do
|
|
48
48
|
|
49
49
|
context 'when data migration table exists' do
|
50
50
|
context 'but there is no data migration on collection' do
|
51
|
-
let(:collection) { double migrations: [] }
|
52
|
-
|
53
51
|
subject { described_class.new collection }
|
54
52
|
|
55
|
-
|
53
|
+
let(:collection) { double migrations: [] }
|
54
|
+
|
55
|
+
it { expect { subject.migrate }.not_to change { version.call } }
|
56
56
|
end
|
57
57
|
|
58
58
|
context 'and has data migration on collection' do
|
@@ -95,7 +95,7 @@ describe DataMigrater::Migrator do
|
|
95
95
|
after { FileUtils.rm next_migration }
|
96
96
|
|
97
97
|
it 'does not run the data migrations' do
|
98
|
-
expect(data_migration).
|
98
|
+
expect(data_migration).not_to receive :execute
|
99
99
|
|
100
100
|
described_class.new(collection).migrate
|
101
101
|
end
|
data/spec/migration_spec.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe DataMigrater::Migration do
|
@@ -18,11 +20,11 @@ describe DataMigrater::Migration do
|
|
18
20
|
FileUtils.rm_rf 'db'
|
19
21
|
end
|
20
22
|
|
21
|
-
describe
|
22
|
-
let(:migration) { double.as_null_object }
|
23
|
-
|
23
|
+
describe '#execute' do
|
24
24
|
subject { described_class.new version, name, filename, path }
|
25
25
|
|
26
|
+
let(:migration) { double.as_null_object }
|
27
|
+
|
26
28
|
before do
|
27
29
|
allow(AddColumnToUsersTable).to receive(:new) { migration }
|
28
30
|
end
|
@@ -35,7 +37,7 @@ describe DataMigrater::Migration do
|
|
35
37
|
specify { expect(subject.execute).to be_falsy }
|
36
38
|
|
37
39
|
it 'does not executes' do
|
38
|
-
expect(migration).
|
40
|
+
expect(migration).not_to receive :execute
|
39
41
|
|
40
42
|
subject.execute
|
41
43
|
end
|
@@ -51,7 +53,7 @@ describe DataMigrater::Migration do
|
|
51
53
|
it 'creates a new data_migrations' do
|
52
54
|
subject.execute
|
53
55
|
|
54
|
-
expect(DataMigration.exists?
|
56
|
+
expect(DataMigration.exists?(version: version)).to be_truthy
|
55
57
|
end
|
56
58
|
|
57
59
|
context 'and some error is raised' do
|
@@ -65,7 +67,7 @@ describe DataMigrater::Migration do
|
|
65
67
|
begin
|
66
68
|
subject.execute
|
67
69
|
rescue
|
68
|
-
expect(DataMigration.exists?
|
70
|
+
expect(DataMigration.exists?(version: version)).to be_falsy
|
69
71
|
end
|
70
72
|
end
|
71
73
|
end
|
data/spec/spec_helper.rb
CHANGED
data/spec/support/common.rb
CHANGED
data/spec/support/migrate.rb
CHANGED
metadata
CHANGED
@@ -1,43 +1,57 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: data_migrater
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GetNinjas
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-05-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 4.1.14
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 4.1.14
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: railties
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 4.1.14
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 4.1.14
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: smarter_csv
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.1'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.1'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: bundler
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -161,6 +175,7 @@ files:
|
|
161
175
|
- README.md
|
162
176
|
- lib/data_migrater.rb
|
163
177
|
- lib/data_migrater/collection.rb
|
178
|
+
- lib/data_migrater/csv.rb
|
164
179
|
- lib/data_migrater/logger.rb
|
165
180
|
- lib/data_migrater/migration.rb
|
166
181
|
- lib/data_migrater/migrator.rb
|
@@ -172,15 +187,20 @@ files:
|
|
172
187
|
- lib/generators/data_migrater/templates/db/data_migrate/data_migrate.rb.erb
|
173
188
|
- lib/generators/data_migrater/templates/db/migrate/create_data_migrations.rb
|
174
189
|
- spec/collection_spec.rb
|
175
|
-
- spec/csv/
|
190
|
+
- spec/csv/converters_spec.rb
|
191
|
+
- spec/csv/csv_path_spec.rb
|
192
|
+
- spec/csv/csv_spec.rb
|
193
|
+
- spec/csv/options_spec.rb
|
176
194
|
- spec/data_migration_spec.rb
|
177
195
|
- spec/logger/data_logger_spec.rb
|
196
|
+
- spec/logger/logger_path_spec.rb
|
178
197
|
- spec/migrater_spec.rb
|
179
198
|
- spec/migration_spec.rb
|
180
199
|
- spec/spec_helper.rb
|
181
200
|
- spec/support/common.rb
|
201
|
+
- spec/support/csv/dummy.csv
|
182
202
|
- spec/support/database_cleaner.rb
|
183
|
-
- spec/support/
|
203
|
+
- spec/support/local/dummy.csv
|
184
204
|
- spec/support/migrate.rb
|
185
205
|
homepage: https://github.com/getninjas/data_migrater
|
186
206
|
licenses:
|
@@ -202,19 +222,24 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
202
222
|
version: '0'
|
203
223
|
requirements: []
|
204
224
|
rubyforge_project:
|
205
|
-
rubygems_version: 2.6.
|
225
|
+
rubygems_version: 2.6.11
|
206
226
|
signing_key:
|
207
227
|
specification_version: 4
|
208
228
|
summary: A Data Migrator gem
|
209
229
|
test_files:
|
210
230
|
- spec/collection_spec.rb
|
211
|
-
- spec/csv/
|
231
|
+
- spec/csv/converters_spec.rb
|
232
|
+
- spec/csv/csv_path_spec.rb
|
233
|
+
- spec/csv/csv_spec.rb
|
234
|
+
- spec/csv/options_spec.rb
|
212
235
|
- spec/data_migration_spec.rb
|
213
236
|
- spec/logger/data_logger_spec.rb
|
237
|
+
- spec/logger/logger_path_spec.rb
|
214
238
|
- spec/migrater_spec.rb
|
215
239
|
- spec/migration_spec.rb
|
216
240
|
- spec/spec_helper.rb
|
217
241
|
- spec/support/common.rb
|
242
|
+
- spec/support/csv/dummy.csv
|
218
243
|
- spec/support/database_cleaner.rb
|
219
|
-
- spec/support/
|
244
|
+
- spec/support/local/dummy.csv
|
220
245
|
- spec/support/migrate.rb
|
data/spec/csv/data_csv_spec.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
class Dummy
|
4
|
-
include DataMigrater::CSV
|
5
|
-
|
6
|
-
data_logger path: "dummy.log"
|
7
|
-
|
8
|
-
def log
|
9
|
-
logger.info "done!"
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
RSpec.describe Dummy, "#data_logger" do
|
14
|
-
subject { Dummy.new }
|
15
|
-
|
16
|
-
context "with a given :path" do
|
17
|
-
it "caches the options" do
|
18
|
-
expect(described_class.options).to eq(path: "dummy.log")
|
19
|
-
end
|
20
|
-
|
21
|
-
it "has the right format" do
|
22
|
-
subject.log
|
23
|
-
|
24
|
-
expect(read).to match /\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} -\d{4}\] INFO Dummy: done!\n/
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def read
|
29
|
-
File.readlines(described_class.options[:path]).last
|
30
|
-
end
|
31
|
-
end
|
data/spec/support/methods.rb
DELETED