grumlin 0.7.0 → 0.10.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4260297c3d75ec7bc1f987d8c7bad4efd75c81627814fdf984a0aaac0045332b
4
- data.tar.gz: 1cb521906a08cf5390f058a28f380492a2999e55ef023c473fc6bae64533b53b
3
+ metadata.gz: 2306eba516eebd5d53ac7e8e77acd5d7b2fcb7ad3579e9abc734210aec20ce29
4
+ data.tar.gz: ebd72733ea3f6ac4554044a00aac252f6a14997664a7b95ebdba01d082e4c8cd
5
5
  SHA512:
6
- metadata.gz: 992d2192402f3fe282203a3fd0eff1e6c886470899cb37f00ca2abf1392e4d946c7391be0eb7d6560c9941f7a17a3552682a8a47f56273f4299c06551c1e9ffc
7
- data.tar.gz: d8695e2485915cb7b4d37a755e42d20b6d7f575d906ae5a0aca5f508c01a104c08f7bb51a2285c9dac48a0091771882afeb405fd26e7802c4d48513274e2895f
6
+ metadata.gz: bda5181c00cabc8d69fdaa891a81943527dabfaa69ce70babbba6c1f11efc83b6f942d23d6aaf792d580f842ca7f64971986def6e1cfc1e6d4d3626da05efa1b
7
+ data.tar.gz: 212fbac76d50dfe281e574604ffbb82e8008937d777c279575a05468ee0f063faa6f0a8fa1417e8ea40e96f72b1b9f1f61c9e881e7c9b800d25964ce3ad7932a
data/Gemfile.lock CHANGED
@@ -1,9 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- grumlin (0.7.0)
4
+ grumlin (0.10.1)
5
5
  async-pool (~> 0.3)
6
6
  async-websocket (~> 0.19)
7
+ oj (~> 3.12)
8
+ zeitwerk (~> 2.4)
7
9
 
8
10
  GEM
9
11
  remote: https://rubygems.org/
@@ -62,6 +64,7 @@ GEM
62
64
  nio4r (2.5.8)
63
65
  nokogiri (1.11.7-x86_64-linux)
64
66
  racc (~> 1.4)
67
+ oj (3.13.6)
65
68
  overcommit (0.57.0)
66
69
  childprocess (>= 0.6.3, < 5)
67
70
  iniparse (~> 1.4)
data/grumlin.gemspec CHANGED
@@ -25,4 +25,6 @@ Gem::Specification.new do |spec|
25
25
 
26
26
  spec.add_dependency "async-pool", "~> 0.3"
27
27
  spec.add_dependency "async-websocket", "~> 0.19"
28
+ spec.add_dependency "oj", "~> 3.12"
29
+ spec.add_dependency "zeitwerk", "~> 2.4"
28
30
  end
@@ -2,43 +2,39 @@
2
2
 
3
3
  module Grumlin
4
4
  class AnonymousStep
5
- attr_reader :name, :args
5
+ attr_reader :name, :args, :previous_step
6
6
 
7
7
  # TODO: add other steps
8
8
  SUPPORTED_STEPS = %w[E V addE addV as by coalesce count dedup drop elementMap emit fold from group groupCount has
9
9
  hasId hasLabel hasNot in inV label limit not order out outE path project property repeat select
10
- to unfold valueMap values where].freeze
10
+ to unfold union valueMap values where].freeze
11
11
 
12
- def initialize(name, *args, previous_steps: [])
12
+ def initialize(name, *args, previous_step: nil)
13
13
  @name = name
14
- @previous_steps = previous_steps
14
+ @previous_step = previous_step
15
15
  @args = args
16
16
  end
17
17
 
18
18
  SUPPORTED_STEPS.each do |step|
19
- define_method step do |*args|
20
- add_step(step, args, previous_steps: steps)
19
+ define_method(step) do |*args|
20
+ add_step(step, args)
21
21
  end
22
22
  end
23
23
 
24
24
  def inspect
25
- @inspect ||= to_bytecode.to_s
25
+ bytecode.inspect
26
26
  end
27
27
 
28
28
  alias to_s inspect
