grumlin 0.23.0 → 1.0.0.rc2

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.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +9 -9
  3. data/Gemfile.lock +1 -1
  4. data/README.md +100 -142
  5. data/Rakefile +1 -1
  6. data/bin/console +18 -3
  7. data/doc/middlewares.md +49 -10
  8. data/lib/async/channel.rb +54 -56
  9. data/lib/grumlin/benchmark/repository.rb +10 -14
  10. data/lib/grumlin/client.rb +93 -95
  11. data/lib/grumlin/config.rb +33 -33
  12. data/lib/grumlin/dummy_transaction.rb +13 -15
  13. data/lib/grumlin/edge.rb +18 -20
  14. data/lib/grumlin/expressions/cardinality.rb +5 -9
  15. data/lib/grumlin/expressions/column.rb +5 -9
  16. data/lib/grumlin/expressions/expression.rb +7 -11
  17. data/lib/grumlin/expressions/operator.rb +5 -9
  18. data/lib/grumlin/expressions/order.rb +5 -9
  19. data/lib/grumlin/expressions/p.rb +27 -31
  20. data/lib/grumlin/expressions/pop.rb +5 -9
  21. data/lib/grumlin/expressions/scope.rb +5 -9
  22. data/lib/grumlin/expressions/t.rb +5 -9
  23. data/lib/grumlin/expressions/text_p.rb +5 -9
  24. data/lib/grumlin/expressions/with_options.rb +17 -21
  25. data/lib/grumlin/features/feature_list.rb +8 -12
  26. data/lib/grumlin/features/neptune_features.rb +5 -9
  27. data/lib/grumlin/features/tinkergraph_features.rb +5 -9
  28. data/lib/grumlin/features.rb +8 -10
  29. data/lib/grumlin/middlewares/apply_shortcuts.rb +4 -8
  30. data/lib/grumlin/middlewares/build_query.rb +16 -20
  31. data/lib/grumlin/middlewares/builder.rb +15 -0
  32. data/lib/grumlin/middlewares/cast_results.rb +3 -7
  33. data/lib/grumlin/middlewares/find_blocklisted_steps.rb +14 -0
  34. data/lib/grumlin/middlewares/find_mutating_steps.rb +9 -0
  35. data/lib/grumlin/middlewares/middleware.rb +6 -10
  36. data/lib/grumlin/middlewares/run_query.rb +3 -7
  37. data/lib/grumlin/middlewares/serialize_to_bytecode.rb +5 -9
  38. data/lib/grumlin/middlewares/serialize_to_steps.rb +4 -8
  39. data/lib/grumlin/path.rb +11 -13
  40. data/lib/grumlin/property.rb +14 -16
  41. data/lib/grumlin/query_validators/blocklisted_steps_validator.rb +22 -0
  42. data/lib/grumlin/query_validators/validator.rb +36 -0
  43. data/lib/grumlin/repository/error_handling_strategy.rb +36 -40
  44. data/lib/grumlin/repository/instance_methods.rb +115 -118
  45. data/lib/grumlin/repository.rb +82 -58
  46. data/lib/grumlin/request_dispatcher.rb +55 -57
  47. data/lib/grumlin/request_error_factory.rb +53 -55
  48. data/lib/grumlin/shortcut.rb +19 -21
  49. data/lib/grumlin/shortcuts/properties.rb +12 -16
  50. data/lib/grumlin/shortcuts/storage.rb +67 -74
  51. data/lib/grumlin/shortcuts/upserts.rb +19 -22
  52. data/lib/grumlin/shortcuts.rb +23 -25
  53. data/lib/grumlin/shortcuts_applyer.rb +27 -29
  54. data/lib/grumlin/step.rb +88 -90
  55. data/lib/grumlin/step_data.rb +12 -14
  56. data/lib/grumlin/steppable.rb +23 -25
  57. data/lib/grumlin/steps.rb +52 -54
  58. data/lib/grumlin/steps_serializers/bytecode.rb +53 -56
  59. data/lib/grumlin/steps_serializers/human_readable_bytecode.rb +17 -21
  60. data/lib/grumlin/steps_serializers/serializer.rb +7 -11
  61. data/lib/grumlin/steps_serializers/string.rb +26 -30
  62. data/lib/grumlin/test/rspec/db_cleaner_context.rb +8 -12
  63. data/lib/grumlin/test/rspec/gremlin_context.rb +18 -16
  64. data/lib/grumlin/test/rspec.rb +1 -5
  65. data/lib/grumlin/transaction.rb +34 -36
  66. data/lib/grumlin/transport.rb +71 -73
  67. data/lib/grumlin/traversal_start.rb +31 -33
  68. data/lib/grumlin/traversal_strategies/options_strategy.rb +3 -7
  69. data/lib/grumlin/traverser.rb +5 -7
  70. data/lib/grumlin/typed_value.rb +11 -13
  71. data/lib/grumlin/typing.rb +70 -72
  72. data/lib/grumlin/version.rb +1 -1
  73. data/lib/grumlin/vertex.rb +14 -16
  74. data/lib/grumlin/vertex_property.rb +14 -16
  75. data/lib/grumlin/with_extension.rb +17 -19
  76. data/lib/grumlin.rb +13 -0
  77. metadata +9 -6
  78. data/lib/grumlin/middlewares/frozen_builder.rb +0 -18
  79. data/lib/grumlin/sugar.rb +0 -15
