sql_tree 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|