Skip to content

Commit fe8b0db

Browse files
committed
Added support for MySQL type backticks quoting for identifiers for both parsing and SQL generation.
Usage: SQLTree.identifier_quote_char = '`'
1 parent fac3d1c commit fe8b0db

File tree

4 files changed

+23
-6
lines changed

4 files changed

+23
-6
lines changed

lib/sql_tree.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@
55
# necessary files for the gem to function properly.
66
module SQLTree
77

8+
class << self
9+
# The character to quote variable names with.
10+
attr_accessor :identifier_quote_char
11+
end
12+
13+
# Set default quote characters
14+
self.identifier_quote_char = '"'
15+
816
# Loads constants in the SQLTree namespace using self.load_default_class_file(base, const)
917
# <tt>const</tt>:: The constant that is not yet loaded in the SQLTree namespace. This should be passed as a string or symbol.
1018
def self.const_missing(const)

lib/sql_tree/node.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ def inspect
2727
# SQL queries.
2828
# <tt>name</tt>:: The name of the variable to quote.
2929
def quote_var(name)
30-
"\"#{name}\"" # TODO: MySQL style variable quoting
30+
"#{SQLTree.identifier_quote_char}#{name}#{SQLTree.identifier_quote_char}" # TODO: MySQL style variable quoting
3131
end
3232

3333
# Quotes a string so that it can be used safey within an SQL query.
3434
# <tt>str</tt>:: The string to quote.
3535
def quote_str(str)
36-
"'#{str.gsub(/\'/, "''")}'"
36+
"'#{str.gsub("'", "''")}'"
3737
end
3838

3939
# Parses an SQL fragment tree from a stream of tokens.

lib/sql_tree/tokenizer.rb

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ def empty_keyword_queue!(&block) # :yields: SQLTree::Token
8484
# This method is aliased to <tt>:each</tt> to make the Enumerable
8585
# methods work on this method.
8686
def each_token(&block) # :yields: SQLTree::Token
87+
8788
while next_char
8889
case current_char
8990
when /^\s?$/; # whitespace, go to next character
@@ -93,9 +94,9 @@ def each_token(&block) # :yields: SQLTree::Token
9394
when ','; handle_token(SQLTree::Token::COMMA, &block)
9495
when /\d/; tokenize_number(&block)
9596
when "'"; tokenize_quoted_string(&block)
96-
when OPERATOR_CHARS; tokenize_operator(&block)
9797
when /\w/; tokenize_keyword(&block)
98-
when '"'; tokenize_quoted_variable(&block) # TODO: allow MySQL quoting mode
98+
when OPERATOR_CHARS; tokenize_operator(&block)
99+
when SQLTree.identifier_quote_char; tokenize_quoted_identifier(&block)
99100
end
100101
end
101102

@@ -154,9 +155,9 @@ def tokenize_quoted_string(&block) # :yields: SQLTree::Token::String
154155
#
155156
# The actual quote character that is used depends on the DBMS. For now,
156157
# only the more standard double quote is accepted.
157-
def tokenize_quoted_variable(&block) # :yields: SQLTree::Token::Identifier
158+
def tokenize_quoted_identifier(&block) # :yields: SQLTree::Token::Identifier
158159
variable = ''
159-
until next_char.nil? || current_char == '"' # TODO: allow MySQL quoting mode
160+
until next_char.nil? || current_char == SQLTree.identifier_quote_char # TODO: allow MySQL quoting mode
160161
variable << (current_char == "\\" ? next_char : current_char)
161162
end
162163
handle_token(SQLTree::Token::Identifier.new(variable), &block)

spec/integration/parse_and_generate_spec.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,17 @@
22

33
describe SQLTree, 'parsing and generating SQL' do
44

5+
before(:each) { SQLTree.identifier_quote_char = '"' }
6+
57
it "should parse an generate q query without FROM" do
68
SQLTree['SELECT 1'].to_sql.should == 'SELECT 1'
79
end
10+
11+
it "should parse and generate MySQL type identifier quotes" do
12+
SQLTree.identifier_quote_char = "`"
13+
SQLTree['SELECT `field` FROM `table`'].to_sql.should ==
14+
'SELECT `field` FROM `table`'
15+
end
816

917
it "should parse and generate SQL fo a simple list query" do
1018
SQLTree["SELECT * FROM table"].to_sql.should == 'SELECT * FROM "table"'

0 commit comments

Comments
 (0)