29
29
 
30
- def to_bytecode
31
- @to_bytecode ||= (@previous_steps.last&.to_bytecode || []) + [Translator.to_bytecode(self)]
32
- end
33
-
34
- def steps
35
- (@previous_steps + [self])
30
+ def bytecode(no_return: false)
31
+ @bytecode ||= Bytecode.new(self, no_return: no_return)
36
32
  end
37
33
 
38
34
  private
39
35
 
40
- def add_step(step_name, args, previous_steps:)
41
- self.class.new(step_name, *args, previous_steps: previous_steps)
36
+ def add_step(step_name, args)
37
+ self.class.new(step_name, *args, previous_step: self)
42
38
  end
43
39
  end
44
40
  end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grumlin
4
+ # Incapsulates logic of converting step chains and step arguments to queries that can be sent to the server
5
+ # and to human readable strings.
6
+ class Bytecode
7
+ class NoneStep
8
+ def to_bytecode
9
+ ["none"]
10
+ end
11
+ end
12
+
13
+ NONE_STEP = NoneStep.new
14
+
15
+ def initialize(step, no_return: false)
16
+ @step = step
17
+ @no_return = no_return
18
+ end
19
+
20
+ def inspect
21
+ to_readable_bytecode.to_s
22
+ end
23
+ alias to_s inspect
24
+
25
+ def to_query
26
+ {
27
+ requestId: SecureRandom.uuid,
28
+ op: "bytecode",
29
+ processor: "traversal",
30
+ args: {
31
+ gremlin: to_bytecode,
32
+ aliases: { g: :g }
33
+ }
34
+ }
35
+ end
36
+
37
+ def to_readable_bytecode
38
+ @to_readable_bytecode ||= steps.map { |s| serialize_arg(s, serialization_method: :to_readable_bytecode) }
39
+ end
40
+
41
+ def to_bytecode
42
+ @to_bytecode ||= {
43
+ "@type": "g:Bytecode",
44
+ "@value": { step: (steps + (@no_return ? [NONE_STEP] : [])).map { |s| serialize_arg(s) } }
45
+ }
46
+ end
47
+
48
+ private
49
+
50
+ # Serializes step or a step argument to either an executable query or a human readable string representation
51
+ # depending on the `serialization_method` parameter. I should be either `:to_readable_bytecode` for human readable
52
+ # representation or `:to_bytecode` for query.
53
+ def serialize_arg(arg, serialization_method: :to_bytecode)
54
+ return arg.send(serialization_method) if arg.respond_to?(:to_bytecode)
55
+ return arg unless arg.is_a?(AnonymousStep)
56
+
57
+ arg.args.flatten.each.with_object([arg.name]) do |a, res|
58
+ res << if a.instance_of?(AnonymousStep)
59
+ a.bytecode.send(serialization_method)
60
+ else
61
+ serialize_arg(a, serialization_method: serialization_method)
62
+ end
63
+ end
64
+ end
65
+
66
+ def steps
67
+ @steps ||= [].tap do |result|
68
+ step = @step
69
+ until step.nil?
70
+ result.unshift(step)
71
+ step = step.previous_step
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -24,8 +24,8 @@ module Grumlin
24
24
  @client.close
25
25
  end
26
26
 
27
- def write(*args)
28
- @client.write(*args)
27
+ def write(bytecode)
28
+ @client.write(bytecode)
29
29
  ensure
30
30
  @count += 1
31
31
  end
@@ -94,11 +94,10 @@ module Grumlin
94
94
  end
95
95
 
96
96
  # TODO: support yielding
97
- def write(*args)
97
+ def write(bytecode)
98
98
  raise NotConnectedError unless connected?
99
99
 
100
- request_id = SecureRandom.uuid
101
- request = to_query(request_id, args)
100
+ request = bytecode.to_query
102
101
  channel = @request_dispatcher.add_request(request)
103
102
  @transport.write(request)
104
103
 
@@ -118,18 +117,6 @@ module Grumlin
118
117
 
119
118
  private
120
119
 
