aql 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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,42 @@
|
|
1
|
+
module AQL
|
2
|
+
class Node
|
3
|
+
class Literal
|
4
|
+
class Composed
|
5
|
+
# Literal list node
|
6
|
+
class List < self
|
7
|
+
handle(Array)
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
# Emit node
|
12
|
+
#
|
13
|
+
# @param [Buffer] buffer
|
14
|
+
#
|
15
|
+
# @return [undefined]
|
16
|
+
#
|
17
|
+
# @api private
|
18
|
+
#
|
19
|
+
def emit(buffer)
|
20
|
+
buffer.wrap_delimited('[', body, ']')
|
21
|
+
end
|
22
|
+
|
23
|
+
# Construct object
|
24
|
+
#
|
25
|
+
# @param [#each] object
|
26
|
+
#
|
27
|
+
# @return [Node::Literal::List]
|
28
|
+
#
|
29
|
+
# @api private
|
30
|
+
#
|
31
|
+
def self.construct(object)
|
32
|
+
body = object.map do |item|
|
33
|
+
Literal.build(item)
|
34
|
+
end
|
35
|
+
new(body)
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module AQL
|
2
|
+
class Node
|
3
|
+
class Literal
|
4
|
+
class Primitive
|
5
|
+
# Literal number node
|
6
|
+
class Number < self
|
7
|
+
handle(Float)
|
8
|
+
handle(Fixnum)
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
# Emit AQL
|
13
|
+
#
|
14
|
+
# @param [Buffer] buffer
|
15
|
+
#
|
16
|
+
# @return [undefined]
|
17
|
+
#
|
18
|
+
# @api private
|
19
|
+
#
|
20
|
+
def emit(buffer)
|
21
|
+
buffer.append(value.to_s)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module AQL
|
2
|
+
class Node
|
3
|
+
class Literal
|
4
|
+
class Primitive
|
5
|
+
# Literal string node
|
6
|
+
class String < self
|
7
|
+
handle(::String)
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
# Emit AQL
|
12
|
+
#
|
13
|
+
# @param [Buffer] buffer
|
14
|
+
#
|
15
|
+
# @return [undefined]
|
16
|
+
#
|
17
|
+
# @api private
|
18
|
+
#
|
19
|
+
def emit(buffer)
|
20
|
+
buffer.append(value.inspect)
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module AQL
|
2
|
+
class Node
|
3
|
+
class Literal
|
4
|
+
# Singleton literal
|
5
|
+
class Singleton < self
|
6
|
+
include Concord.new(:token)
|
7
|
+
|
8
|
+
handle(NilClass)
|
9
|
+
handle(TrueClass)
|
10
|
+
handle(FalseClass)
|
11
|
+
|
12
|
+
private_class_method :new
|
13
|
+
|
14
|
+
# Construct object
|
15
|
+
#
|
16
|
+
# @param [Object] object
|
17
|
+
#
|
18
|
+
# @return [Node::Literal::Singleton]
|
19
|
+
#
|
20
|
+
# @api private
|
21
|
+
#
|
22
|
+
def self.construct(object)
|
23
|
+
MAPPING.fetch(object)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
# Emit node
|
29
|
+
#
|
30
|
+
# @return [undefined]
|
31
|
+
#
|
32
|
+
# @api private
|
33
|
+
#
|
34
|
+
def emit(buffer)
|
35
|
+
buffer.append(token)
|
36
|
+
end
|
37
|
+
|
38
|
+
NULL = new('null')
|
39
|
+
FALSE = new('false')
|
40
|
+
TRUE = new('true')
|
41
|
+
|
42
|
+
MAPPING = {
|
43
|
+
nil => NULL,
|
44
|
+
false => FALSE,
|
45
|
+
true => TRUE
|
46
|
+
}
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module AQL
|
2
|
+
class Node
|
3
|
+
# Generic AQL object name
|
4
|
+
class Name < self
|
5
|
+
include Concord.new(:name)
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
# Emit node
|
10
|
+
#
|
11
|
+
# @param [Buffer] buffer
|
12
|
+
#
|
13
|
+
# @return [undefined]
|
14
|
+
#
|
15
|
+
def emit(buffer)
|
16
|
+
buffer.append(quoted_name)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Return quoted name
|
20
|
+
#
|
21
|
+
# @return [String]
|
22
|
+
#
|
23
|
+
# @api private
|
24
|
+
#
|
25
|
+
def quoted_name
|
26
|
+
%Q(`#{name}`)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module AQL
|
2
|
+
class Node
|
3
|
+
# Null node that does not emit anything
|
4
|
+
NULL = Class.new(self) do
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
# Perform emit on buffer
|
9
|
+
#
|
10
|
+
# @param [Buffer] buffer
|
11
|
+
#
|
12
|
+
# @return [undefined]
|
13
|
+
#
|
14
|
+
# @api private
|
15
|
+
#
|
16
|
+
def emit(_buffer)
|
17
|
+
end
|
18
|
+
|
19
|
+
end.new
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module AQL
|
2
|
+
class Node
|
3
|
+
class Operation
|
4
|
+
# Base class for binary operations
|
5
|
+
class Binary < self
|
6
|
+
include Concord.new(:left, :right)
|
7
|
+
|
8
|
+
# Binary let operation
|
9
|
+
class Let < self
|
10
|
+
|
11
|
+
KEYWORD = :LET
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
# Emit node
|
16
|
+
#
|
17
|
+
# @param [Buffer] buffer
|
18
|
+
#
|
19
|
+
# @return [undefined]
|
20
|
+
#
|
21
|
+
# @api private
|
22
|
+
#
|
23
|
+
def emit(buffer)
|
24
|
+
buffer.append("#{keyword} ")
|
25
|
+
left.visit(buffer)
|
26
|
+
buffer.append(' = ')
|
27
|
+
right.visit(buffer)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module AQL
|
2
|
+
class Node
|
3
|
+
class Operation
|
4
|
+
# For operation
|
5
|
+
class For < self
|
6
|
+
include Concord.new(:local, :source, :body)
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
# Emit node
|
11
|
+
#
|
12
|
+
# @param [Buffer] buffer
|
13
|
+
#
|
14
|
+
# @return [self]
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
#
|
18
|
+
def emit(buffer)
|
19
|
+
buffer.append('FOR ')
|
20
|
+
emit_local(buffer)
|
21
|
+
emit_source(buffer)
|
22
|
+
emit_body(buffer)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Emit body
|
26
|
+
#
|
27
|
+
# @return [undefined]
|
28
|
+
#
|
29
|
+
# @api private
|
30
|
+
#
|
31
|
+
def emit_body(buffer)
|
32
|
+
body.visit(buffer)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Emit local
|
36
|
+
#
|
37
|
+
# @return [undefined]
|
38
|
+
#
|
39
|
+
# @api private
|
40
|
+
#
|
41
|
+
def emit_local(buffer)
|
42
|
+
local.visit(buffer)
|
43
|
+
buffer.append(' IN ')
|
44
|
+
end
|
45
|
+
|
46
|
+
# Emit source
|
47
|
+
#
|
48
|
+
# @return [undefined]
|
49
|
+
#
|
50
|
+
# @api private
|
51
|
+
#
|
52
|
+
def emit_source(buffer)
|
53
|
+
local = source
|
54
|
+
if local.kind_of?(Name)
|
55
|
+
local.visit(buffer)
|
56
|
+
else
|
57
|
+
emit_source_parentheses(buffer)
|
58
|
+
end
|
59
|
+
buffer.append(' ')
|
60
|
+
end
|
61
|
+
|
62
|
+
# Emit source in parentheses
|
63
|
+
#
|
64
|
+
# @return [undefined]
|
65
|
+
#
|
66
|
+
# @api private
|
67
|
+
#
|
68
|
+
def emit_source_parentheses(buffer)
|
69
|
+
buffer.parentheses do
|
70
|
+
source.visit(buffer)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module AQL
|
2
|
+
class Node
|
3
|
+
class Operation
|
4
|
+
# Limit operation
|
5
|
+
class Limit < self
|
6
|
+
KEYWORD = :LIMIT
|
7
|
+
|
8
|
+
include Concord.new(:count, :offset)
|
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
|
+
buffer.append("#{keyword} ")
|
22
|
+
emit_offset(buffer)
|
23
|
+
count.visit(buffer)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Emit offset
|
27
|
+
#
|
28
|
+
# @param [Buffer] buffer
|
29
|
+
#
|
30
|
+
# @return [undefined]
|
31
|
+
#
|
32
|
+
# @api private
|
33
|
+
#
|
34
|
+
def emit_offset(buffer)
|
35
|
+
local = offset || return
|
36
|
+
local.visit(buffer)
|
37
|
+
buffer.append(', ')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module AQL
|
2
|
+
class Node
|
3
|
+
class Operation
|
4
|
+
# Base class for nary operations
|
5
|
+
class Nary < self
|
6
|
+
include Concord.new(:body)
|
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
|
+
buffer.delimited(body)
|
21
|
+
end
|
22
|
+
|
23
|
+
# FILTER operation
|
24
|
+
class Sort < self
|
25
|
+
KEYWORD = :SORT
|
26
|
+
end
|
27
|
+
|
28
|
+
# COLLECT operation
|
29
|
+
class Collect < self
|
30
|
+
KEYWORD = :COLLECT
|
31
|
+
|
32
|
+
# COLLECT INTO operation
|
33
|
+
class Into < self
|
34
|
+
include Concord.new(:body, :name)
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
# Emit node
|
39
|
+
#
|
40
|
+
# @param [Buffer] buffer
|
41
|
+
#
|
42
|
+
# @return [undefined]
|
43
|
+
#
|
44
|
+
# @api private
|
45
|
+
#
|
46
|
+
def emit(buffer)
|
47
|
+
super
|
48
|
+
buffer.append(' INTO ')
|
49
|
+
name.visit(buffer)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|