grumlin 0.8.0 → 0.11.0
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/Gemfile.lock +2 -2
- data/lib/grumlin/anonymous_step.rb +1 -1
- data/lib/grumlin/bytecode.rb +5 -18
- data/lib/grumlin/client.rb +13 -1
- data/lib/grumlin/order.rb +1 -1
- data/lib/grumlin/p.rb +34 -6
- data/lib/grumlin/pop.rb +1 -1
- data/lib/grumlin/request_dispatcher.rb +3 -3
- data/lib/grumlin/step.rb +12 -2
- data/lib/grumlin/t.rb +1 -1
- data/lib/grumlin/typed_value.rb +12 -4
- data/lib/grumlin/u.rb +1 -1
- data/lib/grumlin/version.rb +1 -1
- data/lib/grumlin.rb +22 -15
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0f0edafd4d46b787eb3f8e0ec4032948bdb4de865e4de3199606fb470dc16ef3
|
4
|
+
data.tar.gz: f23ba59dfb18dabe70fc860c38ea4c1777214b4a37e04771b24210d90f449612
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4629a25995953c6617a45721d7082baee59b76425636f6a4536308220bae3e7cb72b571317102339b1888c0e430dbe73320c12f44518940f45c67db829a9a265
|
7
|
+
data.tar.gz: fae1a56f95150f82da47a886da5e4b4a7ab0f725f66e68af61f6456c9a2f1af2cefc580ebf793cba612f0ceeda0b782361476a38511019062cc1534ad98fdb3c
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
grumlin (0.
|
4
|
+
grumlin (0.11.0)
|
5
5
|
async-pool (~> 0.3)
|
6
6
|
async-websocket (~> 0.19)
|
7
7
|
oj (~> 3.12)
|
@@ -64,7 +64,7 @@ GEM
|
|
64
64
|
nio4r (2.5.8)
|
65
65
|
nokogiri (1.11.7-x86_64-linux)
|
66
66
|
racc (~> 1.4)
|
67
|
-
oj (3.13.
|
67
|
+
oj (3.13.6)
|
68
68
|
overcommit (0.57.0)
|
69
69
|
childprocess (>= 0.6.3, < 5)
|
70
70
|
iniparse (~> 1.4)
|
@@ -7,7 +7,7 @@ module Grumlin
|
|
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
12
|
def initialize(name, *args, previous_step: nil)
|
13
13
|
@name = name
|
data/lib/grumlin/bytecode.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
module Grumlin
|
4
4
|
# Incapsulates logic of converting step chains and step arguments to queries that can be sent to the server
|
5
5
|
# and to human readable strings.
|
6
|
-
class Bytecode
|
6
|
+
class Bytecode < TypedValue
|
7
7
|
class NoneStep
|
8
8
|
def to_bytecode
|
9
9
|
["none"]
|
@@ -13,6 +13,8 @@ module Grumlin
|
|
13
13
|
NONE_STEP = NoneStep.new
|
14
14
|
|
15
15
|
def initialize(step, no_return: false)
|
16
|
+
super(type: "Bytecode")
|
17
|
+
|
16
18
|
@step = step
|
17
19
|
@no_return = no_return
|
18
20
|
end
|
@@ -22,27 +24,12 @@ module Grumlin
|
|
22
24
|
end
|
23
25
|
alias to_s inspect
|
24
26
|
|
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
27
|
def to_readable_bytecode
|
38
28
|
@to_readable_bytecode ||= steps.map { |s| serialize_arg(s, serialization_method: :to_readable_bytecode) }
|
39
29
|
end
|
40
30
|
|
41
|
-
def
|
42
|
-
@
|
43
|
-
"@type": "g:Bytecode",
|
44
|
-
"@value": { step: (steps + (@no_return ? [NONE_STEP] : [])).map { |s| serialize_arg(s) } }
|
45
|
-
}
|
31
|
+
def value
|
32
|
+
{ step: (steps + (@no_return ? [NONE_STEP] : [])).map { |s| serialize_arg(s) } }
|
46
33
|
end
|
47
34
|
|
48
35
|
private
|
data/lib/grumlin/client.rb
CHANGED
@@ -97,7 +97,7 @@ module Grumlin
|
|
97
97
|
def write(bytecode)
|
98
98
|
raise NotConnectedError unless connected?
|
99
99
|
|
100
|
-
request = bytecode.
|
100
|
+
request = to_query(bytecode.to_bytecode)
|
101
101
|
channel = @request_dispatcher.add_request(request)
|
102
102
|
@transport.write(request)
|
103
103
|
|
@@ -120,5 +120,17 @@ module Grumlin
|
|
120
120
|
def build_transport
|
121
121
|
Transport.new(@url, parent: @parent, **@client_options)
|
122
122
|
end
|
123
|
+
|
124
|
+
def to_query(bytecode)
|
125
|
+
{
|
126
|
+
requestId: SecureRandom.uuid,
|
127
|
+
op: "bytecode",
|
128
|
+
processor: "traversal",
|
129
|
+
args: {
|
130
|
+
gremlin: bytecode,
|
131
|
+
aliases: { g: :g }
|
132
|
+
}
|
133
|
+
}
|
134
|
+
end
|
123
135
|
end
|
124
136
|
end
|
data/lib/grumlin/order.rb
CHANGED
@@ -9,7 +9,7 @@ module Grumlin
|
|
9
9
|
name = "@#{step}"
|
10
10
|
return instance_variable_get(name) if instance_variable_defined?(name)
|
11
11
|
|
12
|
-
instance_variable_set(name, TypedValue.new("Order", step))
|
12
|
+
instance_variable_set(name, TypedValue.new(type: "Order", value: step))
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
data/lib/grumlin/p.rb
CHANGED
@@ -3,12 +3,40 @@
|
|
3
3
|
module Grumlin
|
4
4
|
module P
|
5
5
|
module P
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
6
|
+
class Predicate < TypedValue
|
7
|
+
def initialize(name, args:, arg_type: nil)
|
8
|
+
super(type: "P")
|
9
|
+
@name = name
|
10
|
+
@args = args
|
11
|
+
@arg_type = arg_type
|
12
|
+
end
|
13
|
+
|
14
|
+
def value
|
15
|
+
@value ||=
|
16
|
+
{
|
17
|
+
predicate: @name,
|
18
|
+
value: TypedValue.new(type: @arg_type, value: @args).to_bytecode
|
19
|
+
}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# TODO: support more predicates
|
24
|
+
%w[eq neq].each do |predicate|
|
25
|
+
define_method predicate do |*args|
|
26
|
+
Predicate.new(predicate, args: args[0])
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
%w[within without].each do |predicate|
|
31
|
+
define_method predicate do |*args|
|
32
|
+
args = if args.count == 1 && args[0].is_a?(Array)
|
33
|
+
args[0]
|
34
|
+
elsif args.count == 1 && args[0].is_a?(Set)
|
35
|
+
args[0].to_a
|
36
|
+
else
|
37
|
+
args.to_a
|
38
|
+
end
|
39
|
+
Predicate.new(predicate, args: args, arg_type: "List")
|
12
40
|
end
|
13
41
|
end
|
14
42
|
end
|
data/lib/grumlin/pop.rb
CHANGED
@@ -9,7 +9,7 @@ module Grumlin
|
|
9
9
|
name = "@#{step}"
|
10
10
|
return instance_variable_get(name) if instance_variable_defined?(name)
|
11
11
|
|
12
|
-
instance_variable_set(name, TypedValue.new("Pop", step))
|
12
|
+
instance_variable_set(name, TypedValue.new(type: "Pop", value: step))
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
@@ -44,7 +44,7 @@ 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
|
@@ -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(
|
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
@@ -10,8 +10,18 @@ module Grumlin
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def next
|
13
|
-
|
14
|
-
|
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
|
data/lib/grumlin/t.rb
CHANGED
data/lib/grumlin/typed_value.rb
CHANGED
@@ -1,19 +1,27 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Grumlin
|
4
|
-
# TODO: find a better name
|
5
4
|
class TypedValue
|
6
|
-
|
5
|
+
attr_reader :type, :value
|
6
|
+
|
7
|
+
def initialize(type: nil, value: nil)
|
7
8
|
@type = type
|
8
9
|
@value = value
|
9
10
|
end
|
10
11
|
|
11
12
|
def to_bytecode
|
12
|
-
@to_bytecode ||=
|
13
|
+
@to_bytecode ||= if type.nil?
|
14
|
+
value
|
15
|
+
else
|
16
|
+
{
|
17
|
+
"@type": "g:#{type}",
|
18
|
+
"@value": value
|
19
|
+
}
|
20
|
+
end
|
13
21
|
end
|
14
22
|
|
15
23
|
def inspect
|
16
|
-
"<#{
|
24
|
+
"<#{type}.#{value}>"
|
17
25
|
end
|
18
26
|
alias to_s inspect
|
19
27
|
alias to_readable_bytecode inspect
|
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|
|
data/lib/grumlin/version.rb
CHANGED
data/lib/grumlin.rb
CHANGED
@@ -57,11 +57,12 @@ module Grumlin
|
|
57
57
|
class UnknownTypeError < ProtocolError; end
|
58
58
|
|
59
59
|
class StatusError < Error
|
60
|
-
attr_reader :status
|
60
|
+
attr_reader :status, :query
|
61
61
|
|
62
|
-
def initialize(status)
|
62
|
+
def initialize(status, query)
|
63
63
|
super(status[:message])
|
64
64
|
@status = status
|
65
|
+
@query = query
|
65
66
|
end
|
66
67
|
end
|
67
68
|
|
@@ -103,16 +104,10 @@ module Grumlin
|
|
103
104
|
@client_concurrency = 5
|
104
105
|
@client_factory = ->(url, parent) { Grumlin::Client.new(url, parent: parent) }
|
105
106
|
end
|
106
|
-
|
107
|
-
def default_pool
|
108
|
-
@default_pool ||= Async::Pool::Controller.new(Grumlin::Client::PoolResource, limit: pool_size)
|
109
|
-
end
|
110
|
-
|
111
|
-
def reset!
|
112
|
-
@default_pool = nil
|
113
|
-
end
|
114
107
|
end
|
115
108
|
|
109
|
+
@pool_mutex = Mutex.new
|
110
|
+
|
116
111
|
class << self
|
117
112
|
def configure
|
118
113
|
yield config
|
@@ -123,14 +118,26 @@ module Grumlin
|
|
123
118
|
end
|
124
119
|
|
125
120
|
def default_pool
|
126
|
-
|
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
|
127
130
|
end
|
128
131
|
|
129
132
|
def close
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
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
|
134
141
|
end
|
135
142
|
end
|
136
143
|
end
|
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.
|
4
|
+
version: 0.11.0
|
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-
|
11
|
+
date: 2021-09-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: async-pool
|