Skip to content

Instantly share code, notes, and snippets.

@jonatas
Created March 4, 2018 14:18
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 jonatas/b2894da3014ba474feb50bf72eba7d25 to your computer and use it in GitHub Desktop.
Save jonatas/b2894da3014ba474feb50bf72eba7d25 to your computer and use it in GitHub Desktop.
Query = Struct.new(:attributes, :source, :conditions, :order_by)
class SQLParser
attr_reader :query
def initialize(string)
@tokens = string.scan(/\(|\)|:?\w+|[\+\-\/\*=]+|[<>]=?/)
@query = Query.new
end
def next_token
@tokens.shift
end
def parse
case token = next_token
when 'select'
@query.attributes = parse_until('from')
parse
when 'from'
@query.source = parse_until('where')
parse
when 'where'
@query.conditions = parse_until('order')
parse
when 'order'
@query.order_by = []
@query.order_by << parse until @tokens.empty?
when /\d+\.\d+/ then token.to_f
when /\d+/ then token.to_i
when /[<>]=?/ then token.to_sym
else token.to_sym
end
end
def parse_until(token_close)
list = []
list << parse until @tokens.empty? || @tokens.first == token_close
list
end
end
sql = SQLParser.new('select id, name from table where age > 30 order age desc')
sql.parse
pp sql.query # <struct Query attributes=[:id, :name], source=[:table], conditions=[:age, :>, 30], order_by=[:age, :desc]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment