Skip to content

Commit

Permalink
Use named tuples for parsing tables and rows
Browse files Browse the repository at this point in the history
  • Loading branch information
josacar committed May 23, 2024
1 parent 09333e4 commit 109e628
Show file tree
Hide file tree
Showing 8 changed files with 28 additions and 24 deletions.
4 changes: 2 additions & 2 deletions spec/triki/mysql_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,14 @@ describe Triki::Mysql do

it "should return a hash of table name, column names for MySQL insert statements" do
hash = subject.parse_insert_statement("INSERT INTO `some_table` (`email`, `name`, `something`, `age`) VALUES ('bob@honk.com','bob', 'some\\'thin,ge())lse1', 25),('joe@joe.com','joe', 'somethingelse2', 54);")
hash.should eq({"ignore" => false, "table_name" => "some_table", "column_names" => ["email", "name", "something", "age"]})
hash.should eq({ignore: false, table_name: "some_table", column_names: ["email", "name", "something", "age"]})
end
end

describe "#parse_insert_ignore_statement" do
it "should return a hash of IGNORE, table name, column names for MySQL insert statements" do
hash = subject.parse_insert_statement("INSERT IGNORE INTO `some_table` (`email`, `name`, `something`, `age`) VALUES ('bob@honk.com','bob', 'some\\'thin,ge())lse1', 25),('joe@joe.com','joe', 'somethingelse2', 54);")
hash.should eq({"ignore" => true, "table_name" => "some_table", "column_names" => ["email", "name", "something", "age"]})
hash.should eq({ignore: true, table_name: "some_table", column_names: ["email", "name", "something", "age"]})
end
end
end
4 changes: 2 additions & 2 deletions spec/triki/postgres_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ describe Triki::Postgres do
it "parses table name and column names" do
line = "COPY some_table (id, email, name, something) FROM stdin;"
hash = subject.parse_copy_statement(line) || raise "Error"
hash["table_name"].should eq("some_table")
hash["column_names"].should eq(["id", "email", "name", "something"])
hash[:table_name].should eq("some_table")
hash[:column_names].should eq(["id", "email", "name", "something"])
end
end

Expand Down
2 changes: 1 addition & 1 deletion spec/triki/sql_server_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ describe Triki::SqlServer do
describe "#parse_insert_statement" do
it "should return a hash of table_name, column_names for SQL Server input statements" do
hash = subject.parse_insert_statement("INSERT [dbo].[TASKS] ([TaskID], [TaskName]) VALUES (61, N\"Report Thing\")")
hash.should eq({"table_name" => "TASKS", "column_names" => ["TaskID", "TaskName"]})
hash.should eq({table_name: "TASKS", column_names: ["TaskID", "TaskName"]})
end

it "should return nil for SQL Server non-insert statements" do
Expand Down
4 changes: 2 additions & 2 deletions src/triki/config_scaffold_generator.cr
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ class Triki
table_data = table_data(statement)
next unless table_data

table_name = table_data["table_name"].as(TableName)
table_name = table_data[:table_name]
next if obfuscator.scaffolded_tables[table_name]? # only process each table_name once

columns = table_data["column_names"].as(ColumnList)
columns = table_data[:column_names]
table_config = config[table_name]?
next if table_config == :truncate || table_config == :keep

Expand Down
4 changes: 2 additions & 2 deletions src/triki/insert_statement_parser.cr
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ class Triki
def parse(obfuscator, config, input_io, output_io)
while statement = input_io.gets(");\n")
if table_data = parse_insert_statement(statement)
table_name = table_data["table_name"].as(String)
columns = table_data["column_names"].as(Array(String))
table_name = table_data[:table_name]
columns = table_data[:column_names]
ignore = table_data["ignore"]?

if config[table_name]?
Expand Down
12 changes: 7 additions & 5 deletions src/triki/mysql.cr
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,19 @@ class Triki
alias Field = String?
alias Fields = Array(Field)
alias Rows = Array(Fields)
alias Table = NamedTuple(ignore: Bool, table_name: String, column_names: ColumnList)

include Triki::InsertStatementParser
include Triki::ConfigScaffoldGenerator

def parse_insert_statement(line)
return unless regex_match = insert_regex.match(line)
{
"ignore" => !regex_match[1]?.nil?,
"table_name" => regex_match[2],
"column_names" => regex_match[3].split(/`\s*,\s*`/).map(&.gsub('`', "")),
}

Table.new(
ignore: !regex_match[1]?.nil?,
table_name: regex_match[2],
column_names: regex_match[3].split(/`\s*,\s*`/).map(&.gsub('`', ""))
)
end

def make_insert_statement(table_name, column_names, rows, ignore = nil)
Expand Down
13 changes: 7 additions & 6 deletions src/triki/postgres.cr
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
class Triki
struct Postgres < Base
alias Table = NamedTuple(table_name: String, column_names: ColumnList)
include Triki::ConfigScaffoldGenerator

# Postgres uses COPY statements instead of INSERT and look like:
Expand All @@ -23,8 +24,8 @@ class Triki
if table_data = parse_copy_statement(line)
inside_copy_statement = true

current_table_name = table_data["table_name"].as(String)
current_columns = table_data["column_names"].as(ColumnList)
current_table_name = table_data[:table_name]
current_columns = table_data[:column_names]

if !config[current_table_name]
Log.warn { "Deprecated: #{current_table_name} was not specified in the config. A future release will cause this to be an error. Please specify the table definition or set it to :keep." }
Expand Down Expand Up @@ -71,10 +72,10 @@ class Triki
def parse_copy_statement(line)
return unless regex_match = /^\s*COPY (.*?) \((.*?)\) FROM\s*/i.match(line)

{
"table_name" => regex_match[1],
"column_names" => regex_match[2].split(/\s*,\s*/),
}
Table.new(
table_name: regex_match[1],
column_names: regex_match[2].split(/\s*,\s*/),
)
end

def make_insert_statement(table_name, column_names, values, ignore = nil)
Expand Down
9 changes: 5 additions & 4 deletions src/triki/sql_server.cr
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
class Triki
struct SqlServer < Base
alias Table = NamedTuple(table_name: String, column_names: ColumnList)
include Triki::InsertStatementParser
include Triki::ConfigScaffoldGenerator

def parse_insert_statement(line)
return unless regex_match = insert_regex.match(line)

{
"table_name" => regex_match[1],
"column_names" => regex_match[2].split(/\]\s*,\s*\[/).map(&.gsub(/[\[\]]/, "")),
}
Table.new(
table_name: regex_match[1],
column_names: regex_match[2].split(/\]\s*,\s*\[/).map(&.gsub(/[\[\]]/, ""))
)
end

def rows_to_be_inserted(line)
Expand Down

0 comments on commit 109e628

Please sign in to comment.