masking 0.0.2 → 0.0.3

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 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