aql 0.0.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.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/.rspec +1 -0
- data/.travis.yml +18 -0
- data/Gemfile +6 -0
- data/Gemfile.devtools +64 -0
- data/Guardfile +18 -0
- data/LICENSE +20 -0
- data/README.md +86 -0
- data/Rakefile +2 -0
- data/TODO +1 -0
- data/aql.gemspec +23 -0
- data/config/flay.yml +3 -0
- data/config/flog.yml +2 -0
- data/config/mutant.yml +3 -0
- data/config/roodi.yml +18 -0
- data/config/site.reek +100 -0
- data/config/yardstick.yml +2 -0
- data/examples/aql.rb +31 -0
- data/lib/aql.rb +62 -0
- data/lib/aql/buffer.rb +129 -0
- data/lib/aql/constants.rb +19 -0
- data/lib/aql/node.rb +45 -0
- data/lib/aql/node/attribute.rb +25 -0
- data/lib/aql/node/block.rb +28 -0
- data/lib/aql/node/call.rb +83 -0
- data/lib/aql/node/literal.rb +48 -0
- data/lib/aql/node/literal/composed.rb +10 -0
- data/lib/aql/node/literal/composed/document.rb +59 -0
- data/lib/aql/node/literal/composed/list.rb +42 -0
- data/lib/aql/node/literal/primitive.rb +10 -0
- data/lib/aql/node/literal/primitive/number.rb +28 -0
- data/lib/aql/node/literal/primitive/string.rb +27 -0
- data/lib/aql/node/literal/singleton.rb +51 -0
- data/lib/aql/node/name.rb +31 -0
- data/lib/aql/node/null.rb +21 -0
- data/lib/aql/node/operation.rb +20 -0
- data/lib/aql/node/operation/binary.rb +33 -0
- data/lib/aql/node/operation/for.rb +77 -0
- data/lib/aql/node/operation/limit.rb +42 -0
- data/lib/aql/node/operation/nary.rb +57 -0
- data/lib/aql/node/operation/unary.rb +75 -0
- data/lib/aql/node/operator.rb +20 -0
- data/lib/aql/node/operator/assignment.rb +28 -0
- data/lib/aql/node/operator/binary.rb +92 -0
- data/lib/aql/node/operator/nary.rb +48 -0
- data/lib/aql/node/operator/ternary.rb +30 -0
- data/lib/aql/node/operator/unary.rb +39 -0
- data/spec/shared/aql_behavior.rb +7 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/support/aql_helper.rb +12 -0
- data/spec/unit/aql/buffer/append_spec.rb +59 -0
- data/spec/unit/aql/buffer/binary_spec.rb +22 -0
- data/spec/unit/aql/buffer/class_methods/utf8_encode_spec.rb +21 -0
- data/spec/unit/aql/buffer/content_spec.rb +24 -0
- data/spec/unit/aql/buffer/delimited_spec.rb +31 -0
- data/spec/unit/aql/buffer/parentheses_spec.rb +33 -0
- data/spec/unit/aql/buffer/wrap_delimited_spec.rb +42 -0
- data/spec/unit/aql/class_methods/literal_node_spec.rb +15 -0
- data/spec/unit/aql/class_methods/name_node_spec.rb +19 -0
- data/spec/unit/aql/node/attribute/aql_spec.rb +22 -0
- data/spec/unit/aql/node/block/aql_spec.rb +28 -0
- data/spec/unit/aql/node/call/aql_spec.rb +39 -0
- data/spec/unit/aql/node/literal/class_methods/build_spec.rb +139 -0
- data/spec/unit/aql/node/literal/class_methods/construct_spec.rb +16 -0
- data/spec/unit/aql/node/literal/class_methods/handle_spec.rb +22 -0
- data/spec/unit/aql/node/literal/composed/document/aql_spec.rb +32 -0
- data/spec/unit/aql/node/literal/composed/document/attribute/aql_spec.rb +15 -0
- data/spec/unit/aql/node/literal/composed/document/class_methods/construct_spec.rb +24 -0
- data/spec/unit/aql/node/literal/composed/list/aql_spec.rb +20 -0
- data/spec/unit/aql/node/literal/composed/list/class_methods/construct_spec.rb +37 -0
- data/spec/unit/aql/node/literal/primitive/number/aql_spec.rb +23 -0
- data/spec/unit/aql/node/literal/primitive/string/aql_spec.rb +21 -0
- data/spec/unit/aql/node/literal/singleton/aql_spec.rb +14 -0
- data/spec/unit/aql/node/literal/singleton/class_methods/construct_spec.rb +30 -0
- data/spec/unit/aql/node/name/aql_spec.rb +33 -0
- data/spec/unit/aql/node/null/aql_spec.rb +7 -0
- data/spec/unit/aql/node/operation/binary/let/aql_spec.rb +10 -0
- data/spec/unit/aql/node/operation/for/aql_spec.rb +18 -0
- data/spec/unit/aql/node/operation/keyword_spec.rb +16 -0
- data/spec/unit/aql/node/operation/limit/aql_spec.rb +19 -0
- data/spec/unit/aql/node/operation/nary/aql_spec.rb +16 -0
- data/spec/unit/aql/node/operation/nary/collect/into/aql_spec.rb +11 -0
- data/spec/unit/aql/node/operation/nary/sort/aql_spec.rb +22 -0
- data/spec/unit/aql/node/operation/unary/aql_spec.rb +12 -0
- data/spec/unit/aql/node/operation/unary/direction/aql_spec.rb +14 -0
- data/spec/unit/aql/node/operation/unary/filter/aql_spec.rb +20 -0
- data/spec/unit/aql/node/operation/unary/return/aql_spec.rb +17 -0
- data/spec/unit/aql/node/operator/assignment/aql_spec.rb +10 -0
- data/spec/unit/aql/node/operator/binary/aql_spec.rb +15 -0
- data/spec/unit/aql/node/operator/nary/aql_spec.rb +31 -0
- data/spec/unit/aql/node/operator/operator_spec.rb +18 -0
- data/spec/unit/aql/node/operator/ternary/aql_spec.rb +12 -0
- data/spec/unit/aql/node/operator/unary/aql_spec.rb +12 -0
- data/spec/unit/aql/node/visit_spec.rb +27 -0
- metadata +262 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
module AQL
|
|
2
|
+
class Node
|
|
3
|
+
class Operation
|
|
4
|
+
# Base class for unary operations
|
|
5
|
+
class Unary < self
|
|
6
|
+
include Concord.new(:expression)
|
|
7
|
+
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
# Emit node
|
|
11
|
+
#
|
|
12
|
+
# @param [Buffer] buffer
|
|
13
|
+
#
|
|
14
|
+
# @return [undefined]
|
|
15
|
+
#
|
|
16
|
+
# @api private
|
|
17
|
+
#
|
|
18
|
+
def emit(buffer)
|
|
19
|
+
buffer.append("#{keyword} ")
|
|
20
|
+
expression.visit(buffer)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Return keyword
|
|
24
|
+
#
|
|
25
|
+
# @return [Symbol]
|
|
26
|
+
#
|
|
27
|
+
# @api private
|
|
28
|
+
#
|
|
29
|
+
def keyword
|
|
30
|
+
self.class::KEYWORD
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Filter operation
|
|
34
|
+
class Filter < self
|
|
35
|
+
KEYWORD = :FILTER
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Return operation
|
|
39
|
+
class Return < self
|
|
40
|
+
KEYWORD = :RETURN
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Abstract base class for sort orders
|
|
44
|
+
class Direction < self
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
# Emit node
|
|
49
|
+
#
|
|
50
|
+
# @param [Buffer] buffer
|
|
51
|
+
#
|
|
52
|
+
# @return [undefined]
|
|
53
|
+
#
|
|
54
|
+
# @api private
|
|
55
|
+
#
|
|
56
|
+
def emit(buffer)
|
|
57
|
+
expression.visit(buffer)
|
|
58
|
+
buffer.append(" #{keyword}")
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Asecnding sort direction
|
|
62
|
+
class Ascending < self
|
|
63
|
+
KEYWORD = :ASC
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Descending sort direction
|
|
67
|
+
class Descending < self
|
|
68
|
+
KEYWORD = :DESC
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module AQL
|
|
2
|
+
class Node
|
|
3
|
+
class Operator
|
|
4
|
+
# Assignment operator
|
|
5
|
+
class Assignment < self
|
|
6
|
+
include Concord.new(:name, :value)
|
|
7
|
+
SYMBOL = :'='
|
|
8
|
+
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
# Emit into buffer
|
|
12
|
+
#
|
|
13
|
+
# @param [Buffer] buffer
|
|
14
|
+
#
|
|
15
|
+
# @return [undefined]
|
|
16
|
+
#
|
|
17
|
+
# @api private
|
|
18
|
+
#
|
|
19
|
+
def emit(buffer)
|
|
20
|
+
name.visit(buffer)
|
|
21
|
+
buffer.append(" #{SYMBOL} ")
|
|
22
|
+
value.visit(buffer)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
module AQL
|
|
2
|
+
class Node
|
|
3
|
+
class Operator
|
|
4
|
+
# Base class for binary operators
|
|
5
|
+
class Binary < self
|
|
6
|
+
include Concord.new(:left, :right)
|
|
7
|
+
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
# Emit node
|
|
11
|
+
#
|
|
12
|
+
# @return [undefined]
|
|
13
|
+
#
|
|
14
|
+
# @api private
|
|
15
|
+
#
|
|
16
|
+
def emit(buffer)
|
|
17
|
+
buffer.binary(left, operator, right)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Binary equality operator
|
|
21
|
+
class Equality < self
|
|
22
|
+
SYMBOL = :==
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Binary inequality operator
|
|
26
|
+
class Inequality < self
|
|
27
|
+
SYMBOL = :'!='
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Binary or operator
|
|
31
|
+
class Or < self
|
|
32
|
+
SYMBOL = :'||'
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Binary and operator
|
|
36
|
+
class And < self
|
|
37
|
+
SYMBOL = :'&&'
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Binary in operator
|
|
41
|
+
class In < self
|
|
42
|
+
SYMBOL = :'IN'
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Binary less than operator
|
|
46
|
+
class LessThan < self
|
|
47
|
+
SYMBOL = :'<'
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Binary less than or equal to operator
|
|
51
|
+
class LessThanOrEqualTo < self
|
|
52
|
+
SYMBOL = :'<='
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Binary greater than operator
|
|
56
|
+
class GreaterThan < self
|
|
57
|
+
SYMBOL = :'>'
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Binary greater than or equal to operator
|
|
61
|
+
class GreaterThanOrEqualTo < self
|
|
62
|
+
SYMBOL = :'>='
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Binary addition operator
|
|
66
|
+
class Addition < self
|
|
67
|
+
SYMBOL = :+
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Binary subtraction operator
|
|
71
|
+
class Subtraction < self
|
|
72
|
+
SYMBOL = :-
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Binary multiplication operator
|
|
76
|
+
class Multiplication < self
|
|
77
|
+
SYMBOL = :*
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Binary division operator
|
|
81
|
+
class Division < self
|
|
82
|
+
SYMBOL = :/
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Binary modulo operator
|
|
86
|
+
class Modulo < self
|
|
87
|
+
SYMBOL = :%
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module AQL
|
|
2
|
+
class Node
|
|
3
|
+
class Operator
|
|
4
|
+
# Base class for n-ary operators
|
|
5
|
+
class Nary < self
|
|
6
|
+
include Concord.new(:body)
|
|
7
|
+
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
# Emit node
|
|
11
|
+
#
|
|
12
|
+
# @return [undefined]
|
|
13
|
+
#
|
|
14
|
+
# @api private
|
|
15
|
+
#
|
|
16
|
+
def emit(buffer)
|
|
17
|
+
local = body
|
|
18
|
+
if local.length == 1
|
|
19
|
+
local.first.visit(buffer)
|
|
20
|
+
return
|
|
21
|
+
end
|
|
22
|
+
emit_body(buffer)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Emit body
|
|
26
|
+
#
|
|
27
|
+
# @rteturn [undefined]
|
|
28
|
+
#
|
|
29
|
+
# @api private
|
|
30
|
+
#
|
|
31
|
+
def emit_body(buffer)
|
|
32
|
+
buffer.parentheses do
|
|
33
|
+
buffer.delimited(body, " #{self.class::SYMBOL} ")
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Nary and operator
|
|
38
|
+
#
|
|
39
|
+
# Only present to ease generation of join filters.
|
|
40
|
+
#
|
|
41
|
+
class And < self
|
|
42
|
+
SYMBOL = :'&&'
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module AQL
|
|
2
|
+
class Node
|
|
3
|
+
class Operator
|
|
4
|
+
# Ternary operator
|
|
5
|
+
class Ternary < self
|
|
6
|
+
include Concord.new(:condition, :left, :right)
|
|
7
|
+
|
|
8
|
+
SYMBOL = :'?'
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
# Emit node
|
|
13
|
+
#
|
|
14
|
+
# @param [Buffer] buffer
|
|
15
|
+
#
|
|
16
|
+
# @return [undefined]
|
|
17
|
+
#
|
|
18
|
+
# @api private
|
|
19
|
+
#
|
|
20
|
+
def emit(buffer)
|
|
21
|
+
condition.visit(buffer)
|
|
22
|
+
buffer.append(" #{operator} ")
|
|
23
|
+
left.visit(buffer)
|
|
24
|
+
buffer.append(' : ')
|
|
25
|
+
right.visit(buffer)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module AQL
|
|
2
|
+
class Node
|
|
3
|
+
class Operator
|
|
4
|
+
# Base class for unary operators
|
|
5
|
+
class Unary < self
|
|
6
|
+
include Concord.new(:target)
|
|
7
|
+
|
|
8
|
+
private
|
|
9
|
+
|
|
10
|
+
# Emit node
|
|
11
|
+
#
|
|
12
|
+
# @return [undefined]
|
|
13
|
+
#
|
|
14
|
+
# @api private
|
|
15
|
+
#
|
|
16
|
+
def emit(buffer)
|
|
17
|
+
buffer.append(operator)
|
|
18
|
+
target.visit(buffer)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Unary negation operator
|
|
22
|
+
class Negation < self
|
|
23
|
+
SYMBOL = :'!'
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Unary plus operator
|
|
27
|
+
class Plus < self
|
|
28
|
+
SYMBOL = :+
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Unary minus operator
|
|
32
|
+
class Minus < self
|
|
33
|
+
SYMBOL = :-
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module AQLHelper
|
|
2
|
+
def compress_aql(string)
|
|
3
|
+
string.gsub(/^[ ]*/, '').split("\n").join(' ')
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
def expect_aql(string)
|
|
7
|
+
expected_aql = compress_aql(string)
|
|
8
|
+
subject { object.aql }
|
|
9
|
+
it_should_behave_like 'an idempotent method'
|
|
10
|
+
it { should eql(expected_aql) }
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe AQL::Buffer, '#append' do
|
|
4
|
+
unless defined?(Encoding)
|
|
5
|
+
before do
|
|
6
|
+
pending "No support for encodings under #{Devtools.rvm}"
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
let(:object) { described_class.new }
|
|
11
|
+
subject { object.append(content) }
|
|
12
|
+
let(:utf8) { Encoding::UTF_8 }
|
|
13
|
+
|
|
14
|
+
this_spec = 'AQL::Bufffer#append'
|
|
15
|
+
|
|
16
|
+
shared_examples_for this_spec do
|
|
17
|
+
it 'should append content to buffer' do
|
|
18
|
+
expect { subject }.to change { object.content }.from('').to(expected_content)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it 'should return utf-8 encoded content' do
|
|
22
|
+
subject.content.encoding.should be(utf8)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it_should_behave_like 'a command method'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
context 'ascii encoded content' do
|
|
29
|
+
let(:content) { 'foo' }
|
|
30
|
+
let(:expected_content) { 'foo'.encode('utf-8') }
|
|
31
|
+
|
|
32
|
+
it_should_behave_like this_spec
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
context 'utf-8 encoded content' do
|
|
36
|
+
let(:content) { "\xC3\xBC".force_encoding(utf8) }
|
|
37
|
+
let(:expected_content) { content.dup }
|
|
38
|
+
|
|
39
|
+
it_should_behave_like this_spec
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
context 'with non utf-8 encodable content' do
|
|
43
|
+
let(:content) { "\xC3\x28".force_encoding('binary') }
|
|
44
|
+
|
|
45
|
+
let(:expected_message) do
|
|
46
|
+
case Devtools.rvm_name
|
|
47
|
+
when 'rbx'
|
|
48
|
+
'"\xC3" to UTF-8 in conversion from ASCII-8BIT to UTF-8'
|
|
49
|
+
else
|
|
50
|
+
'"\xC3" from ASCII-8BIT to UTF-8'
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it 'should raise error' do
|
|
55
|
+
expect { subject }.to raise_error(Encoding::UndefinedConversionError, expected_message)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe AQL::Buffer, '#binary' do
|
|
4
|
+
subject { object.binary(left, operator, right) }
|
|
5
|
+
|
|
6
|
+
let(:object) { described_class.new }
|
|
7
|
+
let(:left) { Node.new('left') }
|
|
8
|
+
let(:right) { Node.new('right') }
|
|
9
|
+
let(:operator) { :operator }
|
|
10
|
+
|
|
11
|
+
class Node
|
|
12
|
+
include Concord.new(:name)
|
|
13
|
+
|
|
14
|
+
def visit(buffer)
|
|
15
|
+
buffer.append(name)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
its(:content) { should eql('(left operator right)') }
|
|
20
|
+
|
|
21
|
+
it_should_behave_like 'a command method'
|
|
22
|
+
end
|