121
- def to_query(request_id, message)
122
- {
123
- requestId: request_id,
124
- op: "bytecode",
125
- processor: "traversal",
126
- args: {
127
- gremlin: Typing.to_bytecode(Translator.to_bytecode_query(message)),
128
- aliases: { g: :g }
129
- }
130
- }
131
- end
132
-
133
120
  def build_transport
134
121
  Transport.new(@url, parent: @parent, **@client_options)
135
122
  end
@@ -44,11 +44,11 @@ module Grumlin
44
44
 
45
45
  request = @requests[request_id]
46
46
 
47
- check_errors!(response[:status])
47
+ check_errors!(response[:status], request[:request])
48
48
 
49
49
  case SUCCESS[response.dig(:status, :code)]
50
50
  when :success
51
- request[:channel] << request[:result] + [response.dig(:result, :data)]
51
+ request[:channel] << [*request[:result], response.dig(:result, :data)]
52
52
  close_request(request_id)
53
53
  when :partial_content then request[:result] << response.dig(:result, :data)
54
54
  when :no_content
@@ -77,9 +77,9 @@ module Grumlin
77
77
 
78
78
  private
79
79
 
80
- def check_errors!(status)
80
+ def check_errors!(status, query)
81
81
  if (error = ERRORS[status[:code]])
82
- raise(error, status)
82
+ raise error.new(status, query)
83
83
  end
84
84
 
85
85
  return unless SUCCESS[status[:code]].nil?
data/lib/grumlin/step.rb CHANGED
@@ -4,32 +4,42 @@ module Grumlin
4
4
  class Step < AnonymousStep
5
5
  attr_reader :client
6
6
 
7
- def initialize(pool, name, *args, previous_steps: [])
8
- super(name, *args, previous_steps: previous_steps)
7
+ def initialize(pool, name, *args, previous_step: nil)
8
+ super(name, *args, previous_step: previous_step)
9
9
  @pool = pool
10
10
  end
11
11
 
12
12
  def next
13
- @enum ||= toList.to_enum
14
- @enum.next
13
+ to_enum.next
14
+ end
15
+
16
+ def hasNext # rubocop:disable Naming/MethodName
17
+ to_enum.peek
18
+ true
19
+ rescue StopIteration
20
+ false
21
+ end
22
+
23
+ def to_enum
24
+ @to_enum ||= toList.to_enum
15
25
  end
16
26
 
17
27
  def toList
18
28
  @pool.acquire do |client|
19
- client.write(*steps)
29
+ client.write(bytecode)
20
30
  end
21
31
  end
22
32
 
23
33
  def iterate
24
34
  @pool.acquire do |client|
25
- client.write(*(steps + [nil]))
35
+ client.write(bytecode(no_return: true))
26
36
  end
27
37
  end
28
38
 
29
39
  private
30
40
 
31
- def add_step(step_name, args, previous_steps:)
32
- self.class.new(@pool, step_name, *args, previous_steps: previous_steps)
41
+ def add_step(step_name, args)
42
+ self.class.new(@pool, step_name, *args, previous_step: self)
33
43
  end
34
44
  end
35
45
  end
@@ -18,8 +18,7 @@ module Grumlin
18
18
  end
19
19
 
20
20
  after do
21
- Grumlin.config.default_pool.close
22
- Grumlin.config.reset!
21
+ Grumlin.close
23
22
  end
24
23
  end
25
24
  end
@@ -7,7 +7,7 @@ module Grumlin
7
7
  # TODO: add other start steps
8
8
  SUPPORTED_START_STEPS = %w[E V addE addV].freeze
9
9
 
10
- def initialize(pool = Grumlin.config.default_pool)
10
+ def initialize(pool = Grumlin.default_pool)
11
11
  @pool = pool
12
12
  end
13
13
 
@@ -8,12 +8,14 @@ module Grumlin
8
8
  @value = value
9
9
  end
10
10
 
11
- def inspect(*)
12
- "#{@type}.#{@value}"
13
- end
14
-
15
11
  def to_bytecode
16
12
  @to_bytecode ||= { "@type": "g:#{@type}", "@value": @value }
17
13
  end
