masking 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ad1fbd60375e405bad8295cdbb8c947139a7ecdb9f0eb3f01d88b97fad571584
4
- data.tar.gz: 00e5a59479399c80a8d7d08f3f1b75ae301bff53a9ebb85bb9086de768a0d139
3
+ metadata.gz: 8a65d39a6c96c94bf473883d1ef9877f1abdd16cfcae97da27e99f8c7afa9963
4
+ data.tar.gz: 109965dbb6e2ee880f9fd955e4f0d05f6a3dfbc8cbecd153315f9bcad275bf86
5
5
  SHA512:
6
- metadata.gz: afe2010c052a9c8e1bb6e6948c933020d5868a35d796f0b0e109360b2e522a566bc6062e89e9e74a2216fdeadbdfb37e8a7d2e81b1d4cfda9de34453e719d4c8
7
- data.tar.gz: 98743faed783497adbba56e39fdb1bff0e757b734f1b1aa11814da40fc42479c88594f556da451026b17187f042f09669f29ed92bd2623cc997236c0106c522e
6
+ metadata.gz: 03010bd6d5fb1c90ed1c6dca9dff8f7d84bfe934d65bf48fab28feb3aa6c67381c0c1c6d85ba055b21334919ad1b075a166e23ab3d01fc76f09575f08c1ccac0
7
+ data.tar.gz: ff9ddd10f8f30c72427815177bb37d68e46fedd7d104d1141d5655449c7ae3811e4d2d0135113b2145b4b809d5774752b9c0100337927d6a59949a9c4fe35580
@@ -5,10 +5,12 @@ plugins:
5
5
  markdownlint:
6
6
  enabled: true
7
7
  checks:
8
- # below 3 checks are disabled because Codeclimate's Markdownlint is not latest version
8
+ # below 3 checks are disabled because Codeclimate's Markdownlint is not latest version (0.5.0)
9
9
  MD023:
10
10
  enabled: false
11
11
  MD034:
12
12
  enabled: false
13
13
  MD036:
14
14
  enabled: false
