axiom-arango-adapter 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. data/.gitignore +4 -0
  2. data/.rspec +5 -0
  3. data/.travis.yml +25 -0
  4. data/Gemfile +9 -0
  5. data/Gemfile.devtools +57 -0
  6. data/Guardfile +18 -0
  7. data/LICENSE +20 -0
  8. data/README.md +92 -0
  9. data/Rakefile +2 -0
  10. data/TODO +1 -0
  11. data/axiom-arango-adapter.gemspec +26 -0
  12. data/config/flay.yml +3 -0
  13. data/config/flog.yml +2 -0
  14. data/config/mutant.yml +3 -0
  15. data/config/roodi.yml +18 -0
  16. data/config/site.reek +102 -0
  17. data/config/yardstick.yml +2 -0
  18. data/lib/axiom-arango-adapter.rb +2 -0
  19. data/lib/axiom/adapter/arango.rb +40 -0
  20. data/lib/axiom/adapter/arango/adapter.rb +68 -0
  21. data/lib/axiom/adapter/arango/gateway.rb +356 -0
  22. data/lib/axiom/adapter/arango/reader.rb +98 -0
  23. data/lib/axiom/adapter/arango/visitor.rb +100 -0
  24. data/lib/axiom/adapter/arango/visitor/aggregate.rb +132 -0
  25. data/lib/axiom/adapter/arango/visitor/attribute.rb +26 -0
  26. data/lib/axiom/adapter/arango/visitor/binary.rb +77 -0
  27. data/lib/axiom/adapter/arango/visitor/for.rb +75 -0
  28. data/lib/axiom/adapter/arango/visitor/for/base.rb +40 -0
  29. data/lib/axiom/adapter/arango/visitor/for/binary.rb +108 -0
  30. data/lib/axiom/adapter/arango/visitor/for/binary/join.rb +131 -0
  31. data/lib/axiom/adapter/arango/visitor/for/binary/product.rb +48 -0
  32. data/lib/axiom/adapter/arango/visitor/for/summarization.rb +113 -0
  33. data/lib/axiom/adapter/arango/visitor/for/unary.rb +29 -0
  34. data/lib/axiom/adapter/arango/visitor/for/unary/extension.rb +72 -0
  35. data/lib/axiom/adapter/arango/visitor/for/unary/limit.rb +31 -0
  36. data/lib/axiom/adapter/arango/visitor/for/unary/offset.rb +34 -0
  37. data/lib/axiom/adapter/arango/visitor/for/unary/order.rb +63 -0
  38. data/lib/axiom/adapter/arango/visitor/for/unary/projection.rb +32 -0
  39. data/lib/axiom/adapter/arango/visitor/for/unary/rename.rb +88 -0
  40. data/lib/axiom/adapter/arango/visitor/for/unary/restriction.rb +42 -0
  41. data/lib/axiom/adapter/arango/visitor/function.rb +33 -0
  42. data/lib/axiom/adapter/arango/visitor/header.rb +55 -0
  43. data/lib/axiom/adapter/arango/visitor/literal.rb +26 -0
  44. data/lib/axiom/adapter/arango/visitor/reverse.rb +27 -0
  45. data/spec/fuzzer.rb +53 -0
  46. data/spec/integration/arango/read_spec.rb +166 -0
  47. data/spec/setup/arangodb.sh +61 -0
  48. data/spec/setup/run.sh +23 -0
  49. data/spec/shared/aql_behavior.rb +7 -0
  50. data/spec/shared/binary_relation_method_behaviour.rb +53 -0
  51. data/spec/shared/unary_relation_method_behaviour.rb +21 -0
  52. data/spec/spec_helper.rb +51 -0
  53. data/spec/support/ice_nine_config.rb +6 -0
  54. data/spec/unit/axiom/adapter/arango/adapter/class_methods/new_spec.rb +24 -0
  55. data/spec/unit/axiom/adapter/arango/adapter/gateway_spec.rb +11 -0
  56. data/spec/unit/axiom/adapter/arango/adapter/reader_spec.rb +12 -0
  57. data/spec/unit/axiom/adapter/arango/gateway/class_methods/new_spec.rb +15 -0
  58. data/spec/unit/axiom/adapter/arango/gateway/difference_spec.rb +16 -0
  59. data/spec/unit/axiom/adapter/arango/gateway/drop_spec.rb +20 -0
  60. data/spec/unit/axiom/adapter/arango/gateway/each_spec.rb +78 -0
  61. data/spec/unit/axiom/adapter/arango/gateway/extend_spec.rb +26 -0
  62. data/spec/unit/axiom/adapter/arango/gateway/intersect_spec.rb +16 -0
  63. data/spec/unit/axiom/adapter/arango/gateway/join_spec.rb +43 -0
  64. data/spec/unit/axiom/adapter/arango/gateway/materialize_spec.rb +26 -0
  65. data/spec/unit/axiom/adapter/arango/gateway/optimize_spec.rb +22 -0
  66. data/spec/unit/axiom/adapter/arango/gateway/product_spec.rb +16 -0
  67. data/spec/unit/axiom/adapter/arango/gateway/project_spec.rb +20 -0
  68. data/spec/unit/axiom/adapter/arango/gateway/remove_spec.rb +20 -0
  69. data/spec/unit/axiom/adapter/arango/gateway/rename_spec.rb +20 -0
  70. data/spec/unit/axiom/adapter/arango/gateway/respond_to_predicate_spec.rb +28 -0
  71. data/spec/unit/axiom/adapter/arango/gateway/restrict_spec.rb +26 -0
  72. data/spec/unit/axiom/adapter/arango/gateway/reverse_spec.rb +20 -0
  73. data/spec/unit/axiom/adapter/arango/gateway/sort_by_spec.rb +26 -0
  74. data/spec/unit/axiom/adapter/arango/gateway/summarize_spec.rb +150 -0
  75. data/spec/unit/axiom/adapter/arango/gateway/take_spec.rb +20 -0
  76. data/spec/unit/axiom/adapter/arango/gateway/unhandled_message_spec.rb +17 -0
  77. data/spec/unit/axiom/adapter/arango/gateway/union_spec.rb +16 -0
  78. data/spec/unit/axiom/adapter/arango/reader/each_spec.rb +43 -0
  79. data/spec/unit/axiom/adapter/arango/visitor/aggregate/count/root_spec.rb +15 -0
  80. data/spec/unit/axiom/adapter/arango/visitor/aggregate/count_spec.rb +15 -0
  81. data/spec/unit/axiom/adapter/arango/visitor/aggregate/maximum/root_spec.rb +15 -0
  82. data/spec/unit/axiom/adapter/arango/visitor/aggregate/maximum_spec.rb +15 -0
  83. data/spec/unit/axiom/adapter/arango/visitor/aggregate/minimum/root_spec.rb +15 -0
  84. data/spec/unit/axiom/adapter/arango/visitor/aggregate/minimum_spec.rb +15 -0
  85. data/spec/unit/axiom/adapter/arango/visitor/aggregate/sum/root_spec.rb +15 -0
  86. data/spec/unit/axiom/adapter/arango/visitor/aggregate/sum_spec.rb +15 -0
  87. data/spec/unit/axiom/adapter/arango/visitor/attribute/root_spec.rb +12 -0
  88. data/spec/unit/axiom/adapter/arango/visitor/binary/root_spec.rb +15 -0
  89. data/spec/unit/axiom/adapter/arango/visitor/class_methods/build_spec.rb +37 -0
  90. data/spec/unit/axiom/adapter/arango/visitor/class_methods/run_spec.rb +26 -0
  91. data/spec/unit/axiom/adapter/arango/visitor/for/base/root_spec.rb +13 -0
  92. data/spec/unit/axiom/adapter/arango/visitor/for/binary/join/local_name_spec.rb +20 -0
  93. data/spec/unit/axiom/adapter/arango/visitor/for/binary/join/right/root_spec.rb +14 -0
  94. data/spec/unit/axiom/adapter/arango/visitor/for/binary/join/root_spec.rb +14 -0
  95. data/spec/unit/axiom/adapter/arango/visitor/for/binary/join_spec.rb +14 -0
  96. data/spec/unit/axiom/adapter/arango/visitor/for/binary/local_name_spec.rb +14 -0
  97. data/spec/unit/axiom/adapter/arango/visitor/for/binary/product/right/root_spec.rb +13 -0
  98. data/spec/unit/axiom/adapter/arango/visitor/for/binary/product/root_spec.rb +13 -0
  99. data/spec/unit/axiom/adapter/arango/visitor/for/binary/product_spec.rb +13 -0
  100. data/spec/unit/axiom/adapter/arango/visitor/for/binary/right/join_spec.rb +14 -0
  101. data/spec/unit/axiom/adapter/arango/visitor/for/binary/right/local_name_spec.rb +13 -0
  102. data/spec/unit/axiom/adapter/arango/visitor/for/binary/right/product_spec.rb +13 -0
  103. data/spec/unit/axiom/adapter/arango/visitor/for/local_name_spec.rb +21 -0
  104. data/spec/unit/axiom/adapter/arango/visitor/for/root_spec.rb +29 -0
  105. data/spec/unit/axiom/adapter/arango/visitor/for/summarization/root_spec.rb +53 -0
  106. data/spec/unit/axiom/adapter/arango/visitor/for/unary/extension/root_spec.rb +13 -0
  107. data/spec/unit/axiom/adapter/arango/visitor/for/unary/extension_spec.rb +13 -0
  108. data/spec/unit/axiom/adapter/arango/visitor/for/unary/limit/root_spec.rb +17 -0
  109. data/spec/unit/axiom/adapter/arango/visitor/for/unary/limit_spec.rb +17 -0
  110. data/spec/unit/axiom/adapter/arango/visitor/for/unary/offset/root_spec.rb +17 -0
  111. data/spec/unit/axiom/adapter/arango/visitor/for/unary/offset_spec.rb +17 -0
  112. data/spec/unit/axiom/adapter/arango/visitor/for/unary/order/root_spec.rb +14 -0
  113. data/spec/unit/axiom/adapter/arango/visitor/for/unary/order_spec.rb +14 -0
  114. data/spec/unit/axiom/adapter/arango/visitor/for/unary/projection/root_spec.rb +13 -0
  115. data/spec/unit/axiom/adapter/arango/visitor/for/unary/projection_spec.rb +13 -0
  116. data/spec/unit/axiom/adapter/arango/visitor/for/unary/rename/root_spec.rb +13 -0
  117. data/spec/unit/axiom/adapter/arango/visitor/for/unary/rename_spec.rb +13 -0
  118. data/spec/unit/axiom/adapter/arango/visitor/for/unary/restriction/root_spec.rb +14 -0
  119. data/spec/unit/axiom/adapter/arango/visitor/for/unary/restriction_spec.rb +14 -0
  120. data/spec/unit/axiom/adapter/arango/visitor/header/root_spec.rb +12 -0
  121. data/spec/unit/axiom/adapter/arango/visitor/literal/root_spec.rb +10 -0
  122. data/spec/unit/axiom/adapter/arango/visitor/static/root_spec.rb +19 -0
  123. data/spec/unit/axiom/adapter/arango/visitor/visit_spec.rb +52 -0
  124. data/spec/unit/axiom/adapter/arango/visitor/visitor_spec.rb +39 -0
  125. metadata +379 -0
