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.
- checksums.yaml +4 -4
- data/.rubocop.yml +9 -9
- data/Gemfile.lock +1 -1
- data/README.md +100 -142
- data/Rakefile +1 -1
- data/bin/console +18 -3
- data/doc/middlewares.md +49 -10
- data/lib/async/channel.rb +54 -56
- data/lib/grumlin/benchmark/repository.rb +10 -14
- data/lib/grumlin/client.rb +93 -95
- data/lib/grumlin/config.rb +33 -33
- data/lib/grumlin/dummy_transaction.rb +13 -15
- data/lib/grumlin/edge.rb +18 -20
- data/lib/grumlin/expressions/cardinality.rb +5 -9
- data/lib/grumlin/expressions/column.rb +5 -9
- data/lib/grumlin/expressions/expression.rb +7 -11
- data/lib/grumlin/expressions/operator.rb +5 -9
- data/lib/grumlin/expressions/order.rb +5 -9
- data/lib/grumlin/expressions/p.rb +27 -31
- data/lib/grumlin/expressions/pop.rb +5 -9
- data/lib/grumlin/expressions/scope.rb +5 -9
- data/lib/grumlin/expressions/t.rb +5 -9
- data/lib/grumlin/expressions/text_p.rb +5 -9
- data/lib/grumlin/expressions/with_options.rb +17 -21
- data/lib/grumlin/features/feature_list.rb +8 -12
- data/lib/grumlin/features/neptune_features.rb +5 -9
- data/lib/grumlin/features/tinkergraph_features.rb +5 -9
- data/lib/grumlin/features.rb +8 -10
- data/lib/grumlin/middlewares/apply_shortcuts.rb +4 -8
- data/lib/grumlin/middlewares/build_query.rb +16 -20
- data/lib/grumlin/middlewares/builder.rb +15 -0
- data/lib/grumlin/middlewares/cast_results.rb +3 -7
- data/lib/grumlin/middlewares/find_blocklisted_steps.rb +14 -0
- data/lib/grumlin/middlewares/find_mutating_steps.rb +9 -0
- data/lib/grumlin/middlewares/middleware.rb +6 -10
- data/lib/grumlin/middlewares/run_query.rb +3 -7
- data/lib/grumlin/middlewares/serialize_to_bytecode.rb +5 -9
- data/lib/grumlin/middlewares/serialize_to_steps.rb +4 -8
- data/lib/grumlin/path.rb +11 -13
- data/lib/grumlin/property.rb +14 -16
- data/lib/grumlin/query_validators/blocklisted_steps_validator.rb +22 -0
- data/lib/grumlin/query_validators/validator.rb +36 -0
- data/lib/grumlin/repository/error_handling_strategy.rb +36 -40
- data/lib/grumlin/repository/instance_methods.rb +115 -118
- data/lib/grumlin/repository.rb +82 -58
- data/lib/grumlin/request_dispatcher.rb +55 -57
- data/lib/grumlin/request_error_factory.rb +53 -55
- data/lib/grumlin/shortcut.rb +19 -21
- data/lib/grumlin/shortcuts/properties.rb +12 -16
- data/lib/grumlin/shortcuts/storage.rb +67 -74
- data/lib/grumlin/shortcuts/upserts.rb +19 -22
- data/lib/grumlin/shortcuts.rb +23 -25
- data/lib/grumlin/shortcuts_applyer.rb +27 -29
- data/lib/grumlin/step.rb +88 -90
- data/lib/grumlin/step_data.rb +12 -14
- data/lib/grumlin/steppable.rb +23 -25
- data/lib/grumlin/steps.rb +52 -54
- data/lib/grumlin/steps_serializers/bytecode.rb +53 -56
- data/lib/grumlin/steps_serializers/human_readable_bytecode.rb +17 -21
- data/lib/grumlin/steps_serializers/serializer.rb +7 -11
- data/lib/grumlin/steps_serializers/string.rb +26 -30
- data/lib/grumlin/test/rspec/db_cleaner_context.rb +8 -12
- data/lib/grumlin/test/rspec/gremlin_context.rb +18 -16
- data/lib/grumlin/test/rspec.rb +1 -5
- data/lib/grumlin/transaction.rb +34 -36
- data/lib/grumlin/transport.rb +71 -73
- data/lib/grumlin/traversal_start.rb +31 -33
- data/lib/grumlin/traversal_strategies/options_strategy.rb +3 -7
- data/lib/grumlin/traverser.rb +5 -7
- data/lib/grumlin/typed_value.rb +11 -13
- data/lib/grumlin/typing.rb +70 -72
- data/lib/grumlin/version.rb +1 -1
- data/lib/grumlin/vertex.rb +14 -16
- data/lib/grumlin/vertex_property.rb +14 -16
- data/lib/grumlin/with_extension.rb +17 -19
- data/lib/grumlin.rb +13 -0
- metadata +9 -6
- data/lib/grumlin/middlewares/frozen_builder.rb +0 -18
- data/lib/grumlin/sugar.rb +0 -15
data/lib/grumlin/client.rb
CHANGED
@@ -1,125 +1,123 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
class
|
5
|
-
|
6
|
-
attr_reader :client
|
7
|
-
|
8
|
-
def self.call
|
9
|
-
config = Grumlin.config
|
10
|
-
new(config.url, client_factory: config.client_factory, concurrency: config.client_concurrency)
|
11
|
-
end
|
12
|
-
|
13
|
-
def initialize(url, client_factory:, concurrency: 1, parent: Async::Task.current)
|
14
|
-
super(concurrency)
|
15
|
-
@client = client_factory.call(url, parent).tap(&:connect)
|
16
|
-
@parent = parent
|
17
|
-
end
|
3
|
+
class Grumlin::Client
|
4
|
+
class PoolResource < Async::Pool::Resource
|
5
|
+
attr_reader :client
|
18
6
|
|
19
|
-
|
20
|
-
|
21
|
-
|
7
|
+
def self.call
|
8
|
+
config = Grumlin.config
|
9
|
+
new(config.url, client_factory: config.client_factory, concurrency: config.client_concurrency)
|
10
|
+
end
|
22
11
|
|
23
|
-
|
24
|
-
|
25
|
-
|
12
|
+
def initialize(url, client_factory:, concurrency: 1, parent: Async::Task.current)
|
13
|
+
super(concurrency)
|
14
|
+
@client = client_factory.call(url, parent).tap(&:connect)
|
15
|
+
@parent = parent
|
16
|
+
end
|
26
17
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
@count += 1
|
31
|
-
end
|
18
|
+
def closed?
|
19
|
+
!@client.connected?
|
20
|
+
end
|
32
21
|
|
33
|
-
|
34
|
-
|
35
|
-
|
22
|
+
def close
|
23
|
+
@client.close
|
24
|
+
end
|
36
25
|
|
37
|
-
|
38
|
-
|
39
|
-
|
26
|
+
def write(query)
|
27
|
+
@client.write(query)
|
28
|
+
ensure
|
29
|
+
@count += 1
|
40
30
|
end
|
41
31
|
|
42
|
-
|
32
|
+
def viable?
|
33
|
+
!closed?
|
34
|
+
end
|
43
35
|
|
44
|
-
|
45
|
-
|
46
|
-
@url = url
|
47
|
-
@client_options = client_options
|
48
|
-
@parent = parent
|
49
|
-
@request_dispatcher = nil
|
50
|
-
@transport = nil
|
36
|
+
def reusable?
|
37
|
+
!closed?
|
51
38
|
end
|
39
|
+
end
|
52
40
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
41
|
+
include Console
|
42
|
+
|
43
|
+
# Client is not reusable. Once closed should be recreated.
|
44
|
+
def initialize(url, parent: Async::Task.current, **client_options)
|
45
|
+
@url = url
|
46
|
+
@client_options = client_options
|
47
|
+
@parent = parent
|
48
|
+
@request_dispatcher = nil
|
49
|
+
@transport = nil
|
50
|
+
end
|
51
|
+
|
52
|
+
def connect
|
53
|
+
raise ClientClosedError if @closed
|
54
|
+
|
55
|
+
@transport = build_transport
|
56
|
+
response_channel = @transport.connect
|
57
|
+
@request_dispatcher = Grumlin::RequestDispatcher.new
|
58
|
+
@response_task = @parent.async do
|
59
|
+
response_channel.each do |response|
|
60
|
+
@request_dispatcher.add_response(response)
|
65
61
|
end
|
66
|
-
|
62
|
+
rescue Async::Stop, Async::TimeoutError, StandardError
|
63
|
+
close(check_requests: false)
|
67
64
|
end
|
65
|
+
logger.debug(self, "Connected")
|
66
|
+
end
|
68
67
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
68
|
+
# Before calling close the user must ensure that:
|
69
|
+
# 1) There are no ongoing requests
|
70
|
+
# 2) There will be no new writes after
|
71
|
+
def close(check_requests: true) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
72
|
+
return if @closed
|
74
73
|
|
75
|
-
|
74
|
+
@closed = true
|
76
75
|
|
77
|
-
|
78
|
-
|
76
|
+
@transport&.close
|
77
|
+
@transport&.wait
|
79
78
|
|
80
|
-
|
81
|
-
|
79
|
+
@response_task&.stop
|
80
|
+
@response_task&.wait
|
82
81
|
|
83
|
-
|
82
|
+
return if @request_dispatcher&.requests&.empty?
|
84
83
|
|
85
|
-
|
84
|
+
@request_dispatcher.clear unless check_requests
|
86
85
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
86
|
+
raise ResourceLeakError, "Request list is not empty: #{@request_dispatcher.requests}" if check_requests
|
87
|
+
ensure
|
88
|
+
logger.debug(self, "Closed")
|
89
|
+
end
|
91
90
|
|
92
|
-
|
93
|
-
|
94
|
-
|
91
|
+
def connected?
|
92
|
+
@transport&.connected? || false
|
93
|
+
end
|
95
94
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
end
|
95
|
+
# TODO: support yielding
|
96
|
+
def write(query)
|
97
|
+
raise NotConnectedError unless connected?
|
98
|
+
|
99
|
+
channel = @request_dispatcher.add_request(query)
|
100
|
+
begin
|
101
|
+
@transport.write(query)
|
102
|
+
channel.dequeue
|
103
|
+
rescue Async::Stop, Async::TimeoutError
|
104
|
+
close(check_requests: false)
|
105
|
+
raise
|
108
106
|
end
|
107
|
+
end
|
109
108
|
|
110
|
-
|
111
|
-
|
112
|
-
|
109
|
+
def inspect
|
110
|
+
"<#{self.class} url=#{@url} connected=#{connected?}>"
|
111
|
+
end
|
113
112
|
|
114
|
-
|
115
|
-
|
116
|
-
|
113
|
+
def to_s
|
114
|
+
inspect
|
115
|
+
end
|
117
116
|
|
118
|
-
|
117
|
+
private
|
119
118
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
end
|
119
|
+
# This might be overridden in successors
|
120
|
+
def build_transport
|
121
|
+
Grumlin::Transport.new(@url, parent: @parent, **@client_options)
|
124
122
|
end
|
125
123
|
end
|
data/lib/grumlin/config.rb
CHANGED
@@ -1,41 +1,41 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
end.freeze
|
17
|
-
|
18
|
-
class ConfigurationError < Grumlin::Error; end
|
19
|
-
|
20
|
-
class UnknownProviderError < ConfigurationError; end
|
21
|
-
|
22
|
-
def initialize
|
23
|
-
@pool_size = 10
|
24
|
-
@client_concurrency = 5
|
25
|
-
@provider = :tinkergraph
|
26
|
-
@client_factory = ->(url, parent) { Grumlin::Client.new(url, parent: parent) }
|
27
|
-
end
|
3
|
+
class Grumlin::Config
|
4
|
+
attr_accessor :url, :pool_size, :client_concurrency, :client_factory, :provider
|
5
|
+
|
6
|
+
SUPPORTED_PROVIDERS = [:neptune, :tinkergraph].freeze
|
7
|
+
|
8
|
+
DEFAULT_MIDDLEWARES = Grumlin::Middlewares::Builder.new do |b|
|
9
|
+
b.use Grumlin::Middlewares::SerializeToSteps
|
10
|
+
b.use Grumlin::Middlewares::ApplyShortcuts
|
11
|
+
b.use Grumlin::Middlewares::SerializeToBytecode
|
12
|
+
b.use Grumlin::Middlewares::BuildQuery
|
13
|
+
b.use Grumlin::Middlewares::CastResults
|
14
|
+
b.use Grumlin::Middlewares::RunQuery
|
15
|
+
end
|
28
16
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
end
|
33
|
-
end
|
17
|
+
class ConfigurationError < Grumlin::Error; end
|
18
|
+
|
19
|
+
class UnknownProviderError < ConfigurationError; end
|
34
20
|
|
35
|
-
|
36
|
-
|
21
|
+
def initialize
|
22
|
+
@pool_size = 10
|
23
|
+
@client_concurrency = 5
|
24
|
+
@provider = :tinkergraph
|
25
|
+
@client_factory = ->(url, parent) { Grumlin::Client.new(url, parent: parent) }
|
26
|
+
end
|
37
27
|
|
38
|
-
|
28
|
+
def middlewares
|
29
|
+
@middlewares ||= Grumlin::Middlewares::Builder.new do |b|
|
30
|
+
b.use DEFAULT_MIDDLEWARES
|
39
31
|
end
|
32
|
+
yield(@middlewares) if block_given?
|
33
|
+
@middlewares
|
34
|
+
end
|
35
|
+
|
36
|
+
def validate!
|
37
|
+
return if SUPPORTED_PROVIDERS.include?(provider.to_sym)
|
38
|
+
|
39
|
+
raise UnknownProviderError, "provider '#{provider}' is unknown. Supported providers: #{SUPPORTED_PROVIDERS}"
|
40
40
|
end
|
41
41
|
end
|
@@ -1,25 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
attr_reader :uuid
|
3
|
+
class Grumlin::DummyTransaction < Grumlin::Transaction
|
4
|
+
attr_reader :uuid
|
6
5
|
|
7
|
-
|
6
|
+
include Console
|
8
7
|
|
9
|
-
|
10
|
-
|
8
|
+
def initialize(traversal_start_class, middlewares:, pool: nil) # rubocop:disable Lint/MissingSuper, Lint/UnusedMethodArgument
|
9
|
+
@traversal_start_class = traversal_start_class
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
end
|
11
|
+
logger.info(self) do
|
12
|
+
"#{Grumlin.config.provider} does not support transactions. commit and rollback are ignored, data will be saved"
|
15
13
|
end
|
14
|
+
end
|
16
15
|
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
def commit
|
17
|
+
nil
|
18
|
+
end
|
20
19
|
|
21
|
-
|
22
|
-
|
23
|
-
end
|
20
|
+
def rollback
|
21
|
+
nil
|
24
22
|
end
|
25
23
|
end
|
data/lib/grumlin/edge.rb
CHANGED
@@ -1,28 +1,26 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
attr_reader :label, :id, :inVLabel, :outVLabel, :inV, :outV
|
3
|
+
class Grumlin::Edge
|
4
|
+
attr_reader :label, :id, :inVLabel, :outVLabel, :inV, :outV
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
6
|
+
def initialize(label:, id:, inVLabel:, outVLabel:, inV:, outV:)
|
7
|
+
@label = label
|
8
|
+
@id = Grumlin::Typing.cast(id)
|
9
|
+
@inVLabel = inVLabel
|
10
|
+
@outVLabel = outVLabel
|
11
|
+
@inV = Grumlin::Typing.cast(inV)
|
12
|
+
@outV = Grumlin::Typing.cast(outV)
|
13
|
+
end
|
15
14
|
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
def ==(other)
|
16
|
+
self.class == other.class && @label == other.label && @id == other.id
|
17
|
+
end
|
19
18
|
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
def inspect
|
20
|
+
"e[#{@id}][#{@outV}-#{@label}->#{@inV}]"
|
21
|
+
end
|
23
22
|
|
24
|
-
|
25
|
-
|
26
|
-
end
|
23
|
+
def to_s
|
24
|
+
inspect
|
27
25
|
end
|
28
26
|
end
|
@@ -1,15 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module Grumlin
|
4
|
-
|
5
|
-
module Cardinality
|
6
|
-
SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :cardinality).map(&:to_sym).freeze
|
3
|
+
module Grumlin::Expressions::Cardinality
|
4
|
+
SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :cardinality).map(&:to_sym).freeze
|
7
5
|
|
8
|
-
|
9
|
-
|
6
|
+
class << self
|
7
|
+
extend Grumlin::Expressions::Expression
|
10
8
|
|
11
|
-
|
12
|
-
end
|
13
|
-
end
|
9
|
+
define_steps(SUPPORTED_STEPS, "Cardinality")
|
14
10
|
end
|
15
11
|
end
|
@@ -1,15 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module Grumlin
|
4
|
-
|
5
|
-
module Column
|
6
|
-
SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :column).map(&:to_sym).freeze
|
3
|
+
module Grumlin::Expressions::Column
|
4
|
+
SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :column).map(&:to_sym).freeze
|
7
5
|
|
8
|
-
|
9
|
-
|
6
|
+
class << self
|
7
|
+
extend Grumlin::Expressions::Expression
|
10
8
|
|
11
|
-
|
12
|
-
end
|
13
|
-
end
|
9
|
+
define_steps(SUPPORTED_STEPS, "Column")
|
14
10
|
end
|
15
11
|
end
|
@@ -1,17 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module Grumlin
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
name = "@#{step}"
|
10
|
-
return instance_variable_get(name) if instance_variable_defined?(name)
|
3
|
+
module Grumlin::Expressions::Expression
|
4
|
+
def define_steps(steps, tool_name)
|
5
|
+
steps.each do |step|
|
6
|
+
define_method step do
|
7
|
+
name = "@#{step}"
|
8
|
+
return instance_variable_get(name) if instance_variable_defined?(name)
|
11
9
|
|
12
|
-
|
13
|
-
end
|
14
|
-
end
|
10
|
+
instance_variable_set(name, Grumlin::TypedValue.new(type: tool_name, value: step))
|
15
11
|
end
|
16
12
|
end
|
17
13
|
end
|
@@ -1,15 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module Grumlin
|
4
|
-
|
5
|
-
module Operator
|
6
|
-
SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :operator).map(&:to_sym).freeze
|
3
|
+
module Grumlin::Expressions::Operator
|
4
|
+
SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :operator).map(&:to_sym).freeze
|
7
5
|
|
8
|
-
|
9
|
-
|
6
|
+
class << self
|
7
|
+
extend Grumlin::Expressions::Expression
|
10
8
|
|
11
|
-
|
12
|
-
end
|
13
|
-
end
|
9
|
+
define_steps(SUPPORTED_STEPS, "Operator")
|
14
10
|
end
|
15
11
|
end
|
@@ -1,15 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module Grumlin
|
4
|
-
|
5
|
-
module Order
|
6
|
-
SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :order).map(&:to_sym).freeze
|
3
|
+
module Grumlin::Expressions::Order
|
4
|
+
SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :order).map(&:to_sym).freeze
|
7
5
|
|
8
|
-
|
9
|
-
|
6
|
+
class << self
|
7
|
+
extend Grumlin::Expressions::Expression
|
10
8
|
|
11
|
-
|
12
|
-
end
|
13
|
-
end
|
9
|
+
define_steps(SUPPORTED_STEPS, "Order")
|
14
10
|
end
|
15
11
|
end
|
@@ -1,39 +1,35 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
class Predicate
|
7
|
-
attr_reader :namespace, :name, :value, :type
|
3
|
+
class Grumlin::Expressions::P
|
4
|
+
class Predicate
|
5
|
+
attr_reader :namespace, :name, :value, :type
|
8
6
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
7
|
+
def initialize(namespace, name, value:, type: nil)
|
8
|
+
@namespace = namespace
|
9
|
+
@name = name
|
10
|
+
@value = value
|
11
|
+
@type = type
|
12
|
+
end
|
13
|
+
end
|
16
14
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
15
|
+
class << self
|
16
|
+
# TODO: support more predicates
|
17
|
+
[:eq, :gt, :lt, :neq].each do |predicate|
|
18
|
+
define_method predicate do |*args|
|
19
|
+
Predicate.new("P", predicate, value: args[0])
|
20
|
+
end
|
21
|
+
end
|
24
22
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
end
|
36
|
-
end
|
23
|
+
[:within, :without].each do |predicate|
|
24
|
+
define_method predicate do |*args|
|
25
|
+
args = if args.count == 1 && args[0].is_a?(Array)
|
26
|
+
args[0]
|
27
|
+
elsif args.count == 1 && args[0].is_a?(Set)
|
28
|
+
args[0].to_a
|
29
|
+
else
|
30
|
+
args.to_a
|
31
|
+
end
|
32
|
+
Predicate.new("P", predicate, value: args, type: "List")
|
37
33
|
end
|
38
34
|
end
|
39
35
|
end
|
@@ -1,15 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module Grumlin
|
4
|
-
|
5
|
-
module Pop
|
6
|
-
SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :pop).map(&:to_sym).freeze
|
3
|
+
module Grumlin::Expressions::Pop
|
4
|
+
SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :pop).map(&:to_sym).freeze
|
7
5
|
|
8
|
-
|
9
|
-
|
6
|
+
class << self
|
7
|
+
extend Grumlin::Expressions::Expression
|
10
8
|
|
11
|
-
|
12
|
-
end
|
13
|
-
end
|
9
|
+
define_steps(SUPPORTED_STEPS, "Pop")
|
14
10
|
end
|
15
11
|
end
|
@@ -1,15 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module Grumlin
|
4
|
-
|
5
|
-
module Scope
|
6
|
-
SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :scope).map(&:to_sym).freeze
|
3
|
+
module Grumlin::Expressions::Scope
|
4
|
+
SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :scope).map(&:to_sym).freeze
|
7
5
|
|
8
|
-
|
9
|
-
|
6
|
+
class << self
|
7
|
+
extend Grumlin::Expressions::Expression
|
10
8
|
|
11
|
-
|
12
|
-
end
|
13
|
-
end
|
9
|
+
define_steps(SUPPORTED_STEPS, "Scope")
|
14
10
|
end
|
15
11
|
end
|
@@ -1,15 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module Grumlin
|
4
|
-
|
5
|
-
module T
|
6
|
-
SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :t).map(&:to_sym).freeze
|
3
|
+
module Grumlin::Expressions::T
|
4
|
+
SUPPORTED_STEPS = Grumlin.definitions.dig(:expressions, :t).map(&:to_sym).freeze
|
7
5
|
|
8
|
-
|
9
|
-
|
6
|
+
class << self
|
7
|
+
extend Grumlin::Expressions::Expression
|
10
8
|
|
11
|
-
|
12
|
-
end
|
13
|
-
end
|
9
|
+
define_steps(SUPPORTED_STEPS, "T")
|
14
10
|
end
|
15
11
|
end
|
@@ -1,14 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
define_method predicate do |*args|
|
9
|
-
P::Predicate.new("TextP", predicate, value: args[0])
|
10
|
-
end
|
11
|
-
end
|
3
|
+
class Grumlin::Expressions::TextP < Grumlin::Expressions::P
|
4
|
+
class << self
|
5
|
+
[:containing, :endingWith, :notContaining, :notEndingWith, :notStartingWith, :startingWith].each do |predicate|
|
6
|
+
define_method predicate do |*args|
|
7
|
+
P::Predicate.new("TextP", predicate, value: args[0])
|
12
8
|
end
|
13
9
|
end
|
14
10
|
end
|