grumlin 0.10.1 → 0.12.2

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: 2306eba516eebd5d53ac7e8e77acd5d7b2fcb7ad3579e9abc734210aec20ce29
4
- data.tar.gz: ebd72733ea3f6ac4554044a00aac252f6a14997664a7b95ebdba01d082e4c8cd
3
+ metadata.gz: 6680811a534db293d53fb8a190e11334e556866007cea69755e5c4be939849e2
4
+ data.tar.gz: 8e2aaf55bb9355e0440a02f5da6d079a2d5c6dda58a202b63d4d915eff0cebaf
5
5
  SHA512:
6
- metadata.gz: bda5181c00cabc8d69fdaa891a81943527dabfaa69ce70babbba6c1f11efc83b6f942d23d6aaf792d580f842ca7f64971986def6e1cfc1e6d4d3626da05efa1b
7
- data.tar.gz: 212fbac76d50dfe281e574604ffbb82e8008937d777c279575a05468ee0f063faa6f0a8fa1417e8ea40e96f72b1b9f1f61c9e881e7c9b800d25964ce3ad7932a
6
+ metadata.gz: 989ec9a52a001458862ba4ecec9f2c5cee791e4a9b285115088db535696bd65ec2be1f60814a16383e8072d1ce2dad8678bc744340d0ee59a76a8e54db5ad99b
7
+ data.tar.gz: 4bf8b71a4bec8a741f0f700408dcf00e49b7b393b34f2fca432a6682a742990195cb7fb9490d6d4dc6cfd07cc63e278a06f365a7113f540ad6fdf48f463629aa
@@ -65,7 +65,7 @@ jobs:
65
65
  mkdir ~/.gem
66
66
  cat << EOF > ~/.gem/credentials
67
67
  ---
68
- :rubygems_api_key: ${{ secrets.rubygems_api_key }}
68
+ :rubygems_api_key: ${{ secrets.RUBYGEMS_TOKEN }}
69
69
  EOF
70
70
  chmod 0600 /home/runner/.gem/credentials
71
71
 
data/Gemfile CHANGED
@@ -14,5 +14,6 @@ gem "solargraph"
14
14
  gem "async-rspec"
15
15
  gem "factory_bot"
16
16
  gem "overcommit"
17
+ gem "rake"
17
18
  gem "rspec"
18
19
  gem "simplecov"
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- grumlin (0.10.1)
4
+ grumlin (0.12.2)
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.6)
67
+ oj (3.13.7)
68
68
  overcommit (0.57.0)
69
69
  childprocess (>= 0.6.3, < 5)
70
70
  iniparse (~> 1.4)
@@ -83,6 +83,7 @@ GEM
83
83
  protocol-http1 (~> 0.2)
84
84
  racc (1.5.2)
85
85
  rainbow (3.0.0)
86
+ rake (13.0.3)
86
87
  regexp_parser (2.1.1)
87
88
  reverse_markdown (2.0.0)
88
89
  nokogiri
@@ -161,6 +162,7 @@ DEPENDENCIES
161
162
  grumlin!
162
163
  nokogiri
163
164
  overcommit
165
+ rake
164
166
  rspec
165
167
  rubocop
166
168
  rubocop-performance
data/README.md CHANGED
@@ -1,10 +1,30 @@
1
1
  # Grumlin
2
2
 