14
+
15
+ def inspect
16
+ "<#{@type}.#{@value}>"
17
+ end
18
+ alias to_s inspect
19
+ alias to_readable_bytecode inspect
18
20
  end
19
21
  end
@@ -31,19 +31,10 @@ module Grumlin
31
31
  type.call(value[:@value])
32
32
  end
33
33
 
34
- def to_bytecode(step)
35
- {
36
- "@type": "g:Bytecode",
37
- "@value": { step: step }
38
- }
39
- end
40
-
41
34
  private
42
35
 
43
- def castable_type?(value); end
44
-
45
36
  def verify_type!(value)
46
- raise TypeError, "#{value.inspect} cannot be casted" unless CASTABLE_TYPES.any? { |t| value.is_a?(t) }
37
+ raise TypeError, "#{value.inspect} cannot be casted" unless CASTABLE_TYPES.include?(value.class)
47
38
  end
48
39
 
49
40
  def verify_castable_hash!(value, type)
data/lib/grumlin/u.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  module Grumlin
4
4
  module U
5
5
  # TODO: add other start steps
6
- SUPPORTED_START_STEPS = %w[V addV count has out unfold values].freeze
6
+ SUPPORTED_START_STEPS = %w[V addV count fold has out repeat unfold values].freeze
7
7
 
8
8
  class << self
9
9
  SUPPORTED_START_STEPS.each do |step|
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Grumlin
4
- VERSION = "0.7.0"
4
+ VERSION = "0.10.1"
5
5
  end
data/lib/grumlin.rb CHANGED
@@ -1,7 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "securerandom"
4
- require "json"
4
+ require "oj"
5
+
6
+ Oj.mimic_JSON
7
+ Oj.add_to_json
5
8
 
6
9
  require "async"
7
10
  require "async/pool"
@@ -12,34 +15,87 @@ require "async/barrier"
12
15
  require "async/http/endpoint"
13
16
  require "async/websocket/client"
14
17
 
15
- require_relative "async/channel"
18
+ require "zeitwerk"
16
19
 
17
- require_relative "grumlin/version"
18
- require_relative "grumlin/exceptions"
20
+ loader = Zeitwerk::Loader.for_gem
21
+ loader.inflector.inflect(
22
+ "rspec" => "RSpec",
23
+ "db_cleaner_context" => "DBCleanerContext"
24
+ )
19
25
 
20
- require_relative "grumlin/transport"
21
- require_relative "grumlin/client"
22
- require_relative "grumlin/typed_value"
26
+ db_adapters = "#{__dir__}/grumlin/test"
27
+ loader.do_not_eager_load(db_adapters)
23
28
 
24
- require_relative "grumlin/vertex"
25
- require_relative "grumlin/edge"
26
- require_relative "grumlin/path"
27
- require_relative "grumlin/typing"
28
- require_relative "grumlin/traversal"
29
- require_relative "grumlin/request_dispatcher"
30
- require_relative "grumlin/translator"
29
+ module Grumlin
30
+ class Error < StandardError; end
31
31
 
32
- require_relative "grumlin/anonymous_step"
33
- require_relative "grumlin/step"
32
+ class UnknownError < Error; end
34
33
 
