tidus 1.0.9 → 1.1.0

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
  SHA1:
3
- metadata.gz: 5b3221716efdbd435ff2ebef41c745eb240690c5
4
- data.tar.gz: 0fa789680f7cdd82e2e50ef591ab04f053b8c34d
3
+ metadata.gz: 2abe2b87088b2b0c6b190b31dd6deaa8db0fcbe5
4
+ data.tar.gz: 1816fedc56bf0c901745eb49db0ae6d9df71c87e
5
5
  SHA512:
6
- metadata.gz: 16242730fc087732b8d679e234b3da8c65846fde0aafa1be2ddb1ce238c5707876453bc6169e0ccc223932b1fd0a1a2c0168d9d811dccfe054a3705341175ad9
7
- data.tar.gz: 0e5a14be005c1494c20fa885bfc7fb51403c012ad2d49bdc13c64051a646ef7886ab23b23ba35fd81232e20e3c13c8cdb0bd1d88d26c98daf9ee9279861aedec
6
+ metadata.gz: 506f5b3c3f53586e3c9bdc909fc4cddb01b3b3c22ab85110a744e0478b38a504dc57ae5112fbb282b59d23b9decbc85518917b74fd4025a52336e11eb6fe907d
7
+ data.tar.gz: 3ed54eb937f1be9ee00d96764b5e6636386a75ad4c6e861077ef1d43ecc4f1158e37e9cc7a98acb27d2ddd560bd5100fbc21eec3a78d9555636a28857232e59e
@@ -0,0 +1,6 @@
1
+ # encoding: utf-8
2
+
3
+ module Tidus
4
+ class EanAnonymizer < Tidus::BaseSelector
5
+ end
6
+ end
@@ -0,0 +1,147 @@
1
+ module Tidus
2
+ module Postgresql
3
+ class EanAnonymizer
4
+ BASE_MAPPING = '0123456789'.freeze
5
+ DEFAULT_MAPPING_START = 1.freeze
6
+
7
+ def self.anonymize(table_name, column_name, options = {})
8
+ mapping_snippet = build_mapped_digit_snippet(column_name, options)
9
+
10
+ query = <<-SQL
11
+ (
12
+ SELECT
13
+ string_agg(new_digits.digit::TEXT, ''::TEXT)
14
+ FROM (
15
+ (
16
+ SELECT
17
+ pos,
18
+ digit
19
+ FROM (
20
+ #{mapping_snippet}
21
+ ) AS where_sub
22
+ ORDER BY pos ASC
23
+ )
24
+ UNION ALL
25
+ (
26
+ SELECT
27
+ LENGTH(#{column_name}::TEXT) AS pos,
28
+ (
29
+ 10
30
+ -
31
+ (
32
+ (
33
+ SELECT
34
+ SUM(digit)
35
+ FROM (
36
+ #{mapping_snippet}
37
+ ) AS where_sub
38
+ WHERE pos % 2 = LENGTH(#{column_name}::TEXT) % 2
39
+ )
40
+ +
41
+ (
42
+ SELECT
43
+ SUM(digit)
44
+ FROM (
45
+ #{mapping_snippet}
46
+ ) AS where_sub
47
+ WHERE pos % 2 = (LENGTH(#{column_name}::TEXT) - 1) % 2
48
+ ) * 3
49
+ ) % 10
50
+ ) % 10 AS digit
51
+ )
52
+ ) new_digits
53
+ )
54
+ SQL
55
+
56
+ return query.gsub!(/\n/, '').gsub!(/\ +/, ' ')
57
+ end
58
+
59
+ # Generates a new mapping if no cache_key is given
60
+ # Generates a new mapping if the cache_key is unknown
61
+ # Reuses the found mapping if the cache_key is known
62
+ def self.retrieve_mapping(cache_key)
63
+ @cached_mappings ||= {}
64
+ mapping = @cached_mappings[cache_key]
65
+
66
+ if mapping == nil
67
+ mapping = {
68
+ base: BASE_MAPPING,
69
+ replacement: BASE_MAPPING.split('').shuffle.join('')
70
+ }
71
+ end
72
+
73
+ if cache_key != nil
74
+ @cached_mappings[cache_key] = mapping
75
+ end
76
+
77
+ return mapping
78
+ end
79
+
80
+ def self.build_mapped_digit_snippet(column_name, options)
81
+ substrings = build_digit_mapping(column_name, options)
82
+
83
+ return <<-SQL
84
+ SELECT
85
+ *
86
+ FROM (
87
+ SELECT
88
+ ROW_NUMBER() over () AS pos,
89
+ digit::INT
90
+ FROM (
91
+ SELECT
92
+ REGEXP_SPLIT_TO_TABLE(
93
+ #{substrings.join(' || ')},
94
+ ''
95
+ ) AS digit
96
+ ) AS sub
97
+ ) AS sub
98
+ WHERE pos < LENGTH(#{column_name}::TEXT)
99
+ SQL
100
+ end
101
+
102
+ def self.build_digit_mapping(column_name, options)
103
+ mapping = retrieve_mapping(options[:cache_key])
104
+
105
+ options[:start] ||= DEFAULT_MAPPING_START
106
+
107
+ # reduce length by 1 to take away the check digit
108
+ total_length = "LENGTH(#{column_name}::TEXT) - 1"
109
+ length = options[:length] || total_length
110
+
111
+ substrings = []
112
+
113
+ if options[:start] != DEFAULT_MAPPING_START
114
+ substrings << build_substring_snippet(
115
+ column_name,
116
+ DEFAULT_MAPPING_START,
117
+ options[:start] - DEFAULT_MAPPING_START
118
+ )
119
+ end
120
+
121
+ translate_part = <<-SNIPPET
122
+ TRANSLATE(
123
+ #{build_substring_snippet(column_name, options[:start], length)},
124
+ '#{mapping[:base]}',
125
+ '#{mapping[:replacement]}'
126
+ )
127
+ SNIPPET
128
+
129
+ substrings << translate_part.gsub(/\n/, '').gsub(/\ +/, ' ')
130
+
131
+ if options[:length] != nil
132
+ substrings << build_substring_snippet(
133
+ column_name,
134
+ "#{options[:start]} + #{options[:length]}",
135
+ "#{total_length} - #{options[:start]}"
136
+ )
137
+ end
138
+
139
+ return substrings
140
+ end
141
+
142
+ def self.build_substring_snippet(column_name, start, length)
143
+ return "SUBSTRING(#{column_name}::TEXT, #{start}, #{length})"
144
+ end
145
+ end
146
+ end
147
+ end
@@ -1,3 +1,3 @@
1
1
  module Tidus
2
- VERSION = "1.0.9"
2
+ VERSION = "1.1.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tidus
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.9
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Schoknecht
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-08 00:00:00.000000000 Z
11
+ date: 2019-01-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -79,10 +79,12 @@ files:
79
79
  - lib/tidus/query.rb
80
80
  - lib/tidus/strategies/base_selector.rb
81
81
  - lib/tidus/strategies/cond_anonymizer.rb
82
+ - lib/tidus/strategies/ean_anonymizer.rb
82
83
  - lib/tidus/strategies/email_anonymizer.rb
83
84
  - lib/tidus/strategies/null_anonymizer.rb
84
85
  - lib/tidus/strategies/overlay_anonymizer.rb
85
86
  - lib/tidus/strategies/postgresql/cond_anonymizer.rb
87
+ - lib/tidus/strategies/postgresql/ean_anonymizer.rb
86
88
  - lib/tidus/strategies/postgresql/email_anonymizer.rb
87
89
  - lib/tidus/strategies/postgresql/null_anonymizer.rb
88
90
  - lib/tidus/strategies/postgresql/overlay_anonymizer.rb