dumped_railers 0.1.5 → 0.2.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/.gitignore +2 -0
- data/.travis.yml +9 -4
- data/CHANGELOG.md +9 -0
- data/README.md +36 -5
- data/dumped_railers.gemspec +2 -2
- data/gemfiles/{Gemfile.rails_5.2.4 → Gemfile.rails_5.2} +1 -1
- data/gemfiles/{Gemfile.rails_6.1.0 → Gemfile.rails_6.0} +0 -0
- data/gemfiles/{Gemfile.rails_6.0.3.4 → Gemfile.rails_6.1} +0 -0
- data/lib/dumped_railers.rb +23 -18
- data/lib/dumped_railers/configuration.rb +35 -0
- data/lib/dumped_railers/dump.rb +1 -1
- data/lib/dumped_railers/import.rb +3 -2
- data/lib/dumped_railers/preprocessor/strip_ignorables.rb +5 -1
- data/lib/dumped_railers/record_builder/fixture_set.rb +31 -9
- data/lib/dumped_railers/version.rb +1 -1
- metadata +11 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5faab9a280ca3d2e4e4379074ab56846ba2a1c1b65969a272efdf4fd344d8c20
|
4
|
+
data.tar.gz: fa3a52e63c010d51f023fc2815d058dfb8e4b05652f6e6d57893784faa679c53
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c71bbd0aa57f772b63a423ce89249f83a97cb0094a9ee4f53fa1088e1ab0a0e87d617f28c574a48af9728d48d97e841d8fbd811a78d9501ed926b1ef59e28457
|
7
|
+
data.tar.gz: 022e908a2869b8a01395adf9eba867bd6d3726a28dbfe885b5bd876bad05fda2c9c736c8d6180b685fafabdc075ff6ad2561f63b92a97e633f2c0e900de0f8c0
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,12 +1,17 @@
|
|
1
1
|
---
|
2
2
|
language: ruby
|
3
3
|
cache: bundler
|
4
|
+
before_install: gem install bundler
|
4
5
|
rvm:
|
6
|
+
- 3.0.0
|
5
7
|
- 2.7.2
|
6
8
|
- 2.6.6
|
7
9
|
- 2.5.8
|
8
10
|
gemfile:
|
9
|
-
- gemfiles/Gemfile.rails_6.1
|
10
|
-
- gemfiles/Gemfile.rails_6.0
|
11
|
-
- gemfiles/Gemfile.rails_5.2
|
12
|
-
|
11
|
+
- gemfiles/Gemfile.rails_6.1
|
12
|
+
- gemfiles/Gemfile.rails_6.0
|
13
|
+
- gemfiles/Gemfile.rails_5.2
|
14
|
+
jobs:
|
15
|
+
exclude:
|
16
|
+
- rvm: 3.0.0
|
17
|
+
gemfile: gemfiles/Gemfile.rails_5.2
|
data/CHANGELOG.md
CHANGED
@@ -30,3 +30,12 @@
|
|
30
30
|
## [0.1.5]
|
31
31
|
### Added
|
32
32
|
- Supported in-memopry fixtures. Now users can dump into and import from in-memory fixture object without saving files.
|
33
|
+
|
34
|
+
## [0.2.0]
|
35
|
+
### Added
|
36
|
+
- Provide options to limit models to import, so that users can prohibit modification to arbitrary models.
|
37
|
+
- Support for Ruby 3.0.0 (requires Rails >= 6.0)
|
38
|
+
|
39
|
+
### Changed
|
40
|
+
- Accept both global configuration as well as runtime (one-off) settings for all the available options.
|
41
|
+
Now all the configured settings will be overridden at runtime when the settings are provided with arguments.
|
data/README.md
CHANGED
@@ -78,24 +78,24 @@ DumpedRailers.import!(fixtures)
|
|
78
78
|
|
79
79
|
DumpedRailers does not save the fixtures when `base_dir` keyword argument is not specified.
|
80
80
|
|
81
|
-
###
|
81
|
+
### Ignoring Certain Columns
|
82
82
|
|
83
83
|
* By default, DumpedRailers ignore three columns - `id`, `created_at`, `updated_at`. You can always update/change this settings as follows.
|
84
84
|
|
85
85
|
```ruby
|
86
86
|
DumpedRailers.configure do |config|
|
87
|
-
config.ignorable_columns += [:published_on] # published_on will be ignored on top of default settings.
|
87
|
+
config.ignorable_columns += [:published_on] # :published_on will be ignored *on top of* default settings.
|
88
88
|
end
|
89
89
|
```
|
90
90
|
|
91
91
|
* of course you can totally replace the settings with your own.
|
92
92
|
```ruby
|
93
93
|
DumpedRailers.configure do |config|
|
94
|
-
config.ignorable_columns = %i[uuid created_on updated_on] # uuid and created_on will be ignored instead of id, created_at, updated_at
|
94
|
+
config.ignorable_columns = %i[uuid created_on updated_on] # :uuid and :created_on will be ignored *instead of* :id, :created_at, :updated_at
|
95
95
|
end
|
96
96
|
```
|
97
97
|
|
98
|
-
### Masking,
|
98
|
+
### Masking, Filtering
|
99
99
|
|
100
100
|
* you can pass `preprocessors` to DumpedRailers before it starts dump. All the attributes are filtered through preprocessors in order of registration.
|
101
101
|
|
@@ -124,7 +124,38 @@ masking_preprocessor = -> (attrs, model) { attrs.transform_values(&:upcase) }
|
|
124
124
|
|
125
125
|
NOTE: The proprocessors must return attributes in the same format `{ attributes_name: value }` so that preprocessors and dump handlers can preprocessors in nested manner.
|
126
126
|
|
127
|
-
###
|
127
|
+
### Limiting Import with Authorized Models Only
|
128
|
+
|
129
|
+
* In case you don't want to accept arbitrary fixtures to import, you can limit model access as follows:
|
130
|
+
|
131
|
+
```ruby
|
132
|
+
DumpedRailers.import!(fixtures, authorized_models: [Item, Price])
|
133
|
+
```
|
134
|
+
|
135
|
+
This would allow us to import fixtures for items and prices, but reject modification on User, Purchase, Admin data.
|
136
|
+
|
137
|
+
NOTE: Only DumpedRailers.import! is affected by this option. DumpedRailers.dump! can't be scoped (at least in the current version).
|
138
|
+
|
139
|
+
### Configuration
|
140
|
+
|
141
|
+
* All the settings can be configured by either configuration (global) or arguments (at runtime).
|
142
|
+
* When you have duplicated setting, arguments are respected: you can always override configured settings by arguments.
|
143
|
+
|
144
|
+
```ruby
|
145
|
+
DumpedRailers.configure do |config|
|
146
|
+
config.ignorable_columns = [:archived_at]
|
147
|
+
config.preprocessors = [FooPreprocessor, BarPreprocessor]
|
148
|
+
end
|
149
|
+
|
150
|
+
DumpedRailers.dump!(Item, ignorable_columns: [:id], preprocessors: [BazPreprocessor], base_dir: 'tmp/')
|
151
|
+
# this would ignore `id` column, and apply BazPreprocessor only
|
152
|
+
|
153
|
+
DumpedRailers.dump!(Price, base_dir: 'tmp/')
|
154
|
+
# this would ignore `archived_at`, applies FooPreprocessor and BazPreprocessor
|
155
|
+
# (settings provided with arguments are considered as one-off, and don't survive globally)
|
156
|
+
```
|
157
|
+
|
158
|
+
### Dump/Import under default_scope (e.g. ActsAsTenant)
|
128
159
|
|
129
160
|
* Such library builds multi-tenancy environment on one single database, using default_scope to switch over database access rights between tenants. You can incorporate data from Tenant A to Tenant B as follows. let's say we use [ActsAsTenant](https://github.com/ErwinM/acts_as_tenant)
|
130
161
|
|
data/dumped_railers.gemspec
CHANGED
@@ -27,9 +27,9 @@ Gem::Specification.new do |spec|
|
|
27
27
|
|
28
28
|
spec.add_development_dependency 'bundler', '~> 2.0'
|
29
29
|
spec.add_development_dependency 'rake', '~> 12.3.3'
|
30
|
-
spec.add_development_dependency 'rspec', '~> 3.
|
30
|
+
spec.add_development_dependency 'rspec', '~> 3.10'
|
31
31
|
spec.add_development_dependency 'sqlite3'
|
32
|
-
spec.add_development_dependency 'activerecord', '
|
32
|
+
spec.add_development_dependency 'activerecord', '>= 5.2'
|
33
33
|
spec.add_development_dependency 'database_cleaner-active_record', '~> 1.8'
|
34
34
|
spec.add_development_dependency 'pry'
|
35
35
|
spec.add_development_dependency 'pry-byebug'
|
File without changes
|
File without changes
|
data/lib/dumped_railers.rb
CHANGED
@@ -4,45 +4,50 @@ require 'dumped_railers/version'
|
|
4
4
|
require 'dumped_railers/file_helper.rb'
|
5
5
|
require 'dumped_railers/dump'
|
6
6
|
require 'dumped_railers/import'
|
7
|
+
require 'dumped_railers/configuration'
|
7
8
|
|
8
9
|
module DumpedRailers
|
9
|
-
|
10
|
-
|
11
|
-
def dump!(*models, base_dir: nil, preprocessors: nil)
|
12
|
-
preprocessors = [Preprocessor::StripIgnorables.new, *preprocessors].compact.uniq
|
10
|
+
extend Configuration
|
13
11
|
|
14
|
-
|
12
|
+
class << self
|
13
|
+
def dump!(*models, base_dir: nil, preprocessors: nil, ignorable_columns: nil)
|
14
|
+
# override global config settings when options are specified
|
15
|
+
runtime_options = { preprocessors: preprocessors.presence, ignorable_columns: ignorable_columns.presence }.compact.reverse_merge(dump_options.deep_dup)
|
16
|
+
runtime_options[:preprocessors].unshift(
|
17
|
+
default_preprocessor(runtime_options[:ignorable_columns])
|
18
|
+
)
|
19
|
+
|
20
|
+
fixture_handler = Dump.new(*models, preprocessors: runtime_options[:preprocessors])
|
15
21
|
fixtures = fixture_handler.build_fixtures!
|
16
22
|
fixture_handler.persist_all!(base_dir)
|
17
23
|
|
18
24
|
fixtures
|
19
25
|
end
|
20
26
|
|
21
|
-
def import!(*paths)
|
27
|
+
def import!(*paths, authorized_models: nil)
|
22
28
|
# make sure class-baseed caches starts with clean state
|
23
29
|
DumpedRailers::RecordBuilder::FixtureRow::RecordStore.clear!
|
24
30
|
DumpedRailers::RecordBuilder::DependencyTracker.clear!
|
25
31
|
|
26
|
-
|
32
|
+
# override global config settings when options are specified
|
33
|
+
runtime_options = { authorized_models: authorized_models.presence }.compact.reverse_merge(import_options)
|
34
|
+
|
35
|
+
fixture_handler = Import.new(*paths, authorized_models: runtime_options[:authorized_models])
|
27
36
|
fixture_handler.import_all!
|
28
37
|
end
|
29
38
|
|
30
|
-
|
39
|
+
private
|
31
40
|
|
32
|
-
def
|
33
|
-
|
41
|
+
def default_preprocessor(ignorable_columns)
|
42
|
+
Preprocessor::StripIgnorables.new(*ignorable_columns)
|
34
43
|
end
|
35
44
|
|
36
|
-
def
|
37
|
-
|
45
|
+
def dump_options
|
46
|
+
options.slice(:ignorable_columns, :preprocessors)
|
38
47
|
end
|
39
48
|
|
40
|
-
|
41
|
-
|
42
|
-
def configure_defaults!
|
43
|
-
configure do |config|
|
44
|
-
config.ignorable_columns = IGNORABLE_COLUMNS
|
45
|
-
end
|
49
|
+
def import_options
|
50
|
+
options.slice(:authorized_models)
|
46
51
|
end
|
47
52
|
end
|
48
53
|
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DumpedRailers
|
4
|
+
module Configuration
|
5
|
+
extend Forwardable
|
6
|
+
def_delegators :@_config, :preprocessors, :ignorable_columns, :authorized_models
|
7
|
+
|
8
|
+
def configure
|
9
|
+
yield config
|
10
|
+
end
|
11
|
+
|
12
|
+
def options
|
13
|
+
config.to_h
|
14
|
+
end
|
15
|
+
|
16
|
+
IGNORABLE_COLUMNS = %w[id created_at updated_at]
|
17
|
+
def configure_defaults!
|
18
|
+
clear_configuration!(
|
19
|
+
ignorable_columns: IGNORABLE_COLUMNS,
|
20
|
+
preprocessors: [],
|
21
|
+
authorized_models: :any,
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
def config
|
26
|
+
@_config ||= OpenStruct.new
|
27
|
+
end
|
28
|
+
private :config
|
29
|
+
|
30
|
+
def clear_configuration!(**attrs)
|
31
|
+
@_config = OpenStruct.new(attrs)
|
32
|
+
end
|
33
|
+
private :clear_configuration!
|
34
|
+
end
|
35
|
+
end
|
data/lib/dumped_railers/dump.rb
CHANGED
@@ -7,7 +7,7 @@ module DumpedRailers
|
|
7
7
|
class Dump
|
8
8
|
def initialize(*models, preprocessors: [])
|
9
9
|
@fixture_tables = models.map { |model|
|
10
|
-
FixtureBuilder::Model.new(model,
|
10
|
+
FixtureBuilder::Model.new(model, preprocessors: preprocessors)
|
11
11
|
}
|
12
12
|
end
|
13
13
|
|
@@ -6,17 +6,18 @@ module DumpedRailers
|
|
6
6
|
class Import
|
7
7
|
attr_reader :fixture_set
|
8
8
|
|
9
|
-
def initialize(*paths)
|
9
|
+
def initialize(*paths, authorized_models: [])
|
10
10
|
if (paths.first.is_a? Hash)
|
11
11
|
@raw_fixtures = paths.first.values
|
12
12
|
else
|
13
13
|
@raw_fixtures = FileHelper.read_fixtures(*paths)
|
14
14
|
end
|
15
15
|
|
16
|
-
@fixture_set = RecordBuilder::FixtureSet.new(@raw_fixtures)
|
16
|
+
@fixture_set = RecordBuilder::FixtureSet.new(@raw_fixtures, authorized_models: authorized_models)
|
17
17
|
end
|
18
18
|
|
19
19
|
def import_all!
|
20
|
+
fixture_set.authorize_models!
|
20
21
|
fixture_set.sort_by_table_dependencies!
|
21
22
|
@record_sets = fixture_set.build_record_sets!
|
22
23
|
|
@@ -3,9 +3,13 @@
|
|
3
3
|
module DumpedRailers
|
4
4
|
module Preprocessor
|
5
5
|
class StripIgnorables
|
6
|
+
def initialize(*ignorable_columns)
|
7
|
+
@ignorable_columns = ignorable_columns.compact.map(&:to_s)
|
8
|
+
end
|
9
|
+
|
6
10
|
def call(attributes, _model)
|
7
11
|
attributes.reject { |column_name, _v|
|
8
|
-
|
12
|
+
@ignorable_columns.include?(column_name)
|
9
13
|
}
|
10
14
|
end
|
11
15
|
end
|
@@ -8,35 +8,57 @@ module DumpedRailers
|
|
8
8
|
class FixtureSet
|
9
9
|
include TSort
|
10
10
|
attr_reader :fixture_tables, :record_sets
|
11
|
-
|
12
|
-
def initialize(raw_fixtures)
|
11
|
+
|
12
|
+
def initialize(raw_fixtures, authorized_models: [])
|
13
13
|
@fixture_tables = raw_fixtures.map { |raw_records| build_fixture_table(raw_records) }
|
14
|
+
@authorized_models = Array(authorized_models)
|
14
15
|
end
|
15
|
-
|
16
|
+
|
16
17
|
def sort_by_table_dependencies!
|
17
18
|
@fixture_tables.each(&:analyze_metadata_dependencies!)
|
18
19
|
# dependency are sorted in topological order using Active Record reflection
|
19
20
|
@fixture_tables = tsort
|
20
|
-
|
21
|
+
|
21
22
|
self
|
22
23
|
end
|
23
|
-
|
24
|
+
|
25
|
+
def authorize_models!
|
26
|
+
return if @authorized_models.include?(:any)
|
27
|
+
|
28
|
+
unauthorized_models = fixture_models.reject { |model|
|
29
|
+
@authorized_models.include? model
|
30
|
+
}
|
31
|
+
return if unauthorized_models.empty?
|
32
|
+
|
33
|
+
raise RuntimeError, <<~"ERROR_MESSAGE"
|
34
|
+
You are trying to import data into unauthorized models.
|
35
|
+
Make sure that the fixture contains records for authorized models only.
|
36
|
+
|
37
|
+
Models that are forbidden to access: #{unauthorized_models.map(&:name).join(', ')}
|
38
|
+
|
39
|
+
ERROR_MESSAGE
|
40
|
+
end
|
41
|
+
|
24
42
|
def build_record_sets!
|
25
43
|
@record_sets = @fixture_tables.map { |table|
|
26
44
|
[table.model, table.build_records!]
|
27
45
|
}.to_h
|
28
46
|
end
|
29
|
-
|
47
|
+
|
30
48
|
private
|
31
|
-
|
49
|
+
|
32
50
|
def build_fixture_table(raw_records)
|
33
51
|
FixtureTable.new(raw_records)
|
34
52
|
end
|
35
|
-
|
53
|
+
|
54
|
+
def fixture_models
|
55
|
+
@fixture_tables.map(&:model)
|
56
|
+
end
|
57
|
+
|
36
58
|
def tsort_each_node(&block)
|
37
59
|
@fixture_tables.each { |table| block.call(table) }
|
38
60
|
end
|
39
|
-
|
61
|
+
|
40
62
|
def tsort_each_child(node, &block)
|
41
63
|
dependent_nodes = @fixture_tables.select { |table| node.dependencies.include? table.model_name }
|
42
64
|
dependent_nodes.each &block
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dumped_railers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Koji Onishi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-12-
|
11
|
+
date: 2020-12-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '3.
|
47
|
+
version: '3.10'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '3.
|
54
|
+
version: '3.10'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: sqlite3
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -70,14 +70,14 @@ dependencies:
|
|
70
70
|
name: activerecord
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - "
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '5.2'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - "
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '5.2'
|
83
83
|
- !ruby/object:Gem::Dependency
|
@@ -156,10 +156,11 @@ files:
|
|
156
156
|
- bin/console
|
157
157
|
- bin/setup
|
158
158
|
- dumped_railers.gemspec
|
159
|
-
- gemfiles/Gemfile.rails_5.2
|
160
|
-
- gemfiles/Gemfile.rails_6.0
|
161
|
-
- gemfiles/Gemfile.rails_6.1
|
159
|
+
- gemfiles/Gemfile.rails_5.2
|
160
|
+
- gemfiles/Gemfile.rails_6.0
|
161
|
+
- gemfiles/Gemfile.rails_6.1
|
162
162
|
- lib/dumped_railers.rb
|
163
|
+
- lib/dumped_railers/configuration.rb
|
163
164
|
- lib/dumped_railers/dump.rb
|
164
165
|
- lib/dumped_railers/file_helper.rb
|
165
166
|
- lib/dumped_railers/fixture_builder/model.rb
|
@@ -193,7 +194,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
193
194
|
- !ruby/object:Gem::Version
|
194
195
|
version: '0'
|
195
196
|
requirements: []
|
196
|
-
rubygems_version: 3.
|
197
|
+
rubygems_version: 3.1.4
|
197
198
|
signing_key:
|
198
199
|
specification_version: 4
|
199
200
|
summary: A flexible fixture importer/exporter, that can transport ActiveRecord data
|