35
- require_relative "grumlin/t"
36
- require_relative "grumlin/order"
37
- require_relative "grumlin/u"
38
- require_relative "grumlin/p"
39
- require_relative "grumlin/pop"
40
- require_relative "grumlin/sugar"
34
+ class ConnectionError < Error; end
35
+
36
+ class CannotConnectError < ConnectionError; end
37
+
38
+ class DisconnectError < ConnectionError; end
39
+
40
+ class ConnectionStatusError < Error; end
41
+
42
+ class NotConnectedError < ConnectionStatusError; end
43
+
44
+ class AlreadyConnectedError < ConnectionStatusError; end
45
+
46
+ class ProtocolError < Error; end
47
+
48
+ class UnknownResponseStatus < ProtocolError
49
+ attr_reader :status
50
+
51
+ def initialize(status)
52
+ super("unknown response status code #{status[:code]}")
53
+ @status = status
54
+ end
55
+ end
56
+
57
+ class UnknownTypeError < ProtocolError; end
58
+
59
+ class StatusError < Error
60
+ attr_reader :status, :query
61
+
62
+ def initialize(status, query)
63
+ super(status[:message])
64
+ @status = status
65
+ @query = query
66
+ end
67
+ end
68
+
69
+ class ClientSideError < StatusError; end
70
+
71
+ class ServerSideError < StatusError; end
72
+
73
+ class ScriptEvaluationError < ServerSideError; end
74
+
75
+ class InvalidRequestArgumentsError < ServerSideError; end
76
+
77
+ class ServerError < ServerSideError; end
78
+
79
+ class ServerSerializationError < ServerSideError; end
80
+
81
+ class ServerTimeoutError < ServerSideError; end
82
+
83
+ class InternalClientError < Error; end
84
+
85
+ class UnknownRequestStoppedError < InternalClientError; end
86
+
87
+ class ResourceLeakError < InternalClientError; end
88
+
89
+ class UnknownMapKey < InternalClientError
90
+ attr_reader :key, :map
91
+
92
+ def initialize(key, map)
93
+ @key = key
94
+ @map = map
95
+ super("Cannot cast key #{key} in map #{map}")
96
+ end
97
+ end
41
98
 
42
- module Grumlin
43
99
  class Config
44
100
  attr_accessor :url, :pool_size, :client_concurrency, :client_factory
45
101
 
@@ -48,16 +104,10 @@ module Grumlin
48
104
  @client_concurrency = 5
49
105
  @client_factory = ->(url, parent) { Grumlin::Client.new(url, parent: parent) }
50
106
  end
51
-
52
- def default_pool
53
- @default_pool ||= Async::Pool::Controller.new(Grumlin::Client::PoolResource, limit: pool_size)
54
- end
55
-
56
- def reset!
57
- @default_pool = nil
58
- end
59
107
  end
60
108
 
109
+ @pool_mutex = Mutex.new
110
+
61
111
  class << self
62
112
  def configure
63
113
  yield config
@@ -66,5 +116,31 @@ module Grumlin
66
116
  def config
67
117
  @config ||= Config.new
68
118
  end
119
+
120
+ def default_pool
121
+ if Thread.current.thread_variable_get(:grumlin_default_pool)
122
+ return Thread.current.thread_variable_get(:grumlin_default_pool)
123
+ end
124
+
125
+ @pool_mutex.synchronize do
126
+ Thread.current.thread_variable_set(:grumlin_default_pool,
127
+ Async::Pool::Controller.new(Grumlin::Client::PoolResource,
128
+ limit: config.pool_size))
129
+ end
130
+ end
131
+
132
+ def close
133
+ return if Thread.current.thread_variable_get(:grumlin_default_pool).nil?
134
+
135
+ @pool_mutex.synchronize do
136
+ pool = Thread.current.thread_variable_get(:grumlin_default_pool)
137
+ pool.wait while pool.busy?
138
+ pool.close
139
+ Thread.current.thread_variable_set(:grumlin_default_pool, nil)
140
+ end
141
+ end
69
142
  end
70
143
  end
144
+
145
+ loader.setup
146
+ loader.eager_load
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.7.0
4
+ version: 0.10.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gleb Sinyavskiy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-06 00:00:00.000000000 Z
11
+ date: 2021-09-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async-pool
@@ -38,6 +38,34 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0.19'
41
+ - !ruby/object:Gem::Dependency
42
+ name: oj
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.12'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.12'
55
+ - !ruby/object:Gem::Dependency
56
+ name: zeitwerk
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.4'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.4'
41
69
  description: Gremlin query language DSL for Ruby.
42
70
  email:
43
71
  - zhulik.gleb@gmail.com
@@ -66,9 +94,9 @@ files:
66
94
  - lib/async/channel.rb
67
95
  - lib/grumlin.rb
68
96
  - lib/grumlin/anonymous_step.rb
97
+ - lib/grumlin/bytecode.rb
69
98
  - lib/grumlin/client.rb
70
99
  - lib/grumlin/edge.rb
