Class: MongoRecord::SQL::Tokenizer
Overview
A simple tokenizer for SQL.
Instance Attribute Summary collapse
-
#sql ⇒ Object
readonly
Returns the value of attribute sql.
Instance Method Summary collapse
-
#add_extra_token(tok) ⇒ Object
Push
tok
onto the stack. -
#identifier_char?(c) ⇒ Boolean
Return
true
if the next character is a legal starting identifier character. -
#initialize(sql) ⇒ Tokenizer
constructor
A new instance of Tokenizer.
-
#more? ⇒ Boolean
Return
true
if there are more non-whitespace characters. -
#next_string(c) ⇒ Object
Return the next string without its surrounding quotes.
-
#next_token ⇒ Object
Return the next token, or
nil
if there are no more. -
#quote?(c) ⇒ Boolean
Return
true
ifc
is a single or double quote character. -
#skip_whitespace ⇒ Object
Skips whitespace, setting @pos to the position of the next non-whitespace character.
Constructor Details
#initialize(sql) ⇒ Tokenizer
Returns a new instance of Tokenizer.
24 25 26 27 28 29 |
# File 'lib/mongo_record/sql.rb', line 24 def initialize(sql) @sql = sql @length = sql.length @pos = 0 @extra_tokens = [] end |
Instance Attribute Details
#sql ⇒ Object (readonly)
Returns the value of attribute sql.
22 23 24 |
# File 'lib/mongo_record/sql.rb', line 22 def sql @sql end |
Instance Method Details
#add_extra_token(tok) ⇒ Object
Push tok
onto the stack.
32 33 34 |
# File 'lib/mongo_record/sql.rb', line 32 def add_extra_token(tok) @extra_tokens.push(tok) end |
#identifier_char?(c) ⇒ Boolean
Return true
if the next character is a legal starting identifier character.
81 82 83 |
# File 'lib/mongo_record/sql.rb', line 81 def identifier_char?(c) c =~ /[\.a-zA-Z0-9_]/ ? true : false end |
#more? ⇒ Boolean
Return true
if there are more non-whitespace characters.
45 46 47 48 |
# File 'lib/mongo_record/sql.rb', line 45 def more? skip_whitespace @pos < @length end |
#next_string(c) ⇒ Object
Return the next string without its surrounding quotes. Assumes we have already seen a quote character.
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/mongo_record/sql.rb', line 52 def next_string(c) q = c @pos += 1 t = '' while @pos < @length c = @sql[@pos, 1] case c when q if @pos + 1 < @length && @sql[@pos + 1, 1] == q # double quote t += q @pos += 1 else @pos += 1 return t end when '\\' @pos += 1 return t if @pos >= @length t << @sql[@pos, 1] else t << c end @pos += 1 end raise "unterminated string in SQL: #{@sql}" end |
#next_token ⇒ Object
Return the next token, or nil
if there are no more.
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/mongo_record/sql.rb', line 91 def next_token return @extra_tokens.pop unless @extra_tokens.empty? skip_whitespace c = @sql[@pos, 1] return next_string(c) if quote?(c) first_is_identifier_char = identifier_char?(c) t = c @pos += 1 while @pos < @length c = @sql[@pos, 1] break if c == ' ' this_is_identifier_char = identifier_char?(c) break if first_is_identifier_char != this_is_identifier_char && @length > 0 break if !this_is_identifier_char && quote?(c) t << c @pos += 1 end case t when '' nil when /^\d+$/ t.to_i else t end end |
#quote?(c) ⇒ Boolean
Return true
if c
is a single or double quote character.
86 87 88 |
# File 'lib/mongo_record/sql.rb', line 86 def quote?(c) c == '"' || c == "'" end |
#skip_whitespace ⇒ Object
Skips whitespace, setting @pos to the position of the next non-whitespace character. If there is none, @pos will == @length.
38 39 40 41 42 |
# File 'lib/mongo_record/sql.rb', line 38 def skip_whitespace while @pos < @length && [" ", "\n", "\r", "\t"].include?(@sql[@pos,1]) @pos += 1 end end |