@@ -1,89 +1,87 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Grumlin
4
- module Typing
5
- TYPES = {
6
- "g:List" => ->(value) { cast_list(value) },
7
- "g:Set" => ->(value) { cast_list(value).to_set },
8
- "g:Map" => ->(value) { cast_map(value) },
9
- "g:Vertex" => ->(value) { cast_entity(Grumlin::Vertex, value) },
10
- "g:Edge" => ->(value) { cast_entity(Grumlin::Edge, value) },
11
- "g:Path" => ->(value) { cast_entity(Grumlin::Path, value) },
12
- "g:Traverser" => ->(value) { cast_entity(Grumlin::Traverser, value) },
13
- "g:Property" => ->(value) { cast_entity(Grumlin::Property, value) },
14
- "g:Int64" => ->(value) { cast_int(value) },
15
- "g:Int32" => ->(value) { cast_int(value) },
16
- "g:Double" => ->(value) { cast_double(value) },
17
- "g:Direction" => ->(value) { value },
18
- "g:VertexProperty" => ->(value) { cast_entity(Grumlin::VertexProperty, value) },
19
- "g:TraversalMetrics" => ->(value) { cast_map(value[:@value]) },
20
- "g:Metrics" => ->(value) { cast_map(value[:@value]) },
21
- "g:T" => ->(value) { Grumlin::Expressions::T.public_send(value) }
22
- }.freeze
23
-
24
- CASTABLE_TYPES = [Hash, String, Integer, TrueClass, FalseClass, NilClass].freeze
25
-
26
- class << self
27
- def cast(value)
28
- verify_type!(value)
29
-
30
- return value unless value.is_a?(Hash)
31
-
32
- type = TYPES[value[:@type]]
33
-
34
- verify_castable_hash!(value, type)
35
-
36
- type.call(value[:@value])
37
- end
3
+ module Grumlin::Typing
4
+ TYPES = {
5
+ "g:List" => ->(value) { cast_list(value) },
6
+ "g:Set" => ->(value) { cast_list(value).to_set },
7
+ "g:Map" => ->(value) { cast_map(value) },
8
+ "g:Vertex" => ->(value) { cast_entity(Grumlin::Vertex, value) },
9
+ "g:Edge" => ->(value) { cast_entity(Grumlin::Edge, value) },
10
+ "g:Path" => ->(value) { cast_entity(Grumlin::Path, value) },
11
+ "g:Traverser" => ->(value) { cast_entity(Grumlin::Traverser, value) },
12
+ "g:Property" => ->(value) { cast_entity(Grumlin::Property, value) },
13
+ "g:Int64" => ->(value) { cast_int(value) },
14
+ "g:Int32" => ->(value) { cast_int(value) },
15
+ "g:Double" => ->(value) { cast_double(value) },
16
+ "g:Direction" => ->(value) { value },
17
+ "g:VertexProperty" => ->(value) { cast_entity(Grumlin::VertexProperty, value) },
18
+ "g:TraversalMetrics" => ->(value) { cast_map(value[:@value]) },
19
+ "g:Metrics" => ->(value) { cast_map(value[:@value]) },
20
+ "g:T" => ->(value) { Grumlin::Expressions::T.public_send(value) }
21
+ }.freeze
22
+
23
+ CASTABLE_TYPES = [Hash, String, Integer, TrueClass, FalseClass, NilClass].freeze
24
+
25
+ class << self
26
+ def cast(value)
27
+ verify_type!(value)
28
+
29
+ return value unless value.is_a?(Hash)
30
+
31
+ type = TYPES[value[:@type]]
32
+
33
+ verify_castable_hash!(value, type)
34
+
35
+ type.call(value[:@value])
36
+ end
38
37
 
