rgviz 0.45 → 0.46
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/rgviz/lexer.rb +4 -3
- data/lib/rgviz/memory_executor.rb +6 -2
- data/lib/rgviz/nodes.rb +2 -0
- data/lib/rgviz/parser.rb +7 -6
- data/lib/rgviz/token.rb +7 -5
- data/spec/rgviz/lexer_spec.rb +21 -20
- data/spec/rgviz/parser_spec.rb +72 -70
- metadata +2 -2
data/lib/rgviz/lexer.rb
CHANGED
@@ -2,10 +2,9 @@ require 'strscan'
|
|
2
2
|
|
3
3
|
module Rgviz
|
4
4
|
class Lexer < StringScanner
|
5
|
-
def initialize(str
|
5
|
+
def initialize(str)
|
6
6
|
super
|
7
7
|
@token = Token.new
|
8
|
-
@extensions = options[:extensions]
|
9
8
|
end
|
10
9
|
|
11
10
|
def next_token
|
@@ -50,7 +49,7 @@ module Rgviz
|
|
50
49
|
elsif scan /asc\b/i then Token::Asc
|
51
50
|
elsif scan /avg\b/i then Token::Avg
|
52
51
|
elsif scan /by\b/i then Token::By
|
53
|
-
elsif
|
52
|
+
elsif scan /concat\b/i then Token::Concat
|
54
53
|
elsif scan /contains\b/i then Token::Contains
|
55
54
|
elsif scan /count\b/i then Token::Count
|
56
55
|
elsif scan /date\b/i then Token::Date
|
@@ -61,6 +60,7 @@ module Rgviz
|
|
61
60
|
elsif scan /desc\b/i then Token::Desc
|
62
61
|
elsif scan /ends\b/i then Token::Ends
|
63
62
|
elsif scan /false\b/i then Token::False
|
63
|
+
elsif scan /floor\b/i then Token::Floor
|
64
64
|
elsif scan /format\b/i then Token::Format
|
65
65
|
elsif scan /group\b/i then Token::Group
|
66
66
|
elsif scan /hour\b/i then Token::Hour
|
@@ -86,6 +86,7 @@ module Rgviz
|
|
86
86
|
elsif scan /order\b/i then Token::Order
|
87
87
|
elsif scan /pivot\b/i then Token::Pivot
|
88
88
|
elsif scan /quarter\b/i then Token::Quarter
|
89
|
+
elsif scan /round\b/i then Token::Round
|
89
90
|
elsif scan /second\b/i then Token::Second
|
90
91
|
elsif scan /select\b/i then Token::Select
|
91
92
|
elsif scan /starts\b/i then Token::Starts
|
@@ -12,9 +12,9 @@ module Rgviz
|
|
12
12
|
@labels = {}
|
13
13
|
end
|
14
14
|
|
15
|
-
def execute(query
|
15
|
+
def execute(query)
|
16
16
|
@query = query
|
17
|
-
@query = Parser.parse(@query
|
17
|
+
@query = Parser.parse(@query) unless @query.kind_of?(Query)
|
18
18
|
@table = Table.new
|
19
19
|
|
20
20
|
process_labels
|
@@ -454,6 +454,10 @@ module Rgviz
|
|
454
454
|
@value = val1.sec
|
455
455
|
when ScalarFunctionColumn::Quarter
|
456
456
|
@value = (val1.month / 3.0).ceil
|
457
|
+
when ScalarFunctionColumn::Round
|
458
|
+
@value = val1.round
|
459
|
+
when ScalarFunctionColumn::Floor
|
460
|
+
@value = val1.floor
|
457
461
|
when ScalarFunctionColumn::Millisecond
|
458
462
|
raise "Millisecond is not implemented"
|
459
463
|
when ScalarFunctionColumn::Lower
|
data/lib/rgviz/nodes.rb
CHANGED
data/lib/rgviz/parser.rb
CHANGED
@@ -3,14 +3,14 @@ require 'date'
|
|
3
3
|
|
4
4
|
module Rgviz
|
5
5
|
class Parser < Lexer
|
6
|
-
def initialize(string
|
6
|
+
def initialize(string)
|
7
7
|
super
|
8
8
|
@query = Query.new
|
9
9
|
next_token
|
10
10
|
end
|
11
11
|
|
12
|
-
def self.parse(string
|
13
|
-
Parser.new(string
|
12
|
+
def self.parse(string)
|
13
|
+
Parser.new(string).parse
|
14
14
|
end
|
15
15
|
|
16
16
|
def parse
|
@@ -386,7 +386,8 @@ module Rgviz
|
|
386
386
|
when Token::Year, Token::Month, Token::Day,
|
387
387
|
Token::Hour, Token::Minute, Token::Second, Token::Millisecond,
|
388
388
|
Token::Now, Token::DateDiff, Token::Lower, Token::Upper,
|
389
|
-
Token::Quarter, Token::DayOfWeek, Token::ToDate, Token::Concat
|
389
|
+
Token::Quarter, Token::DayOfWeek, Token::ToDate, Token::Concat,
|
390
|
+
Token::Round,Token::Floor
|
390
391
|
function = @token.value
|
391
392
|
string = @token.string
|
392
393
|
next_token
|
@@ -428,12 +429,12 @@ module Rgviz
|
|
428
429
|
check *token_values
|
429
430
|
next_token
|
430
431
|
end
|
431
|
-
|
432
|
+
|
432
433
|
protected
|
433
434
|
def parse_date(date_string)
|
434
435
|
Date.parse(date_string)
|
435
436
|
end
|
436
|
-
|
437
|
+
|
437
438
|
def parse_time(time_string)
|
438
439
|
Time.parse(time_string)
|
439
440
|
end
|
data/lib/rgviz/token.rb
CHANGED
@@ -16,6 +16,7 @@ module Rgviz
|
|
16
16
|
DayOfWeek = :dayOfWeek
|
17
17
|
Ends = :ends
|
18
18
|
False = :false
|
19
|
+
Floor = :floor
|
19
20
|
Format = :format
|
20
21
|
Group = :group
|
21
22
|
Hour = :hour
|
@@ -41,6 +42,7 @@ module Rgviz
|
|
41
42
|
Order = :order
|
42
43
|
Pivot = :pivot
|
43
44
|
Quarter = :quarter
|
45
|
+
Round = :round
|
44
46
|
Second = :second
|
45
47
|
Select = :select
|
46
48
|
Starts = :starts
|
@@ -53,17 +55,17 @@ module Rgviz
|
|
53
55
|
Where = :where
|
54
56
|
With = :with
|
55
57
|
Year = :year
|
56
|
-
|
58
|
+
|
57
59
|
ID = :ID
|
58
60
|
INTEGER = :INTEGER
|
59
61
|
DECIMAL = :DECIMAL
|
60
62
|
STRING = :STRING
|
61
|
-
|
63
|
+
|
62
64
|
PLUS = :'+'
|
63
65
|
MINUS = :'-'
|
64
66
|
STAR = :'*'
|
65
67
|
SLASH = :'/'
|
66
|
-
|
68
|
+
|
67
69
|
COMMA = :','
|
68
70
|
LPAREN = :'('
|
69
71
|
RPAREN = :')'
|
@@ -73,9 +75,9 @@ module Rgviz
|
|
73
75
|
GT = :'>'
|
74
76
|
GTE = :'>='
|
75
77
|
NEQ = :'!='
|
76
|
-
|
78
|
+
|
77
79
|
EOF = :'<EOF>'
|
78
|
-
|
80
|
+
|
79
81
|
attr_accessor :start
|
80
82
|
attr_accessor :value
|
81
83
|
attr_accessor :string
|
data/spec/rgviz/lexer_spec.rb
CHANGED
@@ -3,20 +3,20 @@ require 'rgviz'
|
|
3
3
|
include Rgviz
|
4
4
|
|
5
5
|
describe Lexer do
|
6
|
-
def self.it_lexes_keyword(str, token_value
|
6
|
+
def self.it_lexes_keyword(str, token_value)
|
7
7
|
it "lexes #{str}" do
|
8
|
-
lex = Lexer.new str
|
8
|
+
lex = Lexer.new str
|
9
9
|
tok = lex.next_token
|
10
10
|
tok.value.should == token_value
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
it "lexes #{str} upcase" do
|
14
|
-
lex = Lexer.new str.upcase
|
14
|
+
lex = Lexer.new str.upcase
|
15
15
|
tok = lex.next_token
|
16
16
|
tok.value.should == token_value
|
17
17
|
end
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
def self.it_lexes_id(str, id = str)
|
21
21
|
it "lexes identifier #{str}" do
|
22
22
|
lex = Lexer.new str
|
@@ -25,7 +25,7 @@ describe Lexer do
|
|
25
25
|
tok.string.should == id
|
26
26
|
end
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
def self.it_lexes_string(str, id = str)
|
30
30
|
it "lexes string #{str}" do
|
31
31
|
lex = Lexer.new str
|
@@ -34,7 +34,7 @@ describe Lexer do
|
|
34
34
|
tok.string.should == id
|
35
35
|
end
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
def self.it_lexes_token(str, token_value)
|
39
39
|
it "lexes #{str}" do
|
40
40
|
lex = Lexer.new str
|
@@ -42,7 +42,7 @@ describe Lexer do
|
|
42
42
|
tok.value.should == token_value
|
43
43
|
end
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
def self.it_lexes_integer(str, number)
|
47
47
|
it "lexes #{str}" do
|
48
48
|
lex = Lexer.new str
|
@@ -51,7 +51,7 @@ describe Lexer do
|
|
51
51
|
tok.number.should == number
|
52
52
|
end
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
55
|
def self.it_lexes_decimal(str, number)
|
56
56
|
it "lexes #{str}" do
|
57
57
|
lex = Lexer.new str
|
@@ -60,7 +60,7 @@ describe Lexer do
|
|
60
60
|
tok.number.should == number
|
61
61
|
end
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
64
|
def self.it_lexes_eof(str)
|
65
65
|
it "lexes eof #{str}" do
|
66
66
|
lex = Lexer.new str
|
@@ -68,7 +68,7 @@ describe Lexer do
|
|
68
68
|
tok.value.should == Token::EOF
|
69
69
|
end
|
70
70
|
end
|
71
|
-
|
71
|
+
|
72
72
|
def self.it_lexes_error(str)
|
73
73
|
it "lexes error #{str}" do
|
74
74
|
lex = Lexer.new "x#{str}"
|
@@ -78,7 +78,7 @@ describe Lexer do
|
|
78
78
|
lambda { lex.next_token }.should raise_error(ParseException)
|
79
79
|
end
|
80
80
|
end
|
81
|
-
|
81
|
+
|
82
82
|
it_lexes_keyword 'and', Token::And
|
83
83
|
it_lexes_keyword 'asc', Token::Asc
|
84
84
|
it_lexes_keyword 'avg', Token::Avg
|
@@ -130,7 +130,7 @@ describe Lexer do
|
|
130
130
|
it_lexes_keyword 'where', Token::Where
|
131
131
|
it_lexes_keyword 'with', Token::With
|
132
132
|
it_lexes_keyword 'year', Token::Year
|
133
|
-
|
133
|
+
|
134
134
|
it_lexes_id 'selected'
|
135
135
|
it_lexes_id ' selected ', 'selected'
|
136
136
|
it_lexes_id '`selected`', 'selected'
|
@@ -139,12 +139,12 @@ describe Lexer do
|
|
139
139
|
it_lexes_id 'hello_123_bye'
|
140
140
|
it_lexes_string "'hello world'", "hello world"
|
141
141
|
it_lexes_string '"hello world"', "hello world"
|
142
|
-
|
142
|
+
|
143
143
|
it_lexes_token '+', Token::PLUS
|
144
144
|
it_lexes_token '-', Token::MINUS
|
145
145
|
it_lexes_token '*', Token::STAR
|
146
146
|
it_lexes_token '/', Token::SLASH
|
147
|
-
|
147
|
+
|
148
148
|
it_lexes_token ',', Token::COMMA
|
149
149
|
it_lexes_token '(', Token::LPAREN
|
150
150
|
it_lexes_token ')', Token::RPAREN
|
@@ -155,20 +155,21 @@ describe Lexer do
|
|
155
155
|
it_lexes_token '>=', Token::GTE
|
156
156
|
it_lexes_token '!=', Token::NEQ
|
157
157
|
it_lexes_token '<>', Token::NEQ
|
158
|
-
|
158
|
+
|
159
159
|
it_lexes_integer '1', 1
|
160
160
|
it_lexes_integer '0123', 123
|
161
161
|
it_lexes_integer '45678791230', 45678791230
|
162
162
|
it_lexes_decimal '123.456', 123.456
|
163
163
|
it_lexes_decimal '.456', 0.456
|
164
|
-
|
164
|
+
|
165
165
|
it_lexes_eof ''
|
166
166
|
it_lexes_eof " \t\n\r"
|
167
|
-
|
167
|
+
|
168
168
|
it_lexes_error '!'
|
169
169
|
it_lexes_error '?'
|
170
170
|
it_lexes_error ':'
|
171
171
|
|
172
|
-
|
173
|
-
it_lexes_keyword '
|
172
|
+
it_lexes_keyword 'concat', Token::Concat
|
173
|
+
it_lexes_keyword 'round', Token::Round
|
174
|
+
it_lexes_keyword 'floor', Token::Floor
|
174
175
|
end
|
data/spec/rgviz/parser_spec.rb
CHANGED
@@ -3,31 +3,31 @@ require 'rgviz'
|
|
3
3
|
include Rgviz
|
4
4
|
|
5
5
|
describe Parser do
|
6
|
-
def parse(string
|
7
|
-
Parser.parse(string
|
6
|
+
def parse(string)
|
7
|
+
Parser.parse(string)
|
8
8
|
end
|
9
9
|
|
10
|
-
def parse_select_single_column(string
|
11
|
-
query = parse "select #{string}"
|
10
|
+
def parse_select_single_column(string)
|
11
|
+
query = parse "select #{string}"
|
12
12
|
select = query.select
|
13
13
|
select.columns.length.should == 1
|
14
|
-
|
14
|
+
|
15
15
|
select.columns[0]
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
def parse_where(string)
|
19
19
|
query = parse "where #{string}"
|
20
20
|
query.where.expression
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
def self.it_parses_as_identifier(str)
|
24
24
|
it "parses #{str} as identifier" do
|
25
|
-
col = parse_select_single_column "#{str}"
|
25
|
+
col = parse_select_single_column "#{str}"
|
26
26
|
col.should be_a_kind_of IdColumn
|
27
27
|
col.name.should == "#{str}"
|
28
28
|
end
|
29
29
|
end
|
30
|
-
|
30
|
+
|
31
31
|
def self.it_parses_columns_container(str, method)
|
32
32
|
it "parses #{str}" do
|
33
33
|
query = parse "#{str} foo"
|
@@ -37,7 +37,7 @@ describe Parser do
|
|
37
37
|
cols.columns[0].name.should == 'foo'
|
38
38
|
end
|
39
39
|
end
|
40
|
-
|
40
|
+
|
41
41
|
def self.it_raises_on(str)
|
42
42
|
it "raises on #{str}" do
|
43
43
|
lambda { parse "#{str}" }.should raise_error(ParseException)
|
@@ -54,81 +54,81 @@ describe Parser do
|
|
54
54
|
select = query.select
|
55
55
|
select.columns.should be_empty
|
56
56
|
end
|
57
|
-
|
57
|
+
|
58
58
|
it "parses select simple columns" do
|
59
59
|
query = parse 'select one, two, three'
|
60
60
|
select = query.select
|
61
|
-
|
61
|
+
|
62
62
|
select.columns.length.should == 3
|
63
|
-
|
63
|
+
|
64
64
|
['one', 'two', 'three'].each_with_index do |name, i|
|
65
65
|
select.columns[i].should be_a_kind_of IdColumn
|
66
66
|
select.columns[i].name.should == name
|
67
67
|
end
|
68
68
|
end
|
69
|
-
|
69
|
+
|
70
70
|
it "parses select number" do
|
71
71
|
col = parse_select_single_column '1'
|
72
72
|
col.should be_a_kind_of NumberColumn
|
73
73
|
col.value.should == 1
|
74
74
|
end
|
75
|
-
|
75
|
+
|
76
76
|
it "parses select number with minus" do
|
77
77
|
col = parse_select_single_column '-1'
|
78
78
|
col.should be_a_kind_of NumberColumn
|
79
79
|
col.value.should == -1
|
80
80
|
end
|
81
|
-
|
81
|
+
|
82
82
|
it "parses select number with plus" do
|
83
83
|
col = parse_select_single_column '+1'
|
84
84
|
col.should be_a_kind_of NumberColumn
|
85
85
|
col.value.should == 1
|
86
86
|
end
|
87
|
-
|
87
|
+
|
88
88
|
it "parses select parenthesized number" do
|
89
89
|
col = parse_select_single_column '(1)'
|
90
90
|
col.should be_a_kind_of NumberColumn
|
91
91
|
col.value.should == 1
|
92
92
|
end
|
93
|
-
|
93
|
+
|
94
94
|
it "parses select string" do
|
95
95
|
col = parse_select_single_column '"hello"'
|
96
96
|
col.should be_a_kind_of StringColumn
|
97
97
|
col.value.should == 'hello'
|
98
98
|
end
|
99
|
-
|
99
|
+
|
100
100
|
it "parses select false" do
|
101
101
|
col = parse_select_single_column 'false'
|
102
102
|
col.should be_a_kind_of BooleanColumn
|
103
103
|
col.value.should == false
|
104
104
|
end
|
105
|
-
|
105
|
+
|
106
106
|
it "parses select true" do
|
107
107
|
col = parse_select_single_column 'true'
|
108
108
|
col.should be_a_kind_of BooleanColumn
|
109
109
|
col.value.should == true
|
110
110
|
end
|
111
|
-
|
111
|
+
|
112
112
|
it "parses select date" do
|
113
|
-
col = parse_select_single_column 'date "2010-01-02"'
|
113
|
+
col = parse_select_single_column 'date "2010-01-02"'
|
114
114
|
col.should be_a_kind_of DateColumn
|
115
115
|
col.value.should == Date.parse('2010-01-02')
|
116
116
|
end
|
117
|
-
|
117
|
+
|
118
118
|
it "parses select timeofday" do
|
119
|
-
col = parse_select_single_column 'timeofday "12:01:02"'
|
119
|
+
col = parse_select_single_column 'timeofday "12:01:02"'
|
120
120
|
col.should be_a_kind_of TimeOfDayColumn
|
121
121
|
col.value.hour.should == 12
|
122
122
|
col.value.min.should == 1
|
123
123
|
col.value.sec.should == 2
|
124
124
|
end
|
125
|
-
|
125
|
+
|
126
126
|
it "parses select datetime" do
|
127
|
-
col = parse_select_single_column 'datetime "2010-01-02 12:02:03"'
|
127
|
+
col = parse_select_single_column 'datetime "2010-01-02 12:02:03"'
|
128
128
|
col.should be_a_kind_of DateTimeColumn
|
129
129
|
col.value.should == Time.parse('2010-01-02 12:02:03')
|
130
130
|
end
|
131
|
-
|
131
|
+
|
132
132
|
[
|
133
133
|
['*', ScalarFunctionColumn::Product],
|
134
134
|
['/', ScalarFunctionColumn::Quotient],
|
@@ -139,25 +139,25 @@ describe Parser do
|
|
139
139
|
col = parse_select_single_column "1 #{str} one"
|
140
140
|
col.should be_a_kind_of ScalarFunctionColumn
|
141
141
|
col.function.should == func
|
142
|
-
|
143
|
-
args = col.arguments
|
142
|
+
|
143
|
+
args = col.arguments
|
144
144
|
args.length.should == 2
|
145
|
-
|
145
|
+
|
146
146
|
args[0].should be_a_kind_of NumberColumn
|
147
147
|
args[0].value.should == 1
|
148
|
-
|
148
|
+
|
149
149
|
args[1].should be_a_kind_of IdColumn
|
150
150
|
args[1].name.should == "one"
|
151
151
|
end
|
152
152
|
end
|
153
|
-
|
153
|
+
|
154
154
|
it "parses compound arithmetic" do
|
155
155
|
col = parse_select_single_column "1 * 2 + 3 * 4"
|
156
156
|
col.should be_kind_of ScalarFunctionColumn
|
157
157
|
col.function.should == ScalarFunctionColumn::Sum
|
158
|
-
|
158
|
+
|
159
159
|
col.arguments.length.should == 2
|
160
|
-
|
160
|
+
|
161
161
|
[0, 1].each do |i|
|
162
162
|
sub = col.arguments[i]
|
163
163
|
sub.should be_kind_of ScalarFunctionColumn
|
@@ -165,7 +165,7 @@ describe Parser do
|
|
165
165
|
sub.arguments.length.should == 2
|
166
166
|
end
|
167
167
|
end
|
168
|
-
|
168
|
+
|
169
169
|
[
|
170
170
|
['min', AggregateColumn::Min],
|
171
171
|
['max', AggregateColumn::Max],
|
@@ -174,17 +174,17 @@ describe Parser do
|
|
174
174
|
['sum', AggregateColumn::Sum]
|
175
175
|
].each do |str, function|
|
176
176
|
it "parses #{str} aggregation" do
|
177
|
-
col = parse_select_single_column "#{str}(col)"
|
177
|
+
col = parse_select_single_column "#{str}(col)"
|
178
178
|
col.should be_a_kind_of AggregateColumn
|
179
179
|
col.function.should == function
|
180
|
-
|
180
|
+
|
181
181
|
col.argument.should be_a_kind_of IdColumn
|
182
182
|
col.argument.name.should == 'col'
|
183
183
|
end
|
184
|
-
|
184
|
+
|
185
185
|
it_parses_as_identifier str
|
186
186
|
end
|
187
|
-
|
187
|
+
|
188
188
|
[
|
189
189
|
['year', ScalarFunctionColumn::Year],
|
190
190
|
['month', ScalarFunctionColumn::Month],
|
@@ -200,31 +200,33 @@ describe Parser do
|
|
200
200
|
['quarter', ScalarFunctionColumn::Quarter],
|
201
201
|
['dayofweek', ScalarFunctionColumn::DayOfWeek],
|
202
202
|
['todate', ScalarFunctionColumn::ToDate],
|
203
|
-
['concat', ScalarFunctionColumn::Concat
|
204
|
-
|
203
|
+
['concat', ScalarFunctionColumn::Concat],
|
204
|
+
['round', ScalarFunctionColumn::Round],
|
205
|
+
['floor', ScalarFunctionColumn::Floor]
|
206
|
+
].each do |str, function|
|
205
207
|
it "parses #{str} function" do
|
206
|
-
col = parse_select_single_column "#{str}(col)"
|
208
|
+
col = parse_select_single_column "#{str}(col)"
|
207
209
|
col.should be_a_kind_of ScalarFunctionColumn
|
208
210
|
col.function.should == function
|
209
|
-
|
211
|
+
|
210
212
|
col.arguments.length.should == 1
|
211
213
|
col.arguments[0].should be_a_kind_of IdColumn
|
212
214
|
col.arguments[0].name.should == 'col'
|
213
215
|
end
|
214
|
-
|
216
|
+
|
215
217
|
it_parses_as_identifier str
|
216
218
|
end
|
217
|
-
|
219
|
+
|
218
220
|
it "parses datediff function with many arguments" do
|
219
|
-
col = parse_select_single_column "datediff(1, 2)"
|
221
|
+
col = parse_select_single_column "datediff(1, 2)"
|
220
222
|
col.should be_a_kind_of ScalarFunctionColumn
|
221
223
|
col.function.should == ScalarFunctionColumn::DateDiff
|
222
|
-
|
224
|
+
|
223
225
|
col.arguments.length.should == 2
|
224
226
|
col.arguments[0].value == 1
|
225
227
|
col.arguments[1].value == 2
|
226
228
|
end
|
227
|
-
|
229
|
+
|
228
230
|
[
|
229
231
|
['=', BinaryExpression::Eq],
|
230
232
|
['!=', BinaryExpression::Neq],
|
@@ -249,7 +251,7 @@ describe Parser do
|
|
249
251
|
exp.right.value.should == 1
|
250
252
|
end
|
251
253
|
end
|
252
|
-
|
254
|
+
|
253
255
|
it_parses_as_identifier 'contains'
|
254
256
|
it_parses_as_identifier 'starts'
|
255
257
|
it_parses_as_identifier 'ends'
|
@@ -260,10 +262,10 @@ describe Parser do
|
|
260
262
|
it_parses_as_identifier 'no_format'
|
261
263
|
it_parses_as_identifier 'is'
|
262
264
|
it_parses_as_identifier 'null'
|
263
|
-
|
265
|
+
|
264
266
|
it_parses_columns_container 'group by', :group_by
|
265
267
|
it_parses_columns_container 'pivot', :pivot
|
266
|
-
|
268
|
+
|
267
269
|
[
|
268
270
|
['', Sort::Asc],
|
269
271
|
[' asc', Sort::Asc],
|
@@ -272,86 +274,86 @@ describe Parser do
|
|
272
274
|
it "parses order by" do
|
273
275
|
query = parse "order by foo #{order}, bar #{order}"
|
274
276
|
order_by = query.order_by
|
275
|
-
|
276
|
-
sorts = order_by.sorts
|
277
|
-
|
277
|
+
|
278
|
+
sorts = order_by.sorts
|
279
|
+
|
278
280
|
sorts.length.should == 2
|
279
|
-
|
281
|
+
|
280
282
|
sorts[0].column.should be_a_kind_of IdColumn
|
281
283
|
sorts[0].column.name.should == 'foo'
|
282
284
|
sorts[0].order.should == order
|
283
|
-
|
285
|
+
|
284
286
|
sorts[1].column.should be_a_kind_of IdColumn
|
285
287
|
sorts[1].column.name.should == 'bar'
|
286
288
|
sorts[1].order.should == order
|
287
289
|
end
|
288
290
|
end
|
289
|
-
|
291
|
+
|
290
292
|
it "parses limit" do
|
291
293
|
query = parse "limit 10"
|
292
294
|
query.limit.should == 10
|
293
295
|
end
|
294
|
-
|
296
|
+
|
295
297
|
it "parses offset" do
|
296
298
|
query = parse "offset 10"
|
297
299
|
query.offset.should == 10
|
298
300
|
end
|
299
|
-
|
301
|
+
|
300
302
|
it "parses label" do
|
301
303
|
query = parse "label one 'unu', two 'du'"
|
302
304
|
labels = query.labels
|
303
305
|
labels.length.should == 2
|
304
|
-
|
306
|
+
|
305
307
|
labels[0].column.should be_a_kind_of IdColumn
|
306
308
|
labels[0].column.name.should == 'one'
|
307
309
|
labels[0].label.should == 'unu'
|
308
|
-
|
310
|
+
|
309
311
|
labels[1].column.should be_a_kind_of IdColumn
|
310
312
|
labels[1].column.name.should == 'two'
|
311
313
|
labels[1].label.should == 'du'
|
312
314
|
end
|
313
|
-
|
315
|
+
|
314
316
|
it "parses format" do
|
315
317
|
query = parse "format one 'unu', two 'du'"
|
316
318
|
formats = query.formats
|
317
319
|
formats.length.should == 2
|
318
|
-
|
320
|
+
|
319
321
|
formats[0].column.should be_a_kind_of IdColumn
|
320
322
|
formats[0].column.name.should == 'one'
|
321
323
|
formats[0].pattern.should == 'unu'
|
322
|
-
|
324
|
+
|
323
325
|
formats[1].column.should be_a_kind_of IdColumn
|
324
326
|
formats[1].column.name.should == 'two'
|
325
327
|
formats[1].pattern.should == 'du'
|
326
328
|
end
|
327
|
-
|
329
|
+
|
328
330
|
it "parses options" do
|
329
331
|
query = parse "options no_values no_format"
|
330
332
|
options = query.options
|
331
333
|
options.no_values.should be_true
|
332
334
|
options.no_format.should be_true
|
333
335
|
end
|
334
|
-
|
336
|
+
|
335
337
|
[
|
336
338
|
['and', LogicalExpression::And],
|
337
339
|
['or', LogicalExpression::Or]
|
338
340
|
].each do |str, op|
|
339
341
|
it "parses where with two #{str}" do
|
340
342
|
query = parse "where 1 = 1 #{str} 1 = 2 #{str} 1 = 3"
|
341
|
-
exp = query.where.expression
|
342
|
-
|
343
|
+
exp = query.where.expression
|
344
|
+
|
343
345
|
exp.should be_a_kind_of LogicalExpression
|
344
346
|
exp.operator.should == op
|
345
347
|
exp.operands.length.should == 3
|
346
348
|
end
|
347
349
|
end
|
348
|
-
|
350
|
+
|
349
351
|
['+', '-', '*', '/'].each do |op|
|
350
352
|
it "parses where with two #{op}" do
|
351
353
|
parse "where 1 #{op} 2 #{op} 3 = 4"
|
352
354
|
end
|
353
355
|
end
|
354
|
-
|
356
|
+
|
355
357
|
it_raises_on 'select'
|
356
358
|
it_raises_on 'where'
|
357
359
|
it_raises_on 'where 1'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rgviz
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.46'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2010-06-08 00:00:00.
|
12
|
+
date: 2010-06-08 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Google Visualization API Query Language written in Ruby.
|
15
15
|
email: aborenszweig@manas.com.ar
|