71
- - lib/grumlin/exceptions.rb
72
100
  - lib/grumlin/order.rb
73
101
  - lib/grumlin/p.rb
74
102
  - lib/grumlin/path.rb
@@ -80,7 +108,6 @@ files:
80
108
  - lib/grumlin/test/rspec.rb
81
109
  - lib/grumlin/test/rspec/db_cleaner_context.rb
82
110
  - lib/grumlin/test/rspec/gremlin_context.rb
83
- - lib/grumlin/translator.rb
84
111
  - lib/grumlin/transport.rb
85
112
  - lib/grumlin/traversal.rb
86
113
  - lib/grumlin/typed_value.rb
@@ -1,71 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Grumlin
4
- class Error < StandardError; end
5
-
6
- class UnknownError < Error; end
7
-
8
- class ConnectionError < Error; end
9
-
10
- class CannotConnectError < ConnectionError; end
11
-
12
- class DisconnectError < ConnectionError; end
13
-
14
- class ConnectionStatusError < Error; end
15
-
16
- class NotConnectedError < ConnectionStatusError; end
17
-
18
- class AlreadyConnectedError < ConnectionStatusError; end
19
-
20
- class ProtocolError < Error; end
21
-
22
- class UnknownResponseStatus < ProtocolError
23
- attr_reader :status
24
-
25
- def initialize(status)
26
- super("unknown response status code #{status[:code]}")
27
- @status = status
28
- end
29
- end
30
-
31
- class UnknownTypeError < ProtocolError; end
32
-
33
- class StatusError < Error
34
- attr_reader :status
35
-
36
- def initialize(status)
37
- super(status[:message])
38
- @status = status
39
- end
40
- end
41
-
42
- class ClientSideError < StatusError; end
43
-
44
- class ServerSideError < StatusError; end
45
-
46
- class ScriptEvaluationError < ServerSideError; end
47
-
48
- class InvalidRequestArgumentsError < ServerSideError; end
49
-
50
- class ServerError < ServerSideError; end
51
-
52
- class ServerSerializationError < ServerSideError; end
53
-
54
- class ServerTimeoutError < ServerSideError; end
55
-
56
- class InternalClientError < Error; end
57
-
58
- class UnknownRequestStoppedError < InternalClientError; end
59
-
60
- class ResourceLeakError < InternalClientError; end
61
-
62
- class UnknownMapKey < InternalClientError
63
- attr_reader :key, :map
64
-
65
- def initialize(key, map)
66
- @key = key
67
- @map = map
68
- super("Cannot cast key #{key} in map #{map}")
69
- end
70
- end
71
- end
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Grumlin
4
- module Translator
5
- class << self
6
- def to_bytecode(steps)
7
- return arg_to_bytecode(steps) if steps.is_a?(AnonymousStep)
8
-
9
- steps.map do |step|
10
- arg_to_bytecode(step)
11
- end
12
- end
13
-
14
- def to_bytecode_query(steps)
15
- steps.map do |step|
16
- arg_to_query_bytecode(step)
17
- end
18
- end
19
-
20
- private
21
-
22
- def arg_to_bytecode(arg)
23
- return arg.to_bytecode if arg.is_a?(TypedValue)
24
- return arg unless arg.is_a?(AnonymousStep)
25
-
26
- args = arg.args.flatten.map do |a|
27
- a.instance_of?(AnonymousStep) ? to_bytecode(a.steps) : arg_to_bytecode(a)
28
- end
29
- [arg.name, *args]
30
- end
31
-
32
- def arg_to_query_bytecode(arg)
33
- return ["none"] if arg.nil?
34
- return arg.to_bytecode if arg.is_a?(TypedValue)
35
- return arg unless arg.is_a?(AnonymousStep)
36
-
37
- # return arg.to_bytecode if arg.is_a?(TypedValue)
38
-
39
- args = arg.args.flatten.map do |a|
40
- a.instance_of?(AnonymousStep) ? Typing.to_bytecode(to_bytecode(a.steps)) : arg_to_query_bytecode(a)
41
- end
42
- [arg.name, *args]
43
- end
44
- end
45
- end
46
- end