39
- private
38
+ private
40
39
 
41
- def verify_type!(value)
42
- raise TypeError, "#{value.inspect} cannot be casted" unless CASTABLE_TYPES.include?(value.class)
43
- end
40
+ def verify_type!(value)
41
+ raise TypeError, "#{value.inspect} cannot be casted" unless CASTABLE_TYPES.include?(value.class)
42
+ end
44
43
 
45
- def verify_castable_hash!(value, type)
46
- raise TypeError, "#{value} cannot be casted, @type is missing" if value[:@type].nil?
47
- raise(UnknownTypeError, value[:@type]) if type.nil?
48
- raise TypeError, "#{value} cannot be casted, @value is missing" if value[:@value].nil?
49
- end
44
+ def verify_castable_hash!(value, type)
45
+ raise TypeError, "#{value} cannot be casted, @type is missing" if value[:@type].nil?
46
+ raise(UnknownTypeError, value[:@type]) if type.nil?
47
+ raise TypeError, "#{value} cannot be casted, @value is missing" if value[:@value].nil?
48
+ end
50
49
 
51
- def cast_int(value)
52
- raise TypeError, "#{value} is not an Integer" unless value.is_a?(Integer)
50
+ def cast_int(value)
51
+ raise TypeError, "#{value} is not an Integer" unless value.is_a?(Integer)
53
52
 
54
- value
55
- end
53
+ value
54
+ end
56
55
 
57
- def cast_double(value)
58
- raise TypeError, "#{value} is not a Double" unless value.is_a?(Float)
56
+ def cast_double(value)
57
+ raise TypeError, "#{value} is not a Double" unless value.is_a?(Float)
59
58
 
60
- value
61
- end
59
+ value
60
+ end
62
61
 
63
- def cast_entity(entity, value)
64
- entity.new(**value)
65
- rescue ArgumentError, TypeError
66
- raise TypeError, "#{value} cannot be casted to #{entity.name}"
67
- end
62
+ def cast_entity(entity, value)
63
+ entity.new(**value)
64
+ rescue ArgumentError, TypeError
65
+ raise TypeError, "#{value} cannot be casted to #{entity.name}"
66
+ end
68
67
 
69
- def cast_map(value)
70
- Hash[*value].transform_keys do |key|
71
- next key.to_sym if key.respond_to?(:to_sym)
72
- next cast(key) if key[:@type] # TODO: g.V.group.by(:none_existing_property).next
68
+ def cast_map(value)
69
+ Hash[*value].transform_keys do |key|
70
+ next key.to_sym if key.respond_to?(:to_sym)
71
+ next cast(key) if key[:@type] # TODO: g.V.group.by(:none_existing_property).next
73
72
 
74
- raise UnknownMapKey, key, value
75
- end.transform_values { |v| cast(v) }
76
- rescue ArgumentError
77
- raise TypeError, "#{value} cannot be casted to Hash"
78
- end
73
+ raise UnknownMapKey, key, value
74
+ end.transform_values { |v| cast(v) }
75
+ rescue ArgumentError
76
+ raise TypeError, "#{value} cannot be casted to Hash"
77
+ end
79
78
 