3
- [Gremlin](https://tinkerpop.apache.org/gremlin.html) query language DSL for Ruby
3
+ [![Ruby](https://github.com/zhulik/grumlin/actions/workflows/main.yml/badge.svg)](https://github.com/zhulik/grumlin/actions/workflows/main.yml)
4
+ [![standard-readme compliant](https://img.shields.io/badge/readme%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme)
5
+ [![MIT license](https://img.shields.io/badge/License-MIT-blue.svg)](https://lbesson.mit-license.org/)
4
6
 
5
- **In development. Nothing to write here yet. If you are really interested, check out the source code and the specs.**
7
+ Grumlin is a [Gremlin](https://tinkerpop.apache.org/gremlin.html) graph traversal language DSL and client for Ruby.
8
+ Suitable for and tested with [gremlin-server](http://tinkerpop.apache.org/) and [AWS Neptune](https://aws.amazon.com/neptune/).
6
9
 
7
- ## Installation
10
+ **Important**: Grumlin and it's author are not affiliated with The Apache Software Foundation which develops gremlin
11
+ and gremlin-server.
12
+
13
+ **Important**: Grumlin is based on the [async stack](https://github.com/socketry/async) and utilizes
14
+ [async-websocket](https://github.com/socketry/async-websocket). Code using grumlin must be executed in an async
15
+ event loop.
16
+
17
+ **Warning:** Grumlin is in development, but ready for simple use cases
18
+
19
+ ## Table of contents
20
+ - [Install](#install)
21
+ - [Usage](#usage)
22
+ - [Development](#development)
23
+ - [Contributing](#contributing)
24
+ - [License](#license)
25
+ - [Code Of Conduct](#code-of-conduct)
26
+
27
+ ## Install
8
28
 
9
29
  Add this line to your application's Gemfile:
10
30
 
@@ -22,17 +42,77 @@ Or install it yourself as:
22
42
 
23
43
  ## Usage
24
44
 
25
- TODO: Write usage instructions here
45
+ ### Configuration
46
+ ```ruby
47
+ Grumlin.configure do |config|
48
+ config.url = "ws://localhost:8182/gremlin"
49
+ end
50
+ ```
51
+
52
+ ### Traversing graphs
53
+
54
+ **Warning:** Not all steps and tools described in the standard are supported
55
+
56
+ #### Sugar
57
+
58
+ Grumlin provides an easy to use module called `Grumlin::Sugar`. Once included in your class it injects some useful
59
+ constants and methods turning your class into an entrypoint for traversals.
60
+
61
+ ```ruby
62
+ class MyRepository
63
+ include Grumlin::Sugar
64
+
65
+ def nodes(property1:, property2:)
66
+ g.V()
67
+ .has(T.label, "node")
68
+ .has(:property1, property1)
69
+ .has(:property2, property2)
70
+ .order.by(:property3, Order.asc).limit(10)
71
+ .toList
72
+ end
73
+ end
74
+ ```
75
+
76
+ #### Testing
77
+
78
+ Grumlin provides a couple of helpers to simplify testing code written with it.
79
+
80
+ ##### RSpec
81
+
82
+ Make sure you have [async-rspec](https://github.com/socketry/async-rspec) installed.
83
+
84
+ `spec_helper.rb` or `rails_helper.rb`:
85
+ ```ruby
86
+ require 'async/rspec'
87
+ require require "grumlin/test/rspec"
88
+ ...
89
+ config.include_context(Async::RSpec::Reactor) # Runs async reactor
90
+ config.include_context(Grumlin::Test::RSpec::GremlinContext) # Injects sugar and makes sure client is closed after every test
91
+ config.include_context(Grumlin::Test::RSpec::DBCleanerContext) # Cleans the database before every test
92
+ ...
93
+ ```
94
+
95
+ It is highly recommended to use `Grumlin::Sugar` and not trying to use lower level APIs as they are subject to change.
26
96
 
27
97
  ## Development
28
98
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
99
+ Before running tests make sure you have gremlin-server running on your computer. The simplest way to run it is using
100
+ [docker-compose](https://docs.docker.com/compose/) and provided `docker-compose.yml` and `gremlin_server/Dockerfile`:
101
+
102
+ $ docker-compose up -d gremlin_server
103
+
104
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests.
105
+ You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
106
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
107
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update
108
+ the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version,
109
+ push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
110
 
33
111
  ## Contributing
34
112
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/grumlin. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/grumlin/blob/master/CODE_OF_CONDUCT.md).
113
+ Bug reports and pull requests are welcome on GitHub at https://github.com/zhulik/grumlin. This project is intended to
114
+ be a safe, welcoming space for collaboration, and contributors are expected to adhere to the
115
+ [code of conduct](https://github.com/zhulik/grumlin/blob/master/CODE_OF_CONDUCT.md).
36
116
 
37
117
  ## License
38
118
 
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "rubocop/rake_task"
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[spec rubocop]
data/bin/console CHANGED
@@ -19,5 +19,5 @@ Async do
19
19
  rescue StandardError
20
20
  raise
21
21
  ensure
22
- Grumlin.config.default_pool.close
22
+ Grumlin.close
23
23
  end
data/grumlin.gemspec CHANGED
@@ -8,8 +8,12 @@ Gem::Specification.new do |spec|
8
8
  spec.authors = ["Gleb Sinyavskiy"]
9
9
  spec.email = ["zhulik.gleb@gmail.com"]
10
10
 
11
- spec.summary = "Gremlin query language DSL for Ruby."
12
- spec.description = "Gremlin query language DSL for Ruby."
11
+ spec.summary = "Gremlin graph traversal language DSL and client for Ruby."
12
+
13
+ spec.description = <<~DESCRIPTION
14
+ Gremlin graph traversal language DSL and client for Ruby. Suitable and tested with gremlin-server and AWS Neptune.
15
+ DESCRIPTION
16
+
13
17
  spec.homepage = "https://github.com/zhulik/grumlin"
14
18
  spec.license = "MIT"
15
19
  spec.required_ruby_version = Gem::Requirement.new(">= 2.6.0")
data/lib/async/channel.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  module Async
4
4
  # Channel is a wrapper around Async::Queue that provides
5
5
  # a protocol and handy tools for passing data, exceptions and closing.
6
- # It is designed to be used with only one publisher and one subscriber
6
+ # It is designed to be used only with one publisher and one subscriber
7
7
  class Channel
8
8
  class ChannelError < StandardError; end
9
9
 
@@ -5,9 +5,10 @@ module Grumlin
5
5
  attr_reader :name, :args, :previous_step
6
6
 
7
7
  # TODO: add other steps
8
- SUPPORTED_STEPS = %w[E V addE addV as by coalesce count dedup drop elementMap emit fold from group groupCount has
9
- hasId hasLabel hasNot in inV label limit not order out outE path project property repeat select
10
- to unfold union valueMap values where].freeze
8
+ SUPPORTED_STEPS = %i[E V addE addV as both by coalesce count dedup drop elementMap emit fold from group groupCount
9
+ has hasId hasLabel hasNot id in inE inV label limit not order out outE path project property
10
+ range repeat select sideEffect skip tail to unfold union until valueMap values where
11
+ with].freeze
11
12
 
12
13
  def initialize(name, *args, previous_step: nil)
13
14
  @name = name
@@ -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 to_bytecode
42
- @to_bytecode ||= {
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
@@ -51,10 +38,10 @@ module Grumlin
51
38
  # depending on the `serialization_method` parameter. I should be either `:to_readable_bytecode` for human readable
52
39
  # representation or `:to_bytecode` for query.
53
40
  def serialize_arg(arg, serialization_method: :to_bytecode)
54
- return arg.send(serialization_method) if arg.respond_to?(:to_bytecode)
41
+ return arg.send(serialization_method) if arg.respond_to?(serialization_method)
55
42
  return arg unless arg.is_a?(AnonymousStep)
56
43
 
57
- arg.args.flatten.each.with_object([arg.name]) do |a, res|
44
+ arg.args.flatten.each.with_object([arg.name.to_s]) do |a, res|
58
45
  res << if a.instance_of?(AnonymousStep)
59
46
  a.bytecode.send(serialization_method)
60
47
  else
@@ -97,7 +97,7 @@ module Grumlin
97
97
  def write(bytecode)
98
98
  raise NotConnectedError unless connected?
99
99
 
100
- request = bytecode.to_query
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/edge.rb CHANGED
@@ -18,7 +18,7 @@ module Grumlin
18
18
  end
19
19
 
20
20
  def inspect
21
- "e[#{@id}][#{@inV}-#{@label}->#{@outV}]"
21
+ "e[#{@id}][#{@outV}-#{@label}->#{@inV}]"
22
22
  end
23
23
  alias to_s inspect
24
24
  end
data/lib/grumlin/path.rb CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  module Grumlin
4
4
  class Path
5
+ attr_reader :objects
6
+
5
7
  def initialize(path)
6
8
  @labels = Typing.cast(path[:labels])
7
9
  @objects = Typing.cast(path[:objects])
data/lib/grumlin/sugar.rb CHANGED
@@ -3,11 +3,13 @@
3
3
  module Grumlin
4
4
  module Sugar
5
5
  HELPERS = [
6
- Grumlin::U,
7
- Grumlin::T,
8
- Grumlin::P,
9
- Grumlin::Pop,
10
- Grumlin::Order
6
+ Grumlin::Tools::Order,
7
+ Grumlin::Tools::P,
8
+ Grumlin::Tools::Pop,
9
+ Grumlin::Tools::Scope,
10
+ Grumlin::Tools::T,
11
+ Grumlin::Tools::U,
12
+ Grumlin::Tools::WithOptions
11
13
  ].freeze
12
14
 
13
15
  def self.included(base)
@@ -18,7 +20,7 @@ module Grumlin
18
20
  end
19
21
 
20
22
  def __
21
- Grumlin::U
23
+ Grumlin::Tools::U
22
24
  end
23
25
 
24
26
  def g
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grumlin
4
+ module Tools
5
+ module Order
6
+ extend Tool
7
+
8
+ SUPPORTED_STEPS = %i[asc desc].freeze
9
+
10
+ define_steps(SUPPORTED_STEPS, "Order")
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grumlin
4
+ module Tools
5
+ module P
6
+ class << self
7
+ class Predicate < TypedValue
8
+ def initialize(name, args:, arg_type: nil)
9
+ super(type: "P")
10
+ @name = name
11
+ @args = args
12
+ @arg_type = arg_type
13
+ end
14
+
15
+ def value
16
+ @value ||= {
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
+ %i[eq neq].each do |predicate|
25
+ define_method predicate do |*args|
26
+ Predicate.new(predicate, args: args[0])
27
+ end
28
+ end
29
+
30
+ %i[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")
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grumlin
4
+ module Tools
5
+ module Pop
6
+ extend Tool
7
+
8
+ SUPPORTED_STEPS = %i[all first last mixed].freeze
9
+
10
+ define_steps(SUPPORTED_STEPS, "Pop")
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grumlin
4
+ module Tools
5
+ module Scope
6
+ extend Tool
7
+
8
+ SUPPORTED_STEPS = %i[local].freeze
9
+
10
+ define_steps(SUPPORTED_STEPS, "Scope")
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grumlin
4
+ module Tools
5
+ module T
6
+ extend Tool
7
+
8
+ SUPPORTED_STEPS = %i[id label].freeze
9
+
10
+ define_steps(SUPPORTED_STEPS, "T")
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grumlin
4
+ module Tools
5
+ module Tool
6
+ def define_steps(steps, tool_name)
7
+ steps.each do |step|
8
+ self.class.define_method step do
9
+ name = "@#{step}"
10
+ return instance_variable_get(name) if instance_variable_defined?(name)
11
+
12
+ instance_variable_set(name, TypedValue.new(type: tool_name, value: step))
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grumlin
4
+ module Tools
5
+ module U
6
+ # TODO: add other start steps
7
+ SUPPORTED_STEPS = %i[V addV count drop fold has id inE inV label out outV project repeat timeLimit unfold valueMap
8
+ values].freeze
9
+
10
+ class << self
11
+ SUPPORTED_STEPS.each do |step|
12
+ define_method step do |*args|
13
+ AnonymousStep.new(step, *args)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grumlin
4
+ module Tools
5
+ module WithOptions
6
+ WITH_OPTIONS = {
7
+ tokens: "~tinkerpop.valueMap.tokens",
8
+ none: 0,
9
+ ids: 1,
10
+ labels: 2,
11
+ keys: 4,
12
+ values: 8,
13
+ all: 15,
14
+ indexer: "~tinkerpop.index.indexer",
15
+ list: 0,
16
+ map: 1
17
+ }.freeze
18
+
19
+ class << self
20
+ WITH_OPTIONS.each do |k, v|
21
+ define_method k do
22
+ v
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -2,16 +2,14 @@
2
2
 
3
3
  module Grumlin
4
4
  class Traversal
5
- attr_reader :connection
6
-
7
5
  # TODO: add other start steps
8
- SUPPORTED_START_STEPS = %w[E V addE addV].freeze
6
+ SUPPORTED_STEPS = %i[E V addE addV].freeze
9
7
 
10
8
  def initialize(pool = Grumlin.default_pool)
11
9
  @pool = pool
12
10
  end
13
11
 
14
- SUPPORTED_START_STEPS.each do |step|
12
+ SUPPORTED_STEPS.each do |step|
15
13
  define_method step do |*args|
16
14
  Step.new(@pool, step, *args)
17
15
  end
@@ -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
- def initialize(type, value)
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 ||= { "@type": "g:#{@type}", "@value": @value }
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
- "<#{@type}.#{@value}>"
24
+ "<#{type}.#{value}>"
17
25
  end
18
26
  alias to_s inspect
19
27
  alias to_readable_bytecode inspect
@@ -13,6 +13,7 @@ module Grumlin
13
13
  "g:Int32" => ->(value) { cast_int(value) },
14
14
  "g:Double" => ->(value) { cast_double(value) },
15
15
  "g:Traverser" => ->(value) { cast(value[:value]) }, # TODO: wtf is bulk?
16
+ "g:Direction" => ->(value) { value },
16
17
  "g:T" => ->(value) { value.to_sym }
17
18
  }.freeze
18
19
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Grumlin
4
- VERSION = "0.10.1"
4
+ VERSION = "0.12.2"
5
5
  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.10.1
4
+ version: 0.12.2
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-13 00:00:00.000000000 Z
11
+ date: 2021-10-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async-pool
@@ -66,7 +66,10 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '2.4'
69
- description: Gremlin query language DSL for Ruby.
69
+ description: 'Gremlin graph traversal language DSL and client for Ruby. Suitable and
70
+ tested with gremlin-server and AWS Neptune.
71
+
72
+ '
70
73
  email:
71
74
  - zhulik.gleb@gmail.com
72
75
  executables: []
@@ -85,6 +88,7 @@ files:
85
88
  - Gemfile.lock
86
89
  - LICENSE.txt
87
90
  - README.md
91
+ - Rakefile
88
92
  - bin/console
89
93
  - bin/setup
90
94
  - docker-compose.yml
@@ -97,22 +101,25 @@ files:
97
101
  - lib/grumlin/bytecode.rb
98
102
  - lib/grumlin/client.rb
99
103
  - lib/grumlin/edge.rb
100
- - lib/grumlin/order.rb
101
- - lib/grumlin/p.rb
102
104
  - lib/grumlin/path.rb
103
- - lib/grumlin/pop.rb
104
105
  - lib/grumlin/request_dispatcher.rb
105
106
  - lib/grumlin/step.rb
106
107
  - lib/grumlin/sugar.rb
107
- - lib/grumlin/t.rb
108
108
  - lib/grumlin/test/rspec.rb
109
109
  - lib/grumlin/test/rspec/db_cleaner_context.rb
110
110
  - lib/grumlin/test/rspec/gremlin_context.rb
111
+ - lib/grumlin/tools/order.rb
112
+ - lib/grumlin/tools/p.rb
113
+ - lib/grumlin/tools/pop.rb
114
+ - lib/grumlin/tools/scope.rb
115
+ - lib/grumlin/tools/t.rb
116
+ - lib/grumlin/tools/tool.rb
117
+ - lib/grumlin/tools/u.rb
118
+ - lib/grumlin/tools/with_options.rb
111
119
  - lib/grumlin/transport.rb
112
120
  - lib/grumlin/traversal.rb
113
121
  - lib/grumlin/typed_value.rb
114
122
  - lib/grumlin/typing.rb
115
- - lib/grumlin/u.rb
116
123
  - lib/grumlin/version.rb
117
124
  - lib/grumlin/vertex.rb
118
125
  homepage: https://github.com/zhulik/grumlin
@@ -140,5 +147,5 @@ requirements: []
140
147
  rubygems_version: 3.2.22
141
148
  signing_key:
142
149
  specification_version: 4
143
- summary: Gremlin query language DSL for Ruby.
150
+ summary: Gremlin graph traversal language DSL and client for Ruby.
144
151
  test_files: []
data/lib/grumlin/order.rb DELETED
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Grumlin
4
- module Order
5
- # TODO: share the code?
6
- class << self
7
- %i[asc desc].each do |step|
8
- define_method step do
9
- name = "@#{step}"
10
- return instance_variable_get(name) if instance_variable_defined?(name)
11
-
12
- instance_variable_set(name, TypedValue.new("Order", step))
13
- end
14
- end
15
- end
16
- end
17
- end
data/lib/grumlin/p.rb DELETED
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Grumlin
4
- module P
5
- module P
6
- %w[within].each do |step|
7
- define_method step do |*args|
8
- { # TODO: replace with a TypedValue?
9
- "@type": "g:P",
10
- "@value": { predicate: "within", value: { "@type": "g:List", "@value": args } }
11
- }
12
- end
13
- end
14
- end
15
-
16
- extend P
17
- end
18
- end
data/lib/grumlin/pop.rb DELETED
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Grumlin
4
- module Pop
5
- # TODO: share the code?
6
- class << self
7
- %i[first last all mixed].each do |step|
8
- define_method step do
9
- name = "@#{step}"
10
- return instance_variable_get(name) if instance_variable_defined?(name)
11
-
12
- instance_variable_set(name, TypedValue.new("Pop", step))
13
- end
14
- end
15
- end
16
- end
17
- end
data/lib/grumlin/t.rb DELETED
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Grumlin
4
- module T
5
- # TODO: share the code?
6
- class << self
7
- %i[id label].each do |step|
8
- define_method step do
9
- name = "@#{step}"
10
- return instance_variable_get(name) if instance_variable_defined?(name)
11
-
12
- instance_variable_set(name, TypedValue.new("T", step))
13
- end
14
- end
15
- end
16
- end
17
- end
data/lib/grumlin/u.rb DELETED
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Grumlin
4
- module U
5
- # TODO: add other start steps
6
- SUPPORTED_START_STEPS = %w[V addV count fold has out repeat unfold values].freeze
7
-
8
- class << self
9
- SUPPORTED_START_STEPS.each do |step|
10
- define_method step do |*args|
11
- AnonymousStep.new(step, *args)
12
- end
13
- end
14
- end
15
- end
16
- end