@@ -0,0 +1,108 @@
1
+ module Axiom
2
+ module Adapter
3
+ module Arango
4
+ class Visitor
5
+ class For
6
+ # Base class for binary relation visitors
7
+ class Binary < self
8
+
9
+ LOCAL_NAME = AQL.name_node('left')
10
+
11
+ private
12
+
13
+ # Return iteration source
14
+ #
15
+ # @return [AQL::Node]
16
+ #
17
+ # @api private
18
+ #
19
+ def source
20
+ visit(input.left)
21
+ end
22
+
23
+ # Return body of for statement
24
+ #
25
+ # @return [AQL::Node]
26
+ #
27
+ # @api private
28
+ #
29
+ def body
30
+ self.class::Right.new(input.right, self).root
31
+ end
32
+
33
+ # Visitor for right of join
34
+ class Right < For
35
+
36
+ # Return local name
37
+ #
38
+ # @return [AQL::Node::Name]
39
+ #
40
+ # @api private
41
+ #
42
+ def local_name
43
+ AQL.name_node(:right)
44
+ end
45
+ memoize :local_name
46
+
47
+ private
48
+
49
+ # Return source of iteration
50
+ #
51
+ # @return [AQL::Node]
52
+ #
53
+ # @api private
54
+ #
55
+ def source
56
+ visit(input)
57
+ end
58
+
59
+ # Return return value
60
+ #
61
+ # @return [AQL::Node::Literal::Compised::Document]
62
+ #
63
+ # @api private
64
+ #
65
+ def return_value
66
+ AQL::Node::Literal::Composed::Document.new(left_document_attributes + right_document_attributes)
67
+ end
68
+
69
+ # Return right header
70
+ #
71
+ # @return [Relation::Header]
72
+ #
73
+ # @api private
74
+ #
75
+ def right_header
76
+ input.header
77
+ end
78
+
79
+ # Return left header
80
+ #
81
+ # @return [Relation::Header]
82
+ #
83
+ # @api private
84
+ #
85
+ def left_header
86
+ context_input.left.header
87
+ end
88
+
89
+ abstract_method :left_document_attributes
90
+ abstract_method :right_document_attributes
91
+
92
+ # Return context input
93
+ #
94
+ # @return [Axiom::Relation]
95
+ #
96
+ # @api private
97
+ #
98
+ def context_input
99
+ context.input
100
+ end
101
+
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,131 @@
1
+ module Axiom
2
+ module Adapter
3
+ module Arango
4
+ class Visitor
5
+ class For
6
+ class Binary
7
+ # Visitor for emitting joins
8
+ class Join < self
9
+
10
+ handle(Axiom::Algebra::Join)
11
+
12
+ # Return local name
13
+ #
14
+ # @return [AQL::Node::Name]
15
+ #
16
+ # @api private
17
+ #
18
+ def local_name
19
+ AQL::Node::Name.new("local_#{depth}")
20
+ end
21
+ memoize :local_name
22
+
23
+ private
24
+
25
+ # Visitor for right of join
26
+ class Right < Binary::Right
27
+
28
+ private
29
+
30
+ # Return filter
31
+ #
32
+ # @return [AQL::Node::Operation::Filter]
33
+ #
34
+ # @api private
35
+ #
36
+ def filter
37
+ AQL::Node::Operation::Unary::Filter.new(filter_expression)
38
+ end
39
+
40
+ # Return filter expression
41
+ #
42
+ # @return [AQL::Node]
43
+ #
44
+ # @api private
45
+ #
46
+ def filter_expression
47
+ AQL::Node::Operator::Nary::And.new(filter_predicates)
48
+ end
49
+
50
+ # Return filter predicates
51
+ #
52
+ # @return [Enumerable<AQL::Node::Operator::Binary::Equality>]
53
+ #
54
+ # @api private
55
+ #
56
+ def filter_predicates
57
+ context_input.join_header.map do |attribute|
58
+ filter_predicate(attribute)
59
+ end
60
+ end
61
+
62
+ # Return filter predicate for attribute
63
+ #
64
+ # @param [Attribute] attribute
65
+ #
66
+ # @return [AQL::Node::Operator::Binary::Equality]
67
+ #
68
+ # @api private
69
+ #
70
+ def filter_predicate(attribute)
71
+ AQL::Node::Operator::Binary::Equality.new(visit(attribute, context), visit(attribute))
72
+ end
73
+
74
+ # Return body of for statement
75
+ #
76
+ # @return [AQL::Node]
77
+ #
78
+ # @api private
79
+ #
80
+ def body
81
+ AQL::Node::Block.new([filter, return_operation])
82
+ end
83
+
84
+ # Return left document attributes
85
+ #
86
+ # @return [Enumerable<AQL::Node::Literal::Composed::Document::Attribute>]
87
+ #
88
+ # @api private
89
+ #
90
+ def left_document_attributes
91
+ visitor(left_header, context).document_attributes
92
+ end
93
+
94
+ # Return left header
95
+ #
96
+ # @return [Relation::Header]
97
+ #
98
+ # @api private
99
+ #
100
+ def left_header
101
+ context_input.left.header
102
+ end
103
+
104
+ # Return right document attributes
105
+ #
106
+ # @return [Enumerable<AQL::Node::Literal::Composed::Document::Attribute>]
107
+ #
108
+ # @api private
109
+ #
110
+ def right_document_attributes
111
+ visitor(right_document_header).document_attributes
112
+ end
113
+
114
+ # Return right document header
115
+ #
116
+ # @return [Relation::Header]
117
+ #
118
+ # @api private
119
+ #
120
+ def right_document_header
121
+ right_header - left_header
122
+ end
123
+
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,48 @@
1
+ module Axiom
2
+ module Adapter
3
+ module Arango
4
+ class Visitor
5
+ class For
6
+ class Binary
7
+ # Visitor for emitting products
8
+ class Product < self
9
+
10
+ handle(Axiom::Algebra::Product)
11
+
12
+
13
+ private
14
+
15
+ # Vistior for right of projection
16
+ class Right < Binary::Right
17
+
18
+ private
19
+
20
+ # Return left document attributes
21
+ #
22
+ # @return [Enumerable<AQL::Node::Literal::Composed::Document::Attribute>]
23
+ #
24
+ # @api private
25
+ #
26
+ def left_document_attributes
27
+ visitor = visitor(left_header, context)
28
+ visitor.document_attributes
29
+ end
30
+
31
+ # Return right document attributes
32
+ #
33
+ # @return [Enumerable<AQL::Node::Literal::Composed::Document::Attribute>]
34
+ #
35
+ # @api private
36
+ #
37
+ def right_document_attributes
38
+ visitor(right_header).document_attributes
39
+ end
40
+
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,113 @@
1
+ module Axiom
2
+ module Adapter
3
+ module Arango
4
+ class Visitor
5
+ class For
6
+ # Visitor for axiom summarizations
7
+ class Summarization < self
8
+ handle(Axiom::Algebra::Summarization)
9
+
10
+ LOCAL_NAME = AQL.name_node('summarization')
11
+ COLLECT_NAME = AQL.name_node('collect')
12
+
13
+ private
14
+
15
+ # Return body of for operation
16
+ #
17
+ # @return [AQL::Node::Block]
18
+ #
19
+ # @api private
20
+ #
21
+ def body
22
+ AQL::Node::Block.new([
23
+ collect_operation,
24
+ return_operation
25
+ ])
26
+ end
27
+
28
+ # Return collection assignments
29
+ #
30
+ # @return [Enumerable<AQL::Node::Operator::Assignment>]
31
+ #
32
+ # @api private
33
+ #
34
+ def assignments
35
+ input.summarize_per.header.map do |attribute|
36
+ name = AQL::Node::Name.new(attribute.name.to_s)
37
+ value = AQL::Node::Attribute.new(LOCAL_NAME, name)
38
+ AQL::Node::Operator::Assignment.new(
39
+ name,
40
+ value
41
+ )
42
+ end
43
+ end
44
+ memoize :assignments
45
+
46
+ # Return AQL return value
47
+ #
48
+ # @return [AQL::Node::Literal::Composed::Document]
49
+ #
50
+ # @api private
51
+ #
52
+ def return_value
53
+ AQL::Node::Literal::Composed::Document.new(projected_document_attributes + extension_document_attributes)
54
+ end
55
+
56
+ # Return extension document attributes
57
+ #
58
+ # @return [Enumerable<AQL::Node::Literal::Composed::Document::Attribute>]
59
+ #
60
+ # @api private
61
+ #
62
+ def extension_document_attributes
63
+ input.summarizers.map do |attribute, summarizer|
64
+ extension_document_attribute(attribute, summarizer)
65
+ end
66
+ end
67
+
68
+ # Return extension document attribute
69
+ #
70
+ # @param [Attribute] attribute
71
+ # @param [Aggregate] summarizer
72
+ #
73
+ # @return [AQL::Node::Literal::Composed::Document::Attribute]
74
+ #
75
+ # @api private
76
+ #
77
+ def extension_document_attribute(attribute, summarizer)
78
+ key = AQL::Node::Literal::Primitive::String.new(attribute.name.to_s)
79
+ value = visit(summarizer)
80
+ AQL::Node::Literal::Composed::Document::Attribute.new(key, value)
81
+ end
82
+
83
+ # Return projected document attributes
84
+ #
85
+ # @return [Enumerable<AQL::Node::Literal::Composed::Document::Attribute>]
86
+ #
87
+ # @api private
88
+ #
89
+ def projected_document_attributes
90
+ assignments.map do |assignment|
91
+ value = assignment.name
92
+ key = AQL::Node::Literal::Primitive::String.new(value.name)
93
+ AQL::Node::Literal::Composed::Document::Attribute.new(key, value)
94
+ end
95
+ end
96
+ memoize :projected_document_attributes
97
+
98
+ # Return collect operation
99
+ #
100
+ # @return [AQL::Node::Operation::Nary::Collect::Into]
101
+ #
102
+ # @api private
103
+ #
104
+ def collect_operation
105
+ AQL::Node::Operation::Nary::Collect::Into.new(assignments, COLLECT_NAME)
106
+ end
107
+
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,29 @@
1
+ module Axiom
2
+ module Adapter
3
+ module Arango
4
+ class Visitor
5
+ class For
6
+ # Base class for visitors that emit from unary axiom relations
7
+ class Unary < self
8
+
9
+ private
10
+
11
+ # Return body
12
+ #
13
+ # @return [AQL::Node]
14
+ #
15
+ # @api private
16
+ #
17
+ def body
18
+ AQL::Node::Block.new([
19
+ operation,
20
+ return_operation
21
+ ])
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,72 @@
1
+ module Axiom
2
+ module Adapter
3
+ module Arango
4
+ class Visitor
5
+ class For
6
+ class Unary
7
+ # Visitor for emitting extensions
8
+ class Extension < self
9
+
10
+ handle(Algebra::Extension)
11
+
12
+ LOCAL_NAME = AQL.name_node('extension')
13
+
14
+ private
15
+
16
+ # Return for body
17
+ #
18
+ # @return [AQL::Node]
19
+ #
20
+ # @api private
21
+ #
22
+ def body
23
+ return_operation
24
+ end
25
+
26
+ # Return return value
27
+ #
28
+ # @return [AQL::Node::Call]
29
+ #
30
+ # @api private
31
+ #
32
+ def return_value
33
+ Node::Call.new('MERGE', [local_name, Node::Literal::Composed::Document.new(extended_attributes)])
34
+ end
35
+
36
+ # Return document attribute node
37
+ #
38
+ # @return [Axiom::Attribute] attribute
39
+ #
40
+ # @return [AQL::Node]
41
+ #
42
+ # @api private
43
+ #
44
+ def extended_attributes
45
+ input.extensions.map do |attribute, function|
46
+ document_attribute(attribute, function)
47
+ end
48
+ end
49
+
50
+ # Return document attribute
51
+ #
52
+ # @param [Axiom::Attribute] attribute
53
+ # @param [Axiom::Function] function
54
+ #
55
+ # @return [AQL::Node::Literal::Composed::Document::Attribute>]
56
+ #
57
+ # @api private
58
+ #
59
+ def document_attribute(attribute, function)
60
+ Node::Literal::Composed::Document::Attribute.new(
61
+ Node::Literal::Primitive::String.new(attribute.name.to_s),
62
+ visit(function)
63
+ )
64
+ end
65
+
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end