80
- def cast_list(value)
81
- value.each_with_object([]) do |item, result|
82
- casted_value = cast(item)
83
- next (result << casted_value) unless casted_value.instance_of?(Traverser)
79
+ def cast_list(value)
80
+ value.each_with_object([]) do |item, result|
81
+ casted_value = cast(item)
82
+ next (result << casted_value) unless casted_value.instance_of?(Grumlin::Traverser)
84
83
 
85
- casted_value.bulk.times { result << casted_value.value }
86
- end
84
+ casted_value.bulk.times { result << casted_value.value }
87
85
  end
88
86
  end
89
87
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Grumlin
4
- VERSION = "0.23.0"
4
+ VERSION = "1.0.0.rc2"
5
5
  end
@@ -1,24 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Grumlin
4
- class Vertex
5
- attr_reader :label, :id
3
+ class Grumlin::Vertex
4
+ attr_reader :label, :id
6
5
 
7
- def initialize(label:, id:)
8
- @label = label
9
- @id = Typing.cast(id)
10
- end
6
+ def initialize(label:, id:)
7
+ @label = label
8
+ @id = Grumlin::Typing.cast(id)
9
+ end
11
10
 
12
- def ==(other)
13
- self.class == other.class && @label == other.label && @id == other.id
14
- end
11
+ def ==(other)
12
+ self.class == other.class && @label == other.label && @id == other.id
13
+ end
15
14
 
16
- def inspect
17
- "v[#{@id}]"
18
- end
15
+ def inspect
16
+ "v[#{@id}]"
17
+ end
19
18
 
20
- def to_s
21
- inspect
22
- end
19
+ def to_s
20
+ inspect
23
21
  end
24
22
  end
@@ -1,24 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Grumlin
4
- class VertexProperty
5
- attr_reader :label, :value
3
+ class Grumlin::VertexProperty
4
+ attr_reader :label, :value
6
5
 
7
- def initialize(value)
8
- @label = value[:label]
9
- @value = Typing.cast(value[:value])
10
- end
6
+ def initialize(value)
7
+ @label = value[:label]
8
+ @value = Grumlin::Typing.cast(value[:value])
9
+ end
11
10
 
12
- def inspect
13
- "vp[#{label}->#{value}]"
14
- end
11
+ def inspect
12
+ "vp[#{label}->#{value}]"
13
+ end
15
14
 
16
- def to_s
17
- inspect
18
- end
15
+ def to_s
16
+ inspect
17
+ end
19
18
 
20
- def ==(other)
21
- self.class == other.class && @label == other.label && @value == other.value
22
- end
19
+ def ==(other)
20
+ self.class == other.class && @label == other.label && @value == other.value
23
21
  end
24
22
  end
@@ -1,27 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Grumlin
4
- module WithExtension
5
- def with(name, value)
6
- prev = self
7
- strategy = if is_a?(with_step_class)
8
- prev = previous_step
9
- TraversalStrategies::OptionsStrategy.new(args.first.value.merge(name => value))
10
- else
11
- TraversalStrategies::OptionsStrategy.new({ name => value })
12
- end
13
- with_step_class.new(:withStrategies, args: [strategy], previous_step: prev)
14
- end
3
+ module Grumlin::WithExtension
4
+ def with(name, value)
5
+ prev = self
6
+ strategy = if is_a?(with_step_class)
7
+ prev = previous_step
8
+ Grumlin::TraversalStrategies::OptionsStrategy.new(args.first.value.merge(name => value))
9
+ else
10
+ Grumlin::TraversalStrategies::OptionsStrategy.new({ name => value })
11
+ end
12
+ with_step_class.new(:withStrategies, args: [strategy], previous_step: prev)
13
+ end
15
14
 
16
- private
15
+ private
17
16
 
18
- def with_step_class
19
- @with_step_class ||= Class.new(shortcuts.step_class) do
20
- include WithExtension
17
+ def with_step_class
18
+ @with_step_class ||= Class.new(shortcuts.step_class) do
19
+ include Grumlin::WithExtension
21
20
 
