Skip to content

Instantly share code, notes, and snippets.

@mfpiccolo
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mfpiccolo/66920e112fb15c3454c5 to your computer and use it in GitHub Desktop.
Save mfpiccolo/66920e112fb15c3454c5 to your computer and use it in GitHub Desktop.
# What I want to do is take a string like "some_attribute <= 5" and be able to parse that into SQL
# The string will only ever have one operation so I need to check for the inclusion of any valid opperator
# and build a SQL string based on that.
# initial conditional method
def build_sql_string
@final_sql_array = sql_array.map(&:strip).map do |string|
if string.include?(":")
q = string.split(":")
"(similarity((data->>'#{q[0].strip}')::text, '#{q[1].strip}') > .5 OR " +
"(data->>'#{q[0].strip}')::text ILIKE '%#{q[1].strip}%')"
elsif [">=", "<=", ">", "<"].any? { |join| string.include? join }
q = string.gsub(/\s+/m, ' ').strip.split(" ")
"(data->>'#{q[0].strip}')::int #{q[1]} #{q[2]}"
elsif ["=", "!="].any? {|equal_opp| string.include?(equal_opp) }
q = string.gsub(/\s+/m, ' ').strip.split(" ")
"(data->>'#{q[0].strip}')::text #{q[1]} '#{q[2]}'"
elsif string == "||"
" OR "
elsif string == "&&"
" AND "
else
string
end
end
end
# after refactor
def build_sql_string
@final_sql_array = sql_array.map(&:strip).map do |string|
SqlString.call(string)
end
end
class SqlString
OperatorMapping = {
"<=" => :compare_query, ">=" => :compare_query, "<" => :compare_query,
">" => :compare_query, "=" => :equal_query, "!=" => :equal_query,
"||" => :or_join, "&&" => :and_join, ":" => :like_query
}
attr_reader :sql_string
def self.call(sql_string)
new(sql_string).call
end
def initialize(sql_string)
@sql_string = sql_string
end
def call
operator = sql_string.scan(matchers)
if operator.size == 1
send OperatorMapping[operator.first]
end
end
def like_query
# build sql here
end
private
def matchers
Regexp.union(/<=/, />=/, /</, />/, /=/, /!=/, /\|\|/, /&&/, /:/)
end
end
@elskwid
Copy link

elskwid commented Aug 26, 2014

Hey Mike, perhaps you should look at this parser. It creates an AST for SQL which means you can go from string, to AST, back to an SQL string. https://github.com/rom-rb/sql

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment