sql_tree 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -1
- data/README.rdoc +6 -5
- data/lib/sql_tree.rb +11 -3
- data/lib/sql_tree/node.rb +75 -4
- data/lib/sql_tree/node/delete_query.rb +19 -6
- data/lib/sql_tree/node/expression.rb +431 -163
- data/lib/sql_tree/node/insert_query.rb +13 -17
- data/lib/sql_tree/node/join.rb +8 -12
- data/lib/sql_tree/node/ordering.rb +4 -3
- data/lib/sql_tree/node/select_declaration.rb +62 -0
- data/lib/sql_tree/node/select_query.rb +27 -46
- data/lib/sql_tree/node/source.rb +5 -8
- data/lib/sql_tree/node/table_reference.rb +7 -10
- data/lib/sql_tree/node/update_query.rb +73 -12
- data/lib/sql_tree/parser.rb +70 -14
- data/lib/sql_tree/token.rb +48 -22
- data/lib/sql_tree/tokenizer.rb +23 -16
- data/spec/integration/parse_and_generate_spec.rb +8 -0
- data/spec/lib/matchers.rb +3 -2
- data/spec/unit/delete_query_spec.rb +2 -2
- data/spec/unit/expression_node_spec.rb +24 -23
- data/spec/unit/insert_query_spec.rb +8 -8
- data/spec/unit/leaf_node_spec.rb +17 -17
- data/spec/unit/select_query_spec.rb +4 -4
- data/spec/unit/tokenizer_spec.rb +17 -21
- data/spec/unit/update_query_spec.rb +6 -6
- data/sql_tree.gemspec +3 -3
- metadata +4 -8
- data/lib/sql_tree/node/assignment.rb +0 -22
- data/lib/sql_tree/node/field.rb +0 -49
- data/lib/sql_tree/node/select_expression.rb +0 -45
- data/lib/sql_tree/node/value.rb +0 -33
- data/lib/sql_tree/node/variable.rb +0 -31
@@ -4,21 +4,21 @@ describe SQLTree::Node::InsertQuery do
|
|
4
4
|
|
5
5
|
it "should parse an insert query without field list correctly" do
|
6
6
|
insert = SQLTree::Node::InsertQuery["INSERT INTO table VALUES (1, 'two', 3+4, MD5('$ecret'))"]
|
7
|
-
insert.table.should == 'table'
|
7
|
+
insert.table.should == SQLTree::Node::TableReference.new('table')
|
8
8
|
insert.fields.should be_nil
|
9
9
|
insert.values.should have(4).items
|
10
|
-
insert.values[0].should == SQLTree::Node::Value.new(1)
|
11
|
-
insert.values[1].should == SQLTree::Node::Value.new('two')
|
12
|
-
insert.values[2].should be_kind_of(SQLTree::Node::
|
13
|
-
insert.values[3].should be_kind_of(SQLTree::Node::
|
10
|
+
insert.values[0].should == SQLTree::Node::Expression::Value.new(1)
|
11
|
+
insert.values[1].should == SQLTree::Node::Expression::Value.new('two')
|
12
|
+
insert.values[2].should be_kind_of(SQLTree::Node::Expression::BinaryOperator)
|
13
|
+
insert.values[3].should be_kind_of(SQLTree::Node::Expression::FunctionCall)
|
14
14
|
end
|
15
15
|
|
16
16
|
it "should parse an insert query with field list" do
|
17
17
|
insert = SQLTree::Node::InsertQuery['INSERT INTO table ("field1", "field2") VALUES (1, 2)']
|
18
|
-
insert.table.should == 'table'
|
18
|
+
insert.table.should == SQLTree::Node::TableReference.new('table')
|
19
19
|
insert.fields.should have(2).items
|
20
|
-
insert.fields[0].should == SQLTree::Node::Variable.new('field1')
|
21
|
-
insert.fields[1].should == SQLTree::Node::Variable.new('field2')
|
22
20
|
insert.values.should have(2).items
|
21
|
+
insert.fields[0].should == SQLTree::Node::Expression::Field.new('field1')
|
22
|
+
insert.fields[1].should == SQLTree::Node::Expression::Field.new('field2')
|
23
23
|
end
|
24
24
|
end
|
data/spec/unit/leaf_node_spec.rb
CHANGED
@@ -1,82 +1,82 @@
|
|
1
1
|
require "#{File.dirname(__FILE__)}/../spec_helper"
|
2
2
|
|
3
|
-
describe SQLTree::Node::Value do
|
3
|
+
describe SQLTree::Node::Expression::Value do
|
4
4
|
|
5
5
|
describe '.parse' do
|
6
6
|
it "should not parse a field name" do
|
7
|
-
lambda { SQLTree::Node::Value['field_name'] }.should raise_error(SQLTree::Parser::UnexpectedToken)
|
7
|
+
lambda { SQLTree::Node::Expression::Value['field_name'] }.should raise_error(SQLTree::Parser::UnexpectedToken)
|
8
8
|
end
|
9
9
|
|
10
10
|
it "should parse an integer value correctly" do
|
11
|
-
SQLTree::Node::Value['123'].value.should == 123
|
11
|
+
SQLTree::Node::Expression::Value['123'].value.should == 123
|
12
12
|
end
|
13
13
|
|
14
14
|
it "should parse a string correctly" do
|
15
|
-
SQLTree::Node::Value["'123'"].value.should == '123'
|
15
|
+
SQLTree::Node::Expression::Value["'123'"].value.should == '123'
|
16
16
|
end
|
17
17
|
|
18
18
|
it "should parse a NULL value correctly" do
|
19
|
-
SQLTree::Node::Value['NULL'].value.should == nil
|
19
|
+
SQLTree::Node::Expression::Value['NULL'].value.should == nil
|
20
20
|
end
|
21
21
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
describe SQLTree::Node::Variable do
|
25
|
+
describe SQLTree::Node::Expression::Variable do
|
26
26
|
|
27
27
|
describe '.parse' do
|
28
28
|
it "should parse a variable name correctly" do
|
29
|
-
SQLTree::Node::
|
29
|
+
SQLTree::Node::Expression::Variable['variable'].name.should == 'variable'
|
30
30
|
end
|
31
31
|
|
32
32
|
it "should parse a quoted variable name correctly" do
|
33
|
-
SQLTree::Node::
|
33
|
+
SQLTree::Node::Expression::Variable['"variable"'].name.should == 'variable'
|
34
34
|
end
|
35
35
|
|
36
36
|
it "should raise an error when parsing a reserved keyword as variable" do
|
37
|
-
lambda { SQLTree::Node::
|
37
|
+
lambda { SQLTree::Node::Expression::Variable['select'] }.should raise_error(SQLTree::Parser::UnexpectedToken)
|
38
38
|
end
|
39
39
|
|
40
40
|
it "should parse a quoted reserved keyword as variable name correctly" do
|
41
|
-
SQLTree::Node::
|
41
|
+
SQLTree::Node::Expression::Variable['"select"'].name.should == 'select'
|
42
42
|
end
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
-
describe SQLTree::Node::Field do
|
46
|
+
describe SQLTree::Node::Expression::Field do
|
47
47
|
describe '.parse' do
|
48
48
|
it "should parse a field name with table name correclty" do
|
49
|
-
field = SQLTree::Node::Field['table.field']
|
49
|
+
field = SQLTree::Node::Expression::Field['table.field']
|
50
50
|
field.table.should == 'table'
|
51
51
|
field.name.should == 'field'
|
52
52
|
end
|
53
53
|
|
54
54
|
it "should parse a field name without table name correclty" do
|
55
|
-
field = SQLTree::Node::Field['field']
|
55
|
+
field = SQLTree::Node::Expression::Field['field']
|
56
56
|
field.table.should be_nil
|
57
57
|
field.name.should == 'field'
|
58
58
|
end
|
59
59
|
|
60
60
|
it "should parse a quoted field name without table name correclty" do
|
61
|
-
field = SQLTree::Node::Field['"field"']
|
61
|
+
field = SQLTree::Node::Expression::Field['"field"']
|
62
62
|
field.table.should be_nil
|
63
63
|
field.name.should == 'field'
|
64
64
|
end
|
65
65
|
|
66
66
|
it "should parse a quoted field name with quoted table name correclty" do
|
67
|
-
field = SQLTree::Node::Field['"table"."field"']
|
67
|
+
field = SQLTree::Node::Expression::Field['"table"."field"']
|
68
68
|
field.table.should == 'table'
|
69
69
|
field.name.should == 'field'
|
70
70
|
end
|
71
71
|
|
72
72
|
it "should parse a quoted field name with non-quoted table name correclty" do
|
73
|
-
field = SQLTree::Node::Field['table."field"']
|
73
|
+
field = SQLTree::Node::Expression::Field['table."field"']
|
74
74
|
field.table.should == 'table'
|
75
75
|
field.name.should == 'field'
|
76
76
|
end
|
77
77
|
|
78
78
|
it "should parse a non-quoted field name with quoted table name correclty" do
|
79
|
-
field = SQLTree::Node::Field['"table".field']
|
79
|
+
field = SQLTree::Node::Expression::Field['"table".field']
|
80
80
|
field.table.should == 'table'
|
81
81
|
field.name.should == 'field'
|
82
82
|
end
|
@@ -18,9 +18,9 @@ describe SQLTree::Node::SelectQuery do
|
|
18
18
|
|
19
19
|
tree.select.length.should == 2
|
20
20
|
tree.from.length.should == 2
|
21
|
-
tree.where.should be_kind_of(SQLTree::Node::
|
22
|
-
tree.group_by.first.should be_kind_of(SQLTree::Node::Field)
|
23
|
-
tree.having.should be_kind_of(SQLTree::Node::
|
21
|
+
tree.where.should be_kind_of(SQLTree::Node::Expression::BinaryOperator)
|
22
|
+
tree.group_by.first.should be_kind_of(SQLTree::Node::Expression::Field)
|
23
|
+
tree.having.should be_kind_of(SQLTree::Node::Expression::BinaryOperator)
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -92,7 +92,7 @@ describe SQLTree::Node::Ordering do
|
|
92
92
|
|
93
93
|
it "should parse an ordering without direction" do
|
94
94
|
ordering = SQLTree::Node::Ordering["MD5(3 + 6) DESC"]
|
95
|
-
ordering.expression.should be_kind_of(SQLTree::Node::
|
95
|
+
ordering.expression.should be_kind_of(SQLTree::Node::Expression::FunctionCall)
|
96
96
|
ordering.direction.should == :desc
|
97
97
|
end
|
98
98
|
|
data/spec/unit/tokenizer_spec.rb
CHANGED
@@ -2,65 +2,61 @@ require "#{File.dirname(__FILE__)}/../spec_helper"
|
|
2
2
|
|
3
3
|
describe SQLTree::Tokenizer do
|
4
4
|
|
5
|
-
before(:all) do
|
6
|
-
@tokenizer = SQLTree::Tokenizer.new
|
7
|
-
end
|
8
|
-
|
9
5
|
context "recognizing single tokens" do
|
10
6
|
it "should tokenize SQL query keywords" do
|
11
|
-
|
7
|
+
SQLTree::Tokenizer.tokenize('WHERE').should tokenize_to(:where)
|
12
8
|
end
|
13
9
|
|
14
10
|
it "should tokenize expression keywords" do
|
15
|
-
|
11
|
+
SQLTree::Tokenizer.tokenize('and').should tokenize_to(:and)
|
16
12
|
end
|
17
13
|
|
18
14
|
it "should tokenize muliple separate keywords" do
|
19
|
-
|
15
|
+
SQLTree::Tokenizer.tokenize('SELECT DISTINCT').should tokenize_to(:select, :distinct)
|
20
16
|
end
|
21
17
|
|
22
18
|
it "should ignore excessive whitespace" do
|
23
|
-
|
19
|
+
SQLTree::Tokenizer.tokenize("\tSELECT DISTINCT \r\r").should tokenize_to(:select, :distinct)
|
24
20
|
end
|
25
21
|
|
26
22
|
it "should tokenize variables" do
|
27
|
-
|
23
|
+
SQLTree::Tokenizer.tokenize("var").should tokenize_to(sql_var('var'))
|
28
24
|
end
|
29
25
|
|
30
26
|
it "should tokenize quoted variables" do
|
31
|
-
|
27
|
+
SQLTree::Tokenizer.tokenize('"var"').should tokenize_to(sql_var('var'))
|
32
28
|
end
|
33
29
|
|
34
30
|
it "should tokenize quoted variables even when they are a reserved keyword" do
|
35
|
-
|
31
|
+
SQLTree::Tokenizer.tokenize('"where"').should tokenize_to(sql_var('where'))
|
36
32
|
end
|
37
33
|
|
38
34
|
it "should tokenize strings" do
|
39
|
-
|
35
|
+
SQLTree::Tokenizer.tokenize("'hello' ' world '").should tokenize_to('hello', ' world ')
|
40
36
|
end
|
41
37
|
|
42
38
|
it "should tokenize numbers" do
|
43
|
-
|
39
|
+
SQLTree::Tokenizer.tokenize("1 -2 3.14 -4.0").should tokenize_to(1, -2, 3.14, -4.0)
|
44
40
|
end
|
45
41
|
|
46
42
|
it "should tokenize logical operators" do
|
47
|
-
|
43
|
+
SQLTree::Tokenizer.tokenize("< = <> >=").should tokenize_to(:lt, :eq, :ne, :gte)
|
48
44
|
end
|
49
45
|
|
50
46
|
it "should tokenize arithmetic operators" do
|
51
|
-
|
47
|
+
SQLTree::Tokenizer.tokenize("+ - / * % || &").should tokenize_to(:plus, :minus, :divide, :multiply, :modulo, :concat, :binary_and)
|
52
48
|
end
|
53
49
|
|
54
50
|
it "should tokenize parentheses" do
|
55
|
-
|
51
|
+
SQLTree::Tokenizer.tokenize("(a)").should tokenize_to(lparen, sql_var('a'), rparen)
|
56
52
|
end
|
57
53
|
|
58
54
|
it "should tokenize dots" do
|
59
|
-
|
55
|
+
SQLTree::Tokenizer.tokenize('a."b"').should tokenize_to(sql_var('a'), dot, sql_var('b'))
|
60
56
|
end
|
61
57
|
|
62
58
|
it "should tokenize commas" do
|
63
|
-
|
59
|
+
SQLTree::Tokenizer.tokenize('a , "b"').should tokenize_to(sql_var('a'), comma, sql_var('b'))
|
64
60
|
end
|
65
61
|
end
|
66
62
|
|
@@ -68,18 +64,18 @@ describe SQLTree::Tokenizer do
|
|
68
64
|
# # Combination is currently done in the parsing phase.
|
69
65
|
# context "combining double keywords" do
|
70
66
|
# it "should tokenize double keywords" do
|
71
|
-
#
|
67
|
+
# SQLTree::Tokenizer.tokenize('NOT LIKE').should tokenize_to(:not_like)
|
72
68
|
# end
|
73
69
|
# end
|
74
70
|
|
75
71
|
context "when tokenizing full queries or query fragments" do
|
76
72
|
it "should tokenize a full SQL query" do
|
77
|
-
|
73
|
+
SQLTree::Tokenizer.tokenize("SELECT a.* FROM a_table AS a WHERE a.id > 1").should tokenize_to(
|
78
74
|
:select, sql_var('a'), dot, :multiply, :from, sql_var('a_table'), :as, sql_var('a'), :where, sql_var('a'), dot, sql_var('id'), :gt, 1)
|
79
75
|
end
|
80
76
|
|
81
77
|
it "should tokenize a function call" do
|
82
|
-
|
78
|
+
SQLTree::Tokenizer.tokenize("MD5('test')").should tokenize_to(sql_var('MD5'), lparen, 'test', rparen)
|
83
79
|
end
|
84
80
|
end
|
85
81
|
|
@@ -4,18 +4,18 @@ describe SQLTree::Node::UpdateQuery do
|
|
4
4
|
|
5
5
|
it "should parse a delete query without WHERE clause correctly" do
|
6
6
|
update = SQLTree::Node::UpdateQuery["UPDATE table SET field1 = 1, field2 = 5 - 3"]
|
7
|
-
update.table.should ==
|
7
|
+
update.table.should == SQLTree::Node::TableReference.new("table")
|
8
8
|
update.updates.should have(2).items
|
9
|
-
update.updates[0].field.should ==
|
10
|
-
update.updates[0].expression.should == SQLTree::Node::Value.new(1)
|
11
|
-
update.updates[1].field.should ==
|
12
|
-
update.updates[1].expression.should be_kind_of(SQLTree::Node::
|
9
|
+
update.updates[0].field.should == SQLTree::Node::Expression::Field.new("field1")
|
10
|
+
update.updates[0].expression.should == SQLTree::Node::Expression::Value.new(1)
|
11
|
+
update.updates[1].field.should == SQLTree::Node::Expression::Field.new("field2")
|
12
|
+
update.updates[1].expression.should be_kind_of(SQLTree::Node::Expression)
|
13
13
|
update.where.should be_nil
|
14
14
|
end
|
15
15
|
|
16
16
|
it "should parse a delete query without WHERE clause correctly" do
|
17
17
|
update = SQLTree::Node::UpdateQuery["UPDATE table SET field = 1 WHERE id = 17"]
|
18
|
-
update.table.should ==
|
18
|
+
update.table.should == SQLTree::Node::TableReference.new("table")
|
19
19
|
update.updates.should have(1).item
|
20
20
|
update.where.should be_kind_of(SQLTree::Node::Expression)
|
21
21
|
end
|
data/sql_tree.gemspec
CHANGED
@@ -3,8 +3,8 @@ Gem::Specification.new do |s|
|
|
3
3
|
|
4
4
|
# Do not modify the version and date values by hand, because this will
|
5
5
|
# automatically by them gem release script.
|
6
|
-
s.version = "0.1.
|
7
|
-
s.date = "2009-10-
|
6
|
+
s.version = "0.1.1"
|
7
|
+
s.date = "2009-10-17"
|
8
8
|
|
9
9
|
s.summary = "A pure Ruby library to represent SQL queries with a syntax tree for inspection and modification."
|
10
10
|
s.description = <<-EOS
|
@@ -22,6 +22,6 @@ Gem::Specification.new do |s|
|
|
22
22
|
|
23
23
|
# Do not modify the files and test_files values by hand, because this will
|
24
24
|
# automatically by them gem release script.
|
25
|
-
s.files = %w(spec/unit/select_query_spec.rb spec/unit/insert_query_spec.rb spec/spec_helper.rb lib/sql_tree/tokenizer.rb lib/sql_tree/node/
|
25
|
+
s.files = %w(spec/unit/select_query_spec.rb spec/unit/insert_query_spec.rb spec/spec_helper.rb lib/sql_tree/tokenizer.rb lib/sql_tree/node/join.rb .gitignore lib/sql_tree/node/ordering.rb LICENSE spec/lib/matchers.rb lib/sql_tree/parser.rb sql_tree.gemspec spec/unit/tokenizer_spec.rb spec/unit/expression_node_spec.rb spec/unit/delete_query_spec.rb spec/unit/leaf_node_spec.rb lib/sql_tree/token.rb lib/sql_tree/node/table_reference.rb lib/sql_tree/node/source.rb lib/sql_tree/node/insert_query.rb Rakefile tasks/github-gem.rake spec/unit/update_query_spec.rb spec/integration/parse_and_generate_spec.rb lib/sql_tree/node/select_query.rb lib/sql_tree/node.rb README.rdoc spec/integration/api_spec.rb lib/sql_tree/node/expression.rb lib/sql_tree/node/delete_query.rb lib/sql_tree/node/select_declaration.rb lib/sql_tree.rb lib/sql_tree/node/update_query.rb)
|
26
26
|
s.test_files = %w(spec/unit/select_query_spec.rb spec/unit/insert_query_spec.rb spec/unit/tokenizer_spec.rb spec/unit/expression_node_spec.rb spec/unit/delete_query_spec.rb spec/unit/leaf_node_spec.rb spec/unit/update_query_spec.rb spec/integration/parse_and_generate_spec.rb spec/integration/api_spec.rb)
|
27
27
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sql_tree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Willem van Bergen
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-10-
|
12
|
+
date: 2009-10-17 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -26,7 +26,6 @@ files:
|
|
26
26
|
- spec/unit/insert_query_spec.rb
|
27
27
|
- spec/spec_helper.rb
|
28
28
|
- lib/sql_tree/tokenizer.rb
|
29
|
-
- lib/sql_tree/node/variable.rb
|
30
29
|
- lib/sql_tree/node/join.rb
|
31
30
|
- .gitignore
|
32
31
|
- lib/sql_tree/node/ordering.rb
|
@@ -37,14 +36,11 @@ files:
|
|
37
36
|
- spec/unit/tokenizer_spec.rb
|
38
37
|
- spec/unit/expression_node_spec.rb
|
39
38
|
- spec/unit/delete_query_spec.rb
|
40
|
-
- lib/sql_tree/node/select_expression.rb
|
41
|
-
- lib/sql_tree/node/assignment.rb
|
42
39
|
- spec/unit/leaf_node_spec.rb
|
43
40
|
- lib/sql_tree/token.rb
|
44
41
|
- lib/sql_tree/node/table_reference.rb
|
45
42
|
- lib/sql_tree/node/source.rb
|
46
43
|
- lib/sql_tree/node/insert_query.rb
|
47
|
-
- lib/sql_tree/node/field.rb
|
48
44
|
- Rakefile
|
49
45
|
- tasks/github-gem.rake
|
50
46
|
- spec/unit/update_query_spec.rb
|
@@ -53,9 +49,9 @@ files:
|
|
53
49
|
- lib/sql_tree/node.rb
|
54
50
|
- README.rdoc
|
55
51
|
- spec/integration/api_spec.rb
|
56
|
-
- lib/sql_tree/node/value.rb
|
57
52
|
- lib/sql_tree/node/expression.rb
|
58
53
|
- lib/sql_tree/node/delete_query.rb
|
54
|
+
- lib/sql_tree/node/select_declaration.rb
|
59
55
|
- lib/sql_tree.rb
|
60
56
|
- lib/sql_tree/node/update_query.rb
|
61
57
|
has_rdoc: true
|
@@ -87,7 +83,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
87
83
|
requirements: []
|
88
84
|
|
89
85
|
rubyforge_project:
|
90
|
-
rubygems_version: 1.3.
|
86
|
+
rubygems_version: 1.3.4
|
91
87
|
signing_key:
|
92
88
|
specification_version: 3
|
93
89
|
summary: A pure Ruby library to represent SQL queries with a syntax tree for inspection and modification.
|
@@ -1,22 +0,0 @@
|
|
1
|
-
module SQLTree::Node
|
2
|
-
|
3
|
-
class Assignment < Base
|
4
|
-
|
5
|
-
attr_accessor :field, :expression
|
6
|
-
|
7
|
-
def initialize(field, expression = nil)
|
8
|
-
@field, @expression = field, expression
|
9
|
-
end
|
10
|
-
|
11
|
-
def to_sql
|
12
|
-
"#{quote_var(field)} = #{expression.to_sql}"
|
13
|
-
end
|
14
|
-
|
15
|
-
def self.parse(tokens)
|
16
|
-
assignment = self.new(SQLTree::Node::Variable.parse(tokens).name)
|
17
|
-
tokens.consume(SQLTree::Token::EQ)
|
18
|
-
assignment.expression = SQLTree::Node::Expression.parse(tokens)
|
19
|
-
assignment
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
data/lib/sql_tree/node/field.rb
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
module SQLTree::Node
|
2
|
-
|
3
|
-
class Field < Base
|
4
|
-
|
5
|
-
attr_accessor :name, :table
|
6
|
-
|
7
|
-
alias :field :name
|
8
|
-
alias :field= :name=
|
9
|
-
|
10
|
-
def initialize(name, table = nil)
|
11
|
-
@name = name
|
12
|
-
@table = table
|
13
|
-
end
|
14
|
-
|
15
|
-
def quote_var(name)
|
16
|
-
return '*' if name == :all
|
17
|
-
super(name)
|
18
|
-
end
|
19
|
-
|
20
|
-
def to_sql
|
21
|
-
@table.nil? ? quote_var(@name) : quote_var(@table) + '.' + quote_var(@name)
|
22
|
-
end
|
23
|
-
|
24
|
-
def ==(other)
|
25
|
-
other.name == self.name && other.table == self.table
|
26
|
-
end
|
27
|
-
|
28
|
-
def self.parse(tokens)
|
29
|
-
field_or_table = case tokens.next
|
30
|
-
when SQLTree::Token::MULTIPLY then :all
|
31
|
-
when SQLTree::Token::Variable then tokens.current.literal
|
32
|
-
else raise SQLTree::Parser::UnexpectedToken.new(tokens.current)
|
33
|
-
end
|
34
|
-
|
35
|
-
if tokens.peek == SQLTree::Token::DOT
|
36
|
-
table = field_or_table
|
37
|
-
tokens.consume(SQLTree::Token::DOT)
|
38
|
-
field = case tokens.next
|
39
|
-
when SQLTree::Token::MULTIPLY then :all
|
40
|
-
when SQLTree::Token::Variable then tokens.current.literal
|
41
|
-
else raise SQLTree::Parser::UnexpectedToken.new(tokens.current)
|
42
|
-
end
|
43
|
-
self.new(field, table)
|
44
|
-
else
|
45
|
-
self.new(field_or_table)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
module SQLTree::Node
|
2
|
-
|
3
|
-
class SelectExpression < Base
|
4
|
-
|
5
|
-
attr_accessor :expression, :variable
|
6
|
-
|
7
|
-
def initialize(expression, variable = nil)
|
8
|
-
@expression = expression
|
9
|
-
@variable = variable
|
10
|
-
end
|
11
|
-
|
12
|
-
def to_sql
|
13
|
-
sql = @expression.to_sql
|
14
|
-
sql << " AS " << quote_var(@variable) if @variable
|
15
|
-
return sql
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.parse(tokens)
|
19
|
-
if tokens.peek == SQLTree::Token::MULTIPLY
|
20
|
-
tokens.consume(SQLTree::Token::MULTIPLY)
|
21
|
-
return SQLTree::Node::ALL_FIELDS
|
22
|
-
else
|
23
|
-
expression = SQLTree::Node::Expression.parse(tokens)
|
24
|
-
expr = SQLTree::Node::SelectExpression.new(expression)
|
25
|
-
if tokens.peek == SQLTree::Token::AS
|
26
|
-
tokens.consume(SQLTree::Token::AS)
|
27
|
-
expr.variable = SQLTree::Node::Variable.parse(tokens).name
|
28
|
-
end
|
29
|
-
return expr
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def ==(other)
|
34
|
-
other.expression == self.expression && other.variable == self.variable
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
class AllFieldsExpression < Expression
|
39
|
-
def to_sql
|
40
|
-
'*'
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
ALL_FIELDS = AllFieldsExpression.new
|
45
|
-
end
|