Files

278 lines
15 KiB
Ruby
Raw Permalink Normal View History

2018-02-23 00:40:26 +01:00
#! /bin/ruby
require ('fiddle')
#antlr = Fiddle.dlopen('mylib.so')
2018-02-23 22:11:09 +01:00
#input_string = "(sql_script (unit_statement (data_manipulation_language_statements (insert_statement INSERT (single_table_insert (insert_into_clause INTO (general_table_ref (dml_table_expression_clause (tableview_name (identifier (id_expression (regular_id suppliers)))))) (paren_column_list ( (column_list (column_name (identifier (id_expression (regular_id supplier_id)))) , (column_name (identifier (id_expression (regular_id supplier_name))))) ))) (values_clause VALUES ( (expressions (expression (logical_expression (multiset_expression (relational_expression (compound_expression (concatenation (model_expression (unary_expression (atom (constant (numeric 5000))))))))))) , (expression (logical_expression (multiset_expression (relational_expression (compound_expression (concatenation (model_expression (unary_expression (atom (constant (quoted_string 'Apple')))))))))))) )))))) ; <EOF>)"
#input_string = "(sql_script (unit_statement (data_manipulation_language_statements (insert_statement INSERT (single_table_insert (insert_into_clause INTO (general_table_ref (dml_table_expression_clause (tableview_name (identifier (id_expression (regular_id suppliers)))))) (paren_column_list ( (column_list (column_name (identifier (id_expression (regular_id supplier_id)))) , (column_name (identifier (id_expression (regular_id supplier_name))))) ))) (select_statement (subquery (subquery_basic_elements (query_block SELECT (selected_element (select_list_elements (expressions (expression (logical_expression (multiset_expression (relational_expression (compound_expression (concatenation (model_expression (unary_expression (atom (general_element (general_element_part (id_expression (regular_id account_no))))))))))))) , (expression (logical_expression (multiset_expression (relational_expression (compound_expression (concatenation (model_expression (unary_expression (atom (general_element (general_element_part (id_expression (regular_id (non_reserved_keywords_pre12c name))))))))))))))))) (from_clause FROM (table_ref_list (table_ref (table_ref_aux (table_ref_aux_internal (dml_table_expression_clause (tableview_name (identifier (id_expression (regular_id customers)))))))))) (where_clause WHERE (expression (logical_expression (multiset_expression (relational_expression (relational_expression (compound_expression (concatenation (model_expression (unary_expression (atom (general_element (general_element_part (id_expression (regular_id customer_id)))))))))) (relational_operator >) (relational_expression (compound_expression (concatenation (model_expression (unary_expression (atom (constant (numeric 5000))))))))))))))))))))) ; <EOF>)"
#input_string = "(sql_script (unit_statement (data_manipulation_language_statements (update_statement UPDATE (general_table_ref (dml_table_expression_clause (tableview_name (identifier (id_expression (regular_id customers)))))) (update_set_clause SET (column_based_update_set_clause (column_name (identifier (id_expression (regular_id last_name)))) = (expression (logical_expression (multiset_expression (relational_expression (compound_expression (concatenation (model_expression (unary_expression (atom (constant (quoted_string 'Anderson'))))))))))))) (where_clause WHERE (expression (logical_expression (multiset_expression (relational_expression (relational_expression (compound_expression (concatenation (model_expression (unary_expression (atom (general_element (general_element_part (id_expression (regular_id customer_id)))))))))) (relational_operator =) (relational_expression (compound_expression (concatenation (model_expression (unary_expression (atom (constant (numeric 5000)))))))))))))))) ; <EOF>)"
#input_string = "(sql_script (unit_statement (data_manipulation_language_statements (insert_statement INSERT (single_table_insert (insert_into_clause INTO (general_table_ref (dml_table_expression_clause (tableview_name (identifier (id_expression (regular_id suppliers)))))) (paren_column_list ( (column_list (column_name (identifier (id_expression (regular_id supplier_id)))) , (column_name (identifier (id_expression (regular_id supplier_name))))) ))) (select_statement (subquery (subquery_basic_elements (query_block SELECT (selected_element (select_list_elements (expressions (expression (logical_expression (multiset_expression (relational_expression (compound_expression (concatenation (model_expression (unary_expression (atom (general_element (general_element_part (id_expression (regular_id account_no))))))))))))) , (expression (logical_expression (multiset_expression (relational_expression (compound_expression (concatenation (model_expression (unary_expression (atom (general_element (general_element_part (id_expression (regular_id (non_reserved_keywords_pre12c name))))))))))))))))) (from_clause FROM (table_ref_list (table_ref (table_ref_aux (table_ref_aux_internal (dml_table_expression_clause (tableview_name (identifier (id_expression (regular_id customers)))))))))) (where_clause WHERE (expression (logical_expression (logical_expression (multiset_expression (relational_expression (relational_expression (compound_expression (concatenation (model_expression (unary_expression (atom (general_element (general_element_part (id_expression (regular_id customer_id)))))))))) (relational_operator >) (relational_expression (compound_expression (concatenation (model_expression (unary_expression (atom (constant (numeric 5000))))))))))) and (logical_expression (multiset_expression (relational_expression (relational_expression (compound_expression (concatenation (model_expression (unary_expression (atom (general_element (general_element_part (id_expression (regular_id customer_name)))))))))) (relational_operator <>) (relational_expression (compound_expression (concatenation (model_expression (unary_expression (atom (constant (quoted_string 'john')))))))))))))))))))))) ; <EOF>)"
2018-02-23 00:40:26 +01:00
2018-02-23 22:11:09 +01:00
#input_string = "[@0,0:5='INSERT',<663>,1:0]\n[@1,7:10='INTO',<685>,1:7]\n[@2,12:20='suppliers',<2242>,1:12]\n[@3,22:22='(',<2213>,2:0]\n[@4,23:33='supplier_id',<2242>,2:1]\n[@5,34:34=',',<2219>,2:12]\n[@6,36:48='supplier_name',<2242>,2:14]\n[@7,49:49=')',<2214>,2:27]\n[@8,51:56='VALUES',<2064>,3:0]\n[@9,58:58='(',<2213>,4:0]\n[@10,59:62='5000',<2207>,4:1]\n[@11,63:63=',',<2219>,4:5]\n[@12,65:71=''Apple'',<2209>,4:7]\n[@13,72:72=')',<2214>,4:14]\n[@14,73:73=';',<2231>,4:15]\n[@15,75:74='<EOF>',<-1>,5:0]"
#input_string = "[@0,0:5='INSERT',<663>,1:0]\n[@1,7:10='INTO',<685>,1:7]\n[@2,12:20='suppliers',<2242>,1:12]\n[@3,22:22='(',<2213>,2:0]\n[@4,23:33='supplier_id',<2242>,2:1]\n[@5,34:34=',',<2219>,2:12]\n[@6,36:48='supplier_name',<2242>,2:14]\n[@7,49:49=')',<2214>,2:27]\n[@8,51:56='SELECT',<1482>,3:0]\n[@9,58:67='account_no',<2242>,3:7]\n[@10,68:68=',',<2219>,3:17]\n[@11,70:73='name',<873>,3:19]\n[@12,75:78='FROM',<548>,4:0]\n[@13,80:88='customers',<2242>,4:5]\n[@14,90:94='WHERE',<2105>,5:0]\n[@15,96:106='customer_id',<2242>,5:6]\n[@16,108:108='>',<2228>,5:18]\n[@17,110:113='5000',<2207>,5:20]\n[@18,114:114=';',<2231>,5:24]\n[@19,116:115='<EOF>',<-1>,6:0]"
#input_string = "[@0,0:5='INSERT',<663>,1:0]\n[@1,7:10='INTO',<685>,1:7]\n[@2,12:20='suppliers',<2242>,1:12]\n[@3,22:22='(',<2213>,2:0]\n[@4,23:33='supplier_id',<2242>,2:1]\n[@5,34:34=',',<2219>,2:12]\n[@6,36:48='supplier_name',<2242>,2:14]\n[@7,49:49=')',<2214>,2:27]\n[@8,51:56='SELECT',<1482>,3:0]\n[@9,58:58='(',<2213>,3:7]\n[@10,59:68='account_no',<2242>,3:8]\n[@11,69:69=',',<2219>,3:18]\n[@12,71:74='name',<873>,3:20]\n[@13,75:75=')',<2214>,3:24]\n[@14,77:80='FROM',<548>,4:0]\n[@15,82:90='customers',<2242>,4:5]\n[@16,92:96='WHERE',<2105>,5:0]\n[@17,98:108='customer_id',<2242>,5:6]\n[@18,110:110='>',<2228>,5:18]\n[@19,112:115='5000',<2207>,5:20]\n[@20,116:116=';',<2231>,5:24]\n[@21,118:117='<EOF>',<-1>,6:0]"
#input_string = "[@0,0:5='INSERT',<663>,1:0]\n[@1,7:10='INTO',<685>,1:7]\n[@2,12:20='suppliers',<2242>,1:12]\n[@3,22:22='(',<2213>,2:0]\n[@4,23:33='supplier_id',<2242>,2:1]\n[@5,34:34=',',<2219>,2:12]\n[@6,36:48='supplier_name',<2242>,2:14]\n[@7,49:49=')',<2214>,2:27]\n[@8,51:56='SELECT',<1482>,3:0]\n[@9,58:58='(',<2213>,3:7]\n[@10,59:68='account_no',<2242>,3:8]\n[@11,69:69=',',<2219>,3:18]\n[@12,71:74='name',<873>,3:20]\n[@13,75:75=')',<2214>,3:24]\n[@14,77:80='FROM',<548>,4:0]\n[@15,82:90='customers',<2242>,4:5]\n[@16,92:96='WHERE',<2105>,5:0]\n[@17,98:98='(',<2213>,5:6]\n[@18,99:109='customer_id',<2242>,5:7]\n[@19,111:111='>',<2228>,5:19]\n[@20,113:116='5000',<2207>,5:21]\n[@21,117:117=')',<2214>,5:25]\n[@22,118:118=';',<2231>,5:26]\n[@23,120:119='<EOF>',<-1>,6:0]"
#Problematic input, mixing SELECT statement
input_string = "[@0,0:5='INSERT',<663>,1:0]\n[@1,7:10='INTO',<685>,1:7]\n[@2,12:18='clients',<2242>,1:12]\n[@3,20:20='(',<2213>,2:0]\n[@4,21:29='client_id',<2242>,2:1]\n[@5,30:30=',',<2219>,2:10]\n[@6,32:42='client_name',<2242>,2:12]\n[@7,43:43=',',<2219>,2:23]\n[@8,45:55='client_type',<2242>,2:25]\n[@9,56:56=')',<2214>,2:36]\n[@10,58:63='SELECT',<1482>,3:0]\n[@11,65:69='10345',<2207>,3:7]\n[@12,70:70=',',<2219>,3:12]\n[@13,72:76=''IBM'',<2209>,3:14]\n[@14,77:77=',',<2219>,3:19]\n[@15,79:91=''advertising'',<2209>,3:21]\n[@16,93:96='FROM',<548>,4:0]\n[@17,98:101='dual',<2242>,4:5]\n[@18,103:107='WHERE',<2105>,5:0]\n[@19,109:111='NOT',<1067>,5:6]\n[@20,113:118='EXISTS',<472>,5:10]\n[@21,120:120='(',<2213>,5:17]\n[@22,121:126='SELECT',<1482>,5:18]\n[@23,128:128='*',<2216>,5:25]\n[@24,148:151='FROM',<548>,6:18]\n[@25,153:159='clients',<2242>,6:23]\n[@26,179:183='WHERE',<2105>,7:18]\n[@27,185:191='clients',<2242>,7:24]\n[@28,192:192='.',<2206>,7:31]\n[@29,193:201='client_id',<2242>,7:32]\n[@30,203:203='=',<2233>,7:42]\n[@31,205:209='10345',<2207>,7:44]\n[@32,210:210=')',<2214>,7:49]\n[@33,211:211=';',<2231>,7:50]\n[@34,213:212='<EOF>',<-1>,8:0]"
def get_quoted_value (line)
first_quote = line.index('\'')
last_quote = line.rindex('\'')
if first_quote and last_quote then
return line[first_quote+1..last_quote-1]
else
return ''
end
end
input_array = input_string.split("\n")
#Constants
COMMAND_LINE = 0 #Command is in first line
INSERT_MODE = 0
UPDATE_MODE = 1
output = Hash.new
command_mode = nil
output['command'] = get_quoted_value(input_array[COMMAND_LINE])
case output['command'].downcase
when 'insert'
command_mode = INSERT_MODE
when 'update'
command_mode = UPDATE_MODE
end
i=0
input_array.each do |line|
if line.downcase.index('into') then
output['table_name'] = get_quoted_value(input_array[i+1]) #table for INSERT is line after INTO statement
#column_names are after table name and '('
output['column_names'] = []
k=i+3
loop do
column_name = get_quoted_value(input_array[k])
break if column_name == ')'
if column_name != ',' then output['column_names'].push(column_name) end
k+=1
end
end
if line.downcase.index('values') then
output['column_values'] = []
k=i+2
loop do
column_value = get_quoted_value(input_array[k])
break if column_value == ')'
if column_value != ',' then output['column_values'].push(column_value) end
k+=1
end
end
if line.downcase.index('select') then
output['select_columns'] = []
finish_loop_on_char = 'from'
k=i+1
if get_quoted_value(input_array[i+1]) == '(' then
finish_loop_on_char = ')'
k+=1
end
loop do
column_value = get_quoted_value(input_array[k])
break if column_value.downcase == finish_loop_on_char
if column_value != ',' then output['select_columns'].push(column_value) end
k+=1
end
end
if line.downcase.index('where') then
output['where_conditions'] = ''
finish_loop_on_char = ';'
k=i+1
if get_quoted_value(input_array[i+1]) == '(' then
finish_loop_on_char = ')'
k+=1
end
loop do
column_value = get_quoted_value(input_array[k])
break if column_value.downcase == finish_loop_on_char
output['where_conditions'] += column_value
k+=1
end
end
if line.downcase.index('from') then
output['from_table'] = get_quoted_value(input_array[i+1]) #table for FROM query is line after FROM statement
end
i+=1
end
puts output
return
#Old try
end_of_input = input_string.index(';') - 1
input_string = input_string[0..end_of_input] + ')'
tag_list = []
tag_levels = []
tag_level = 0
input_string.split('(').each do |tag|
level_down = tag.count(')')
clean_tag = tag.gsub ')', ''
#puts clean_tag + "[" + tag_level.to_s + "]"
if clean_tag.length > 1 then
tag_list.push(clean_tag)
tag_levels.push(tag_level)
#result[tag_level] = clean_tag + ';' + result[tag_level].to_s
tag_level += 1
tag_level -= level_down
end
end
#Command : INSERT / UPDATE / DELETE / CREATE / ALTER is on level 3
#On level 3, there is statement like "insert_statement INSERT"
#CONSTANTS :
COMMAND_LEVEL = 3
output = Hash.new
output['command'] = tag_list[COMMAND_LEVEL].split(' ')[1] #command is after space
output['values'] = Hash.new
output['where'] = nil
output['from'] = nil
values_array = []
i=0
value_counter = 0
k=0
first_block = true
tag_list.each do |tag|
puts "[" + tag_levels[i].to_s + "] : " + tag
if tag.index('from_clause') then
output['from'] = tag_list[i+8].to_s.split(' ')[1]
end
if tag.index('where_clause') then
end
if i < tag_list.length-1
if tag_levels[i+1] < tag_levels[i] then
k = tag_levels[i] - tag_levels[i+1]
parent = tag_list[i-k].rstrip.lstrip
clean_tag = tag.split(' ')[1]
if parent == "general_table_ref" then
output['table_name'] = clean_tag
elsif parent == "column_name" then
output['values'][clean_tag] = nil
values_array.push(clean_tag)
elsif parent == "expression" then
output['values'][values_array[value_counter]] = clean_tag
value_counter+=1
i+=1
end
else
end
else
#Last tag in array, locate parent
if first_block then
first_block = false
else
parent = tag_list[i-k-1].rstrip.lstrip
clean_tag = tag.split(' ')[1]
if parent == "expression" then
output['values'][values_array[value_counter]] = clean_tag
end
end
end
i+=1
end
puts output
return
#Old try #2
def parse(input)
puts "New input : " + input
open_count = input.count('(')
close_count = input.count(')')
first_bracket = input.index('(')
last_bracket = input.rindex(')')
if (first_bracket == -1) or (last_bracket == -1) then return '' end
#return everything between brackets
tmp_token = ''
result = []
level = 0
new_input = input[first_bracket+1..last_bracket-1]
# new_input.split('').each do |character|
# if character == '(' then level += 1 end
# if character == ')' then level -= 1 end
# if level == 0 then
# puts "ok"
# if tmp_token.length > 0 then
# result.push(tmp_token)
# tmp_token=''
# end
# else
# tmp_token += character
# end
# end
# puts "==="
# return result
end