15
+ exclude_patterns:
16
+ - ".chglog/*.tpl.md"
@@ -0,0 +1,41 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [v0.0.3] - 2019-07-07
11
+
12
+ ### Changed
13
+
14
+ - Update Document [#25](https://github.com/kibitan/masking/pull/25)
15
+ - Performance Tuning [#28](https://github.com/kibitan/masking/pull/28) special thanks [@isaiah](https://github.com/isaiah)
16
+
17
+ ```
18
+ $ bin/benchmark.rb
19
+ (v0.0.2)
20
+ user system total real
21
+ 2.197755 0.239222 2.436977 ( 2.460922)
22
+
23
+ (v0.0.3)
24
+ user system total real
25
+ 1.136621 0.198741 1.335362 ( 1.355499)
26
+ ```
27
+
28
+ ## [v0.0.2] - 2019-01-06
29
+
30
+ ### Fix
31
+
32
+ - fix bug about NoMethodError on some environment
33
+
34
+ ## [v0.0.1] - 2019-01-05
35
+
36
+ Initial release version. 🎉
37
+
38
+ [Unreleased]: https://github.com/kibitan/masking/compare/v0.0.3...HEAD
39
+ [v0.0.3]: https://github.com/kibitan/masking/compare/v0.0.2...v0.0.3
40
+ [v0.0.2]: https://github.com/kibitan/masking/compare/v0.0.1...v0.0.2
41
+ [v0.0.1]: https://github.com/kibitan/masking/tree/v0.0.1
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- masking (0.0.2)
4
+ masking (0.0.3)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -3,18 +3,12 @@
3
3
  [![Build Status](https://travis-ci.org/kibitan/masking.svg?branch=master)](https://travis-ci.org/kibitan/masking)
4
4
  [![Coverage Status](https://coveralls.io/repos/github/kibitan/masking/badge.svg?branch=master)](https://coveralls.io/github/kibitan/masking?branch=master)
5
5
  [![Maintainability](https://api.codeclimate.com/v1/badges/290b3005ecc193a3d138/maintainability)](https://codeclimate.com/github/kibitan/masking/maintainability)
6
+ [![Gem Version](https://badge.fury.io/rb/masking.svg)](https://badge.fury.io/rb/masking)
6
7
 
7
8
  The command line tool for anonymizing database records by parsing a SQL dump file and build new SQL dump file with masking sensitive/credential data.
8
9
 
9
10
  ## Installation
10
11
 
11
- ```bash
12
- git clone git@github.com:kibitan/masking.git
13
- bin/setup
14
- ```
15
-
16
- or install it yourself as:
17
-
18
12
  ```bash
19
13
  gem install masking
20
14
  ```
@@ -29,51 +23,57 @@ gem install masking
29
23
 
30
24
  ## Usage
31
25
 
32
- 1. setup configuration of target columns to `masking.yml`
33
-
34
- ```yaml
35
- # table_name:
36
- # column_name: masked_value
37
-
38
- users:
39
- string: anonymized string
40
- email: anonymized+%{n}@example.com # %{n} will be replaced with sequential number
41
- integer: 12345
42
- float: 123.45
43
- boolean: true
44
- null: null
45
- date: 2018-08-24
46
- time: 2018-08-24 15:54:06
47
- binary_or_blob: !binary | # Binary Data Language-Independent Type for YAML™ Version 1.1: http://yaml.org/type/binary.html
48
- R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5
49
- OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+
50
- +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC
51
- AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=
52
- ```
53
-
54
- A value will be implicitly converted to compatible type. If you prefer to explicitly convert, you could use a tag as defined in [YAML Version 1.1](http://yaml.org/spec/current.html#id2503753)
55
-
56
- ```yaml
57
- not-date: !!str 2002-04-28
58
- ```
26
+ 1. Setup configuration for anonymizing target tables/columns to `masking.yml`
27
+
28
+ ```yaml
29
+ # table_name:
30
+ # column_name: masked_value
31
+
32
+ users:
33
+ string: anonymized string
34
+ email: anonymized+%{n}@example.com # %{n} will be replaced with sequential number
35
+ integer: 12345
36
+ float: 123.45
37
+ boolean: true
38
+ null: null
39
+ date: 2018-08-24
40
+ time: 2018-08-24 15:54:06
41
+ binary_or_blob: !binary | # Binary Data Language-Independent Type for YAML™ Version 1.1: http://yaml.org/type/binary.html
42
+ R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5
43
+ OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+
44
+ +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC
45
+ AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=
46
+ ```
47
+
48
+ A value will be implicitly converted to compatible type. If you prefer to explicitly convert, you could use a tag as defined in [YAML Version 1.1](http://yaml.org/spec/current.html#id2503753)
49
+
50
+ ```yaml
51
+ not-date: !!str 2002-04-28
52
+ ```
53
+
54
+ String should be matched with [MySQL String Type]( https://dev.mysql.com/doc/refman/8.0/en/string-type-overview.html). Integer/Float should be matched with [MySQL Numeric Type](https://dev.mysql.com/doc/refman/8.0/en/numeric-type-overview.html). Date/Time should be matched with [MySQL Date and Time Type](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-type-overview.html).
59
55
 
60
- String should be matched with [MySQL String Type]( https://dev.mysql.com/doc/refman/8.0/en/string-type-overview.html). Integer/Float should be matched with [MySQL Numeric Type](https://dev.mysql.com/doc/refman/8.0/en/numeric-type-overview.html). Date/Time should be matched with [MySQL Date and Time Type](https://dev.mysql.com/doc/refman/8.0/en/date-and-time-type-overview.html).
56
+ *NOTE: MasKING doesn't check actual schema's type from dump. If you put uncomaptible value it will cause error during restoring to database.*
61
57
 
62
- *NOTE: MasKING doesn't check actual schema's type from dump. If you put uncomaptible value it will cause error during restoring to database.*
58
+ 1. Dump database with anonymizing
63
59
 
64
- 1. dump with mask
60
+ MasKING works with `mysqldump --complete-insert`
65
61
 
66
- MasKING works with `mysqldump --complete-insert`
62
+ ```bash
63
+ mysqldump --complete-insert -u USERNAME DATABASE_NAME | masking > anonymized_dump.sql
64
+ ```
67
65
 
68
- ```bash
69
- mysqldump --complete-insert -u USERNAME DATABASE_NAME | masking > masked_dump.sql
70
- ```
66
+ 1. Restore from anonymized dump file
71
67
 
72
- 1. restore
68
+ ```bash
69
+ mysql -u USERNAME ANONYMIZED_DATABASE_NAME < anonymized_dump.sql
70
+ ```
73
71
 
74
- ```bash
75
- mysql -u USERNAME MASKED_DATABASE_NAME < masked_dump.sql
76
- ```
72
+ Tip: If you don't need to have anonymized dump file, you can directly insert from stream. It can be faster because it has less IO interaction.
73
+
74
+ ```bash
75
+ mysqldump --complete-insert -u USERNAME DATABASE_NAME | masking | mysql -u USERNAME ANONYMIZED_DATABASE_NAME
76
+ ```
77
77
 
78
78
  ### options
79
79
 
@@ -83,13 +83,48 @@ Usage: masking [options]
83
83
  -c, --config=FILE_PATH specify config file. default: masking.yml
84
84
  ```
85
85
 
86
- ## Run test & rubocop & notes
86
+ ## Use case of annonymized (production) database
87
+
88
+ * Simulate for database migration and find a problem before release
89
+
90
+ Some schema changing statement will lock table and it will cause trouble during the migration. But, without having a large number of record such as production, a migration will finish at the moment and easy to overlook.
91
+
92
+ * Performance optimization of database queries
93
+
94
+ Some database query can be slow, but some query isn't reproducible until you have similar amount of records/cardinality.
95
+
96
+ * Finding bug before release on production
97
+
98
+ Some bugs are related to unexpected data in production (for instance so long text, invalid/not-well formatted data) and it might be noticed after releasing in production.
99
+
100
+ * Better development/demo of a feature
101
+
102
+ Using similar data with real one will be good to make a good view of how feature looks like. It makes easy to find out the things to be changed/fixed before release/check the feature in production.
103
+
104
+ * Analyze metrics on our production data with respecting GDPR
105
+
106
+ We can use this database for BI and some trouble shooting.
107
+
108
+ * And… your idea here!
109
+
110
+ ## Development
111
+
112
+ ```bash
113
+ git clone git@github.com:kibitan/masking.git
114
+ bin/setup
115
+ ```
116
+
117
+ You can also run `bin/console` for an interactive prompt that will allow you to experiment.
118
+
119
+ To install this gem onto your local machine, run `bundle exec rake install`.
120
+
121
+ ### Run test & rubocop & notes
87
122
 
88
123
  ```bash
89
124
  bundle exec rake
90
125
  ```
91
126
 
92
- ### Protip
127
+ #### Protip
93
128
 
94
129
  It's useful that set `rake` on [Git hooks](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks).
95
130
 
@@ -100,18 +135,12 @@ bundle exec rake
100
135
  EOF
101
136
  ```
102
137
 
103
- ### [Markdown lint](https://github.com/markdownlint/markdownlint)
138
+ #### [Markdown lint](https://github.com/markdownlint/markdownlint)
104
139
 
105
140
  ```bash
106
141
  bundle exec mdl *.md
107
142
  ```
108
143
 
109
- ## Development
110
-
111
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
112
-
113
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
114
-
115
144
  ### Profiling
116
145
 
117
146
  use `bin/masking_profile`
@@ -127,6 +156,16 @@ graph html is saved at /your/repo/profile/graph.html
127
156
 
128
157
  see also: [ruby-prof/ruby-prof: ruby-prof: a code profiler for MRI rubies](https://github.com/ruby-prof/ruby-prof)
129
158
 
159
+ ### Benchmark
160
+
161
+ use `bin/benchmark.rb`
162
+
163
+ ```bash
164
+ $ bin/benchmark.rb
165
+ user system total real
166
+ 1.152776 0.207064 1.359840 ( 1.375090)
167
+ ```
168
+
130
169
  ## Design Concept
131
170
 
132
171
  ### KISS ~ keep it simple, stupid ~
@@ -137,10 +176,6 @@ No connection to database, No handling file, Only dealing with stdin/stdout. ~ D
137
176
 
138
177
  Depend on only pure language standard libraries, no external libraries. (except development/test environment)
139
178
 
140
- ### High Code Quality
141
-
142
- 100% of code coverage [![Coverage Status](https://coveralls.io/repos/github/kibitan/masking/badge.svg?branch=master)](https://coveralls.io/github/kibitan/masking?branch=master) and low complexity [![Maintainability](https://api.codeclimate.com/v1/badges/290b3005ecc193a3d138/maintainability)](https://codeclimate.com/github/kibitan/masking/maintainability)
143
-
144
179
  ## Future Todo
145
180
 
146
181
  * Pluguable/customizable for a mask way e.g. integrate with [Faker](https://github.com/stympy/faker)
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ $LOAD_PATH.unshift('./lib')
5
+ require 'benchmark'
6
+ require 'masking'
7
+
8
+ n = 10_000
9
+
10
+ Masking.configure do |config|
11
+ config.target_columns_file_path = 'spec/fixtures/config/masking.yml'
12
+ end
13
+
14
+ fixture = File.open('spec/fixtures/insert_statement/sample.sql')
15
+
16
+ Benchmark.bm do |x|
17
+ x.report do
18
+ n.times do
19
+ Masking::Main.new(input: fixture, output: File.open(File::NULL, 'w')).run
20
+ fixture.rewind
21
+ end
22
+ end
23
+ end
@@ -37,11 +37,11 @@ RubyProf::GraphHtmlPrinter.new(result).tap do |graph_html_printer|
37
37
  end
38
38
 
39
39
  # # this is quite slow so commented out. but it's useful
40
- # call_stack_html_file = Pathname(__dir__).join('../profile/call_stack.html')
41
- # RubyProf::CallStackPrinter.new(result).tap do |call_stack_html_printer|
42
- # call_stack_html_printer.print(File.new(call_stack_html_file, 'w'))
43
- # puts "call stack html is saved at #{call_stack_html_file}"
44
- # end
40
+ call_stack_html_file = Pathname(__dir__).join('../profile/call_stack.html')
41
+ RubyProf::CallStackPrinter.new(result).tap do |call_stack_html_printer|
42
+ call_stack_html_printer.print(File.new(call_stack_html_file, 'w'))
43
+ puts "call stack html is saved at #{call_stack_html_file}"
44
+ end
45
45
 
46
46
  # # I'm not sure how to read this
47
47
  # call_graph_dot_file = Pathname(__dir__).join('../profile/call_graph.dot')
@@ -24,7 +24,7 @@ module Masking
24
24
 
25
25
  # TODO: refactoring
26
26
  def columns(table_name:)
27
- tables.find { |table| table.name == table_name.to_sym }&.columns
27
+ tables[table_name.to_sym]&.columns
28
28
  end
29
29
 
30
30
  def ==(other)
@@ -41,10 +41,8 @@ module Masking
41
41
 
42
42
  # TODO: extract to other class
43
43
  def tables
44
- @tables ||= [].tap do |arr|
45
- data.each do |table_name, columns|
46
- arr << Table.new(table_name, columns: columns)
47
- end
44
+ @tables ||= data.each_with_object({}) do |kv, r|
45
+ r[kv[0].to_sym] = Table.new(kv[0], columns: kv[1])
48
46
  end
49
47
  end
50
48
  end
@@ -7,6 +7,7 @@ module Masking
7
7
  class TargetColumns
8
8
  class Column
9
9
  attr_reader :name, :table_name, :method_value
10
+ attr_accessor :index
10
11
 
11
12
  def initialize(name, table_name:, method_value:)
12
13
  @name = name.to_sym
@@ -8,7 +8,7 @@ module Masking
8
8
  class Method
9
9
  class Date
10
10
  def initialize(value)
11
- @date = value
11
+ @date = value.strftime(FORMAT)
12
12
  end
13
13
 
14
14
  def call
@@ -21,7 +21,7 @@ module Masking
21
21
  FORMAT = '%Y-%m-%d'
22
22
 
23
23
  def date_format
24
- date.strftime(FORMAT)
24
+ date
25
25
  end
26
26
  end
27
27
  end
@@ -6,11 +6,11 @@ module Masking
6
6
  class Method
7
7
  class Float
8
8
  def initialize(value)
9
- @float = value
9
+ @float = value.to_s
10
10
  end
11
11
 
12
12
  def call
13
- float.to_s
13
+ float
14
14
  end
15
15
 
16
16
  private
@@ -6,11 +6,11 @@ module Masking
6
6
  class Method
7
7
  class Integer
8
8
  def initialize(value)
9
- @integer = value
9
+ @integer = value.to_s
10
10
  end
11
11
 
12
12
  def call
13
- integer.to_s
13
+ integer
14
14
  end
15
15
 
16
16
  private
@@ -11,13 +11,13 @@ module Masking
11
11
  end
12
12
 
13
13
  def call
14
- "'#{output}'".b
14
+ ("'" + output + "'").b
15
15
  end
16
16
 
17
17
  private
18
18
 
19
+ SEQUENTIAL_NUMBER_PLACEHOLDER = '%{n}' # rubocop:disable Style/FormatStringToken
19
20
  attr_reader :string
20
- SEQUENTIAL_NUMBER_PLACEHOLDER = /%{n}/.freeze
21
21
 
22
22
  def output
23
23
  string.sub(SEQUENTIAL_NUMBER_PLACEHOLDER, sequence.to_s)
@@ -6,7 +6,7 @@ module Masking
6
6
  class Method
7
7
  class Time
8
8
  def initialize(value)
9
- @time = value
9
+ @time = value.strftime(FORMAT)
10
10
  end
11
11
 
12
12
  def call
@@ -19,7 +19,7 @@ module Masking
19
19
  FORMAT = '%Y-%m-%d %H:%M:%S'
20
20
 
21
21
  def time_format
22
- time.strftime(FORMAT)
22
+ time
23
23
  end
24
24
  end
25
25
  end
@@ -23,19 +23,26 @@ module Masking
23
23
  end
24
24
 
25
25
  # TODO: define insert_statement.mask_values(column, mask_method) method & refactoring
26
- # rubocop:disable Metrics/AbcSize
26
+ # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
27
27
  def process
28
28
  return raw_line unless target_table?
29
29
 
30
- target_columns.columns(table_name: insert_statement.table).each do |target_column|
31
- insert_statement.values.map do |value|
32
- value[target_column.name] = target_column.masked_value if value.column?(target_column.name)
30
+ columns = target_columns.columns(table_name: insert_statement.table)
31
+ if columns.first.index.nil?
32
+ columns.each do |target_column|
33
+ target_column.index = insert_statement.columns.index(target_column.name)
34
+ end
35
+ end
36
+
37
+ insert_statement.values.each do |values|
38
+ columns.each do |target_column|
39
+ values[target_column.index] = target_column.masked_value unless target_column.index.nil?
33
40
  end
34
41
  end
35
42
 
36
43
  insert_statement.sql
37
44
  end
38
- # rubocop:enable Metrics/AbcSize
45
+ # rubocop:enable Metrics/AbcSize,Metrics/MethodLength
39
46
 
40
47
  def target_table?
41
48
  target_columns.contains?(table_name: insert_statement.table)
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'masking/insert_statement/value'
4
3
  require 'masking/insert_statement/sql_builder'
5
4
 
6
5
  module Masking
@@ -26,8 +25,7 @@ module Masking
26
25
  # NOTE: define and extract to ValueSet class?
27
26
  @values ||= values_section.split(VALUE_ROW_SPLITTER)
28
27
  .tap { |rows| rows.each_with_index { |_, i| recursive_pattern_value_concat(rows, i) } }
29
- .map { |row| row.scan(values_regexp).flatten }
30
- .map { |data| Value.new(columns: columns, data: data) }
28
+ .flat_map { |row| row.scan(values_regexp) }
31
29
  end
32
30
 
33
31
  def sql
@@ -65,7 +63,7 @@ module Masking
65
63
  # e.g. INSERT ... VALUES (123,'string ),( abc'),(456,'ab');
66
64
  # refs: implementation of parsing CSV on ruby standard library FasterCSV (ja): https://www.clear-code.com/blog/2018/12/25.html
67
65
  def recursive_pattern_value_concat(value_rows, index)
68
- return if value_rows[index].gsub(/\\\\/, '').gsub(/\\'/, '').scan(/'/).count.even?
66
+ return if value_rows[index].gsub(/\\\\/, '').gsub(/\\'/, '').count(?').even?
69
67
 
70
68
  value_rows[index] += VALUE_ROW_SPLITTER + value_rows.delete_at(index + 1)
71
69
  recursive_pattern_value_concat(value_rows, index)
@@ -27,7 +27,7 @@ module Masking
27
27
  end
28
28
 
29
29
  def values_section
30
- values.map(&:phrase).join(?,)
30
+ values.map { |value| '(' + value.join(',') + ')' }.join(',')
31
31
  end
32
32
  end
33
33
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Masking
4
- VERSION = '0.0.2'
4
+ VERSION = '0.0.3'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: masking
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chikahiro Tokoro
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-01-05 00:00:00.000000000 Z
11
+ date: 2019-07-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -193,12 +193,14 @@ files:
193
193
  - ".rubocop.yml"
194
194
  - ".ruby-version"
195
195
  - ".travis.yml"
196
+ - CHANGELOG.md
196
197
  - CODE_OF_CONDUCT.md
197
198
  - Gemfile
198
199
  - Gemfile.lock
199
200
  - LICENSE.txt
200
201
  - README.md
201
202
  - Rakefile
203
+ - bin/benchmark.rb
202
204
  - bin/console
203
205
  - bin/masking_profile
204
206
  - bin/setup
@@ -226,7 +228,6 @@ files:
226
228
  - lib/masking/errors.rb
227
229
  - lib/masking/insert_statement.rb
228
230
  - lib/masking/insert_statement/sql_builder.rb
229
- - lib/masking/insert_statement/value.rb
230
231
  - lib/masking/sql_dump_line.rb
231
232
  - lib/masking/version.rb
232
233
  - masking.gemspec
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'delegate'
4
-
5
- module Masking
6
- class InsertStatement
7
- class Value < ::SimpleDelegator
8
- def initialize(columns:, data:)
9
- @columns = columns
10
- @data = Struct.new(*columns).new(*data)
11
- # NOTE: is it better to get rid of SimpleDelegator, store data in instance variable and define accesor for it?
12
- super(@data)
13
- end
14
-
15
- def phrase
16
- '(' + to_a.join(?,) + ')'
17
- end
18
-
19
- # override for make comparable
20
- # NOTE: original #== method comapares struct subclass
21
- def ==(other)
22
- to_h == other.to_h
23
- end
24
-
25
- def column?(column_name)
26
- @columns.include?(column_name.to_sym)
27
- end
28
- end
29
- end
30
- end