class Masking::InsertStatement
Constants
- BINARY_REGEXP
- COLUMNS_REGEXP
- NULL_REGEXP
- NUMBER_REGEXP
NOTE: in mysqldump,
integer/float/NULL type has dumped without single quote. e.g. -123 / 2.4 / NULL string/time type has dumped with single quote. e.g. 'string' / '2018-08-22 13:27:34' binary/blob type has dumped with _binary prefix. e.g. _binary 'binarydata' if there is single quote inside of value, it will dumped with escape. e.g. 'chikahiro\'s item' in number, there could be include Scientific notation e.g. 1.2E3 / -1.2E-3 / 1e+030 / 9.71726e-17 refs: https://dev.mysql.com/doc/refman/5.7/en/precision-math-numbers.html
- PARSE_REGEXP
- STRING_TIME_REGEXP
- VALUE_REGEXP
- VALUE_ROW_SPLITTER
Attributes
columns_section[R]
raw_statement[R]
sql_builder[R]
table[R]
values_section[R]
Public Class Methods
new(raw_statement, sql_builder: SQLBuilder)
click to toggle source
# File lib/masking/insert_statement.rb, line 10 def initialize(raw_statement, sql_builder: SQLBuilder) @raw_statement = raw_statement @sql_builder = sql_builder PARSE_REGEXP.match(raw_statement).tap do |match_data| raise Error::InsertStatementParseError if match_data.nil? @table = match_data[:table] @columns_section = match_data[:columns_section] @values_section = match_data[:values_section] end end
Public Instance Methods
column_index(column_name)
click to toggle source
# File lib/masking/insert_statement.rb, line 27 def column_index(column_name) columns.index(column_name) end
columns()
click to toggle source
# File lib/masking/insert_statement.rb, line 23 def columns @columns ||= columns_section.scan(COLUMNS_REGEXP).flatten.map(&:to_sym) end
mask_value(column_index:, mask_method:)
click to toggle source
# File lib/masking/insert_statement.rb, line 37 def mask_value(column_index:, mask_method:) values.each do |value| value[column_index] = mask_method.call end end
sql()
click to toggle source
# File lib/masking/insert_statement.rb, line 43 def sql sql_builder.new(table: table, columns: columns, values: values).sql end
values()
click to toggle source
# File lib/masking/insert_statement.rb, line 31 def values @values ||= values_section.split(VALUE_ROW_SPLITTER) .tap { |rows| rows.each_with_index { |_, i| recursive_pattern_value_concat(rows, i) } } .flat_map { |row| row.scan(values_regexp) } end
Private Instance Methods
recursive_pattern_value_concat(value_rows, index)
click to toggle source
Check single quote count on each value, and just continue if it's even number. if it's odd, concat with next row (it means a value contains “),(” pattern)
e.g. INSERT ... VALUES (123,'string ),( abc'),(456,'ab');
refs: implementation of parsing CSV on ruby standard library FasterCSV (ja): www.clear-code.com/blog/2018/12/25.html
# File lib/masking/insert_statement.rb, line 77 def recursive_pattern_value_concat(value_rows, index) return if value_rows[index].gsub(/\\\\/, '').gsub(/\\'/, '').count(?').even? value_rows[index] += VALUE_ROW_SPLITTER + value_rows.delete_at(index + 1) recursive_pattern_value_concat(value_rows, index) end
values_regexp()
click to toggle source
# File lib/masking/insert_statement.rb, line 69 def values_regexp @values_regexp ||= /^\(?#{([VALUE_REGEXP] * columns.count).join(?,)}\)?$/ end