remont 0.1.0 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +9 -0
- data/LICENSE +21 -0
- data/README.md +26 -10
- data/lib/remont/config.rb +1 -7
- data/lib/remont/record_processor.rb +8 -7
- data/lib/remont/schema.rb +27 -7
- data/lib/remont/tasks/remont.rake +10 -2
- data/lib/remont/version.rb +1 -1
- data/remont.gemspec +1 -0
- metadata +9 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fef6ca4c4fb15d4b408b15362f695d57f35c251bd1a39e9acffe3781e1ba0dfe
|
4
|
+
data.tar.gz: 9232bafef16dd069c9e3beab41225ffc01e2a5efc828ef3127044f1d8dea7039
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6fda028ec5e55bdb4fef7b1cb60e955444bae187f611ebf7fe0b8e7ff2d9d8e365f58903b653cc16e15039c6d15202e7cf133250fc43e3027a16e7b499171f03
|
7
|
+
data.tar.gz: 41c1b71c8b424a99dbf022dd51ca11b13df6a982163ef3f8ad9988090808bd1f115dee0779ace5d1e99084566079b0b6037573a283d03400920907da5e967c8f
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2022 Infinum
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
CHANGED
@@ -21,14 +21,12 @@ Add `config/initializers/remont.rb`
|
|
21
21
|
```ruby
|
22
22
|
Remont.setup do |config|
|
23
23
|
config.process_timestamp_attribute = :processed_at
|
24
|
-
config.script_path = 'db/remont.rb'
|
25
24
|
end
|
26
25
|
```
|
27
26
|
|
28
|
-
| Option | Default value | Description
|
29
|
-
| --- | :---: | ---
|
30
|
-
| `process_timestamp_attribute` |
|
31
|
-
| `script_path` | `'db/remont.rb'` | entry point for the schema processing task |
|
27
|
+
| Option | Default value | Description |
|
28
|
+
| --- | :---: | --- |
|
29
|
+
| `process_timestamp_attribute` | `nil` | processing status attribute identifier |
|
32
30
|
|
33
31
|
On successful record processing, `process_timestamp_attribute` on the record will be set to the current processing time (`Time.now.getlocal`).
|
34
32
|
|
@@ -38,11 +36,10 @@ In the following example, the intention is to simulate anonymization of the `use
|
|
38
36
|
```ruby
|
39
37
|
# config/initializers/remont.rb
|
40
38
|
Remont.setup do |config|
|
41
|
-
config.process_timestamp_attribute = :
|
42
|
-
config.script_path = 'db/anonymize.rb'
|
39
|
+
config.process_timestamp_attribute = :anonymized_at
|
43
40
|
end
|
44
41
|
```
|
45
|
-
- define processing script
|
42
|
+
- define the processing script
|
46
43
|
```ruby
|
47
44
|
# db/anonymize.rb
|
48
45
|
schema model: User do
|
@@ -53,8 +50,12 @@ schema model: Order do
|
|
53
50
|
attribute(:billing_address) { '23 Wall Street, NY' }
|
54
51
|
end
|
55
52
|
```
|
56
|
-
- and run `
|
53
|
+
- and run `remont` rake task with the path to the processing script
|
54
|
+
```bash
|
55
|
+
bundle exec rake "remont[db/anonymize.rb]"
|
56
|
+
```
|
57
57
|
|
58
|
+
Passing the script path to the rake task is mandatory.
|
58
59
|
Running the rake task would result in updating `email` (and `anonymized_at`) column for each row in the `users` table, and `billing_address` column for each row in the `orders` table.
|
59
60
|
|
60
61
|
### Schema
|
@@ -77,14 +78,29 @@ schema model: Order do
|
|
77
78
|
scope { |scope| scope.where(status: :active) }
|
78
79
|
end
|
79
80
|
```
|
81
|
+
### Recording the processing end time
|
82
|
+
Library supports an option to store the processing end time of a record. Enable the behavior by configuring a processing status attribute identifier for the schema. Configure the attribute identifier
|
83
|
+
- globally (`Remont::Config#process_timestamp_attribute`, for all schemas)
|
84
|
+
- or individually per schema (in the schema DSL, overrides the global setting)
|
85
|
+
```ruby
|
86
|
+
schema model: User, process_timestamp_attribute: :anonymized_at do
|
87
|
+
end
|
88
|
+
|
89
|
+
schema model: Order do
|
90
|
+
with_process_timestamp_attribute :anonymized_at
|
91
|
+
end
|
92
|
+
```
|
93
|
+
|
94
|
+
Set process status attribute to `nil` to disable the behavior.
|
80
95
|
### Skipping the processed records
|
81
|
-
In some cases, it's desirable to skip already processed records. You can
|
96
|
+
In some cases, it's desirable to skip already processed records. You can enable this behavior by declaring `without_processed` within the `schema` block. When declared, the processing dataset query will be extended with a condition that excludes already processed records.
|
82
97
|
```ruby
|
83
98
|
schema model: User do
|
84
99
|
without_processed
|
85
100
|
# ...
|
86
101
|
end
|
87
102
|
```
|
103
|
+
Configure processing status attribute before declaring the `without_processed`. An error will be raised otherwise.
|
88
104
|
### Callbacks
|
89
105
|
Custom pre-processing or post-processing behavior can be declared using `before` and `after` callbacks.
|
90
106
|
```ruby
|
data/lib/remont/config.rb
CHANGED
@@ -1,16 +1,10 @@
|
|
1
1
|
module Remont
|
2
2
|
class Config
|
3
|
-
DEFAULT_SCRIPT_PATH = 'db/remont.rb'.freeze
|
4
|
-
|
5
3
|
# @return [Symbol]
|
6
4
|
attr_accessor :process_timestamp_attribute
|
7
5
|
|
8
|
-
# @return [String]
|
9
|
-
attr_accessor :script_path
|
10
|
-
|
11
6
|
def initialize
|
12
|
-
@process_timestamp_attribute =
|
13
|
-
@script_path = DEFAULT_SCRIPT_PATH
|
7
|
+
@process_timestamp_attribute = nil
|
14
8
|
end
|
15
9
|
end
|
16
10
|
end
|
@@ -2,11 +2,11 @@ module Remont
|
|
2
2
|
class RecordProcessor
|
3
3
|
NOOP = proc {}
|
4
4
|
|
5
|
-
# @param [
|
5
|
+
# @param [Remont::Schema] schema
|
6
6
|
# @param [Proc] before
|
7
7
|
# @param [Proc] after
|
8
|
-
def initialize(
|
9
|
-
@
|
8
|
+
def initialize(schema, before, after)
|
9
|
+
@schema = schema
|
10
10
|
@before = before || NOOP
|
11
11
|
@after = after || NOOP
|
12
12
|
end
|
@@ -25,12 +25,13 @@ module Remont
|
|
25
25
|
|
26
26
|
private
|
27
27
|
|
28
|
-
attr_reader :
|
28
|
+
attr_reader :schema
|
29
29
|
attr_reader :before
|
30
30
|
attr_reader :after
|
31
31
|
|
32
32
|
def processed_attributes(record)
|
33
|
-
|
33
|
+
schema
|
34
|
+
.attributes
|
34
35
|
.select { |attribute| record.send(attribute.name).present? }
|
35
36
|
.reduce(default_processed_attributes) do |memo, attribute|
|
36
37
|
memo.merge(attribute.name => attribute.process(record.send(attribute.name), record))
|
@@ -38,10 +39,10 @@ module Remont
|
|
38
39
|
end
|
39
40
|
|
40
41
|
def default_processed_attributes
|
41
|
-
return {} unless
|
42
|
+
return {} unless schema.process_timestamp_attribute
|
42
43
|
|
43
44
|
{
|
44
|
-
|
45
|
+
schema.process_timestamp_attribute => Time.now.getlocal
|
45
46
|
}
|
46
47
|
end
|
47
48
|
end
|
data/lib/remont/schema.rb
CHANGED
@@ -1,16 +1,23 @@
|
|
1
1
|
module Remont
|
2
2
|
class Schema
|
3
|
-
|
4
|
-
|
3
|
+
MISSING_PROCESSING_STATUS_ATTR = "Processing status attribute isn't configured".freeze
|
4
|
+
|
5
|
+
# @return [Array<Remont::Attribute>]
|
6
|
+
attr_reader :attributes
|
7
|
+
|
8
|
+
# @return [Nil, String, Symbol]
|
9
|
+
attr_reader :process_timestamp_attribute
|
5
10
|
|
6
11
|
# @param [Hash] opts
|
7
12
|
# @option [Class] :model
|
8
13
|
# @option [Proc] :scope
|
14
|
+
# @option [String, Symbol] :process_timestamp_attribute
|
9
15
|
# @param [Proc] block
|
10
16
|
def initialize(opts = {}, &block)
|
11
17
|
@model = opts.fetch(:model)
|
12
|
-
@model_scope = opts.fetch(:scope,
|
13
|
-
@without_processed_scope =
|
18
|
+
@model_scope = opts.fetch(:scope, default_scope)
|
19
|
+
@without_processed_scope = default_scope
|
20
|
+
@process_timestamp_attribute = opts.fetch(:process_timestamp_attribute, Remont.config.process_timestamp_attribute)
|
14
21
|
@before_cb = nil
|
15
22
|
@after_cb = nil
|
16
23
|
@attributes = []
|
@@ -20,7 +27,17 @@ module Remont
|
|
20
27
|
|
21
28
|
# @return [Remont::Schema]
|
22
29
|
def without_processed
|
23
|
-
|
30
|
+
raise MISSING_PROCESSING_STATUS_ATTR if @process_timestamp_attribute.nil?
|
31
|
+
|
32
|
+
@without_processed_scope = proc { |scope| scope.where(process_timestamp_attribute => nil) }
|
33
|
+
|
34
|
+
self
|
35
|
+
end
|
36
|
+
|
37
|
+
# @param [String, Symbol] attr_name
|
38
|
+
# @return [Remont::Schema]
|
39
|
+
def with_process_timestamp_attribute(attr_name)
|
40
|
+
@process_timestamp_attribute = attr_name
|
24
41
|
|
25
42
|
self
|
26
43
|
end
|
@@ -70,12 +87,11 @@ module Remont
|
|
70
87
|
attr_reader :model
|
71
88
|
attr_reader :without_processed_scope
|
72
89
|
attr_reader :model_scope
|
73
|
-
attr_reader :attributes
|
74
90
|
attr_reader :before_cb
|
75
91
|
attr_reader :after_cb
|
76
92
|
|
77
93
|
def processor
|
78
|
-
@processor ||= RecordProcessor.new(
|
94
|
+
@processor ||= RecordProcessor.new(self, before_cb, after_cb)
|
79
95
|
end
|
80
96
|
|
81
97
|
def records_for_processing
|
@@ -83,5 +99,9 @@ module Remont
|
|
83
99
|
without_processed_scope.call(model.all)
|
84
100
|
)
|
85
101
|
end
|
102
|
+
|
103
|
+
def default_scope
|
104
|
+
proc { |scope| scope }
|
105
|
+
end
|
86
106
|
end
|
87
107
|
end
|
@@ -1,5 +1,13 @@
|
|
1
1
|
desc 'Run schema processing'
|
2
|
-
task remont: :
|
3
|
-
|
2
|
+
task :remont, [:script_path] => :remont_env do |_, args|
|
3
|
+
script_path = args[:script_path]
|
4
|
+
abort 'Missing script path' unless script_path
|
5
|
+
|
6
|
+
path = Rails.root.join(script_path)
|
4
7
|
Remont::Script.new(path).run!
|
5
8
|
end
|
9
|
+
|
10
|
+
task :remont_env do # rubocop:disable Rails/RakeEnvironment
|
11
|
+
Rake::Task['environment'].invoke
|
12
|
+
rescue StandardError # rubocop:disable Lint/SuppressedException
|
13
|
+
end
|
data/lib/remont/version.rb
CHANGED
data/remont.gemspec
CHANGED
@@ -8,6 +8,7 @@ Gem::Specification.new do |spec|
|
|
8
8
|
|
9
9
|
spec.summary = 'DSL for row level data processing.'
|
10
10
|
spec.homepage = 'https://github.com/infinum/remont'
|
11
|
+
spec.license = 'MIT'
|
11
12
|
spec.required_ruby_version = Gem::Requirement.new('>= 2.7.0')
|
12
13
|
|
13
14
|
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: remont
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rails Team
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-10-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -108,7 +108,7 @@ dependencies:
|
|
108
108
|
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
|
-
description:
|
111
|
+
description:
|
112
112
|
email:
|
113
113
|
- team.rails@infinum.com
|
114
114
|
executables: []
|
@@ -125,6 +125,7 @@ files:
|
|
125
125
|
- CHANGELOG.md
|
126
126
|
- CODE_OF_CONDUCT.md
|
127
127
|
- Gemfile
|
128
|
+
- LICENSE
|
128
129
|
- README.md
|
129
130
|
- Rakefile
|
130
131
|
- bin/console
|
@@ -140,14 +141,15 @@ files:
|
|
140
141
|
- lib/remont/version.rb
|
141
142
|
- remont.gemspec
|
142
143
|
homepage: https://github.com/infinum/remont
|
143
|
-
licenses:
|
144
|
+
licenses:
|
145
|
+
- MIT
|
144
146
|
metadata:
|
145
147
|
allowed_push_host: https://rubygems.org
|
146
148
|
homepage_uri: https://github.com/infinum/remont
|
147
149
|
source_code_uri: https://github.com/infinum/remont
|
148
150
|
changelog_uri: https://github.com/infinum/remont/blob/master/CHANGELOG.md
|
149
151
|
rubygems_mfa_required: 'true'
|
150
|
-
post_install_message:
|
152
|
+
post_install_message:
|
151
153
|
rdoc_options: []
|
152
154
|
require_paths:
|
153
155
|
- lib
|
@@ -163,7 +165,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
163
165
|
version: '0'
|
164
166
|
requirements: []
|
165
167
|
rubygems_version: 3.1.4
|
166
|
-
signing_key:
|
168
|
+
signing_key:
|
167
169
|
specification_version: 4
|
168
170
|
summary: DSL for row level data processing.
|
169
171
|
test_files: []
|