22
- def with_step_class
23
- self.class
24
- end
21
+ def with_step_class
22
+ self.class
25
23
  end
26
24
  end
27
25
  end
data/lib/grumlin.rb CHANGED
@@ -184,6 +184,19 @@ module Grumlin
184
184
  def definitions
185
185
  @definitions ||= YAML.safe_load(File.read(File.join(__dir__, "definitions.yml")), symbolize_names: true)
186
186
  end
187
+
188
+ def fake_uuid(*parts, separator: "->")
189
+ uuid = Digest::MD5.hexdigest(parts.join(separator))
190
+
191
+ segments = [8, 4, 4, 4, 12]
192
+ parts = segments.map do |n|
193
+ uuid[0...n].tap do
194
+ uuid = uuid[n..]
195
+ end
196
+ end
197
+
198
+ parts.join("-")
199
+ end
187
200
  end
188
201
  end
189
202
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grumlin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.23.0
4
+ version: 1.0.0.rc2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gleb Sinyavskiy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-09-08 00:00:00.000000000 Z
11
+ date: 2022-09-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async-pool
@@ -156,14 +156,18 @@ files:
156
156
  - lib/grumlin/features/tinkergraph_features.rb
157
157
  - lib/grumlin/middlewares/apply_shortcuts.rb
158
158
  - lib/grumlin/middlewares/build_query.rb
159
+ - lib/grumlin/middlewares/builder.rb
159
160
  - lib/grumlin/middlewares/cast_results.rb
160
- - lib/grumlin/middlewares/frozen_builder.rb
161
+ - lib/grumlin/middlewares/find_blocklisted_steps.rb
162
+ - lib/grumlin/middlewares/find_mutating_steps.rb
161
163
  - lib/grumlin/middlewares/middleware.rb
162
164
  - lib/grumlin/middlewares/run_query.rb
163
165
  - lib/grumlin/middlewares/serialize_to_bytecode.rb
164
166
  - lib/grumlin/middlewares/serialize_to_steps.rb
165
167
  - lib/grumlin/path.rb
166
168
  - lib/grumlin/property.rb
169
+ - lib/grumlin/query_validators/blocklisted_steps_validator.rb
170
+ - lib/grumlin/query_validators/validator.rb
167
171
  - lib/grumlin/repository.rb
168
172
  - lib/grumlin/repository/error_handling_strategy.rb
169
173
  - lib/grumlin/repository/instance_methods.rb
@@ -183,7 +187,6 @@ files:
183
187
  - lib/grumlin/steps_serializers/human_readable_bytecode.rb
184
188
  - lib/grumlin/steps_serializers/serializer.rb
185
189
  - lib/grumlin/steps_serializers/string.rb
186
- - lib/grumlin/sugar.rb
187
190
  - lib/grumlin/test/rspec.rb
188
191
  - lib/grumlin/test/rspec/db_cleaner_context.rb
189
192
  - lib/grumlin/test/rspec/gremlin_context.rb
@@ -218,9 +221,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
218
221
  version: 2.7.0
219
222
  required_rubygems_version: !ruby/object:Gem::Requirement
220
223
  requirements:
221
- - - ">="
224
+ - - ">"
222
225
  - !ruby/object:Gem::Version
223
- version: '0'
226
+ version: 1.3.1
224
227
  requirements: []
225
228
  rubygems_version: 3.2.33
226
229
  signing_key:
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Grumlin
4
- module Middlewares
5
- class FrozenBuilder < ::Middleware::Builder
6
- def initialize(opts = nil, &block)
7
- super(opts, &block)
8
- freeze
9
- end
10
-
11
- def freeze
12
- super
13
-
14
- stack.freeze
15
- end
16
- end
17
- end
18
- end
data/lib/grumlin/sugar.rb DELETED
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Grumlin
4
- module Sugar
5
- def self.included(base)
6
- base.include(Grumlin::Expressions)
7
- end
8
-
9
- %i[__ g].each do |name|
10
- define_method name do |cuts = Shortcuts::Storage.empty|
11
- cuts.send(name)
12
- end
13
- end
14
- end
15
- end