rom-neo4j 0.0.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 +7 -0
- data/.gitignore +2 -0
- data/Gemfile +3 -0
- data/README.md +68 -0
- data/lib/rom-neo4j.rb +1 -0
- data/lib/rom/neo4j.rb +10 -0
- data/lib/rom/neo4j/dataset.rb +62 -0
- data/lib/rom/neo4j/relation.rb +99 -0
- data/lib/rom/neo4j/repository.rb +20 -0
- data/lib/rom/neo4j/support/core_ext.rb +46 -0
- data/lib/rom/neo4j/version.rb +5 -0
- data/rom-neo4j.gemspec +27 -0
- data/spec/integration/adapter_spec.rb +83 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/unit/query_spec.rb +36 -0
- data/spec/unit/relation_spec.rb +34 -0
- metadata +134 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 434f1e9e4586f8d8a826631dc3df4acb084fd636
|
4
|
+
data.tar.gz: f8856d06f8ca5f12b65f21b793bc91e9ca88d1a0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8d1aea0e308f15dd1e66e98cdff967bab262bb6b0f840c8166610a156d84a134dc5ce3d4b29e6dd0c103e42ca79303c74923dd24413918f7082979066f1c86ca
|
7
|
+
data.tar.gz: 506f5147ffd33784f81a10e700238f79e484c53cbcd699fbc1996af979a1067ab2e936303a91eef05852c2a19344845886dabb3852825cc1548b54bdc7fca2d4
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
# ROM::Neo4j
|
2
|
+
|
3
|
+
Map objects returned from Neo4j graph traversals using the [Ruby Object Mapper](https://github.com/rom-rb/rom) toolkit.
|
4
|
+
|
5
|
+
## Status
|
6
|
+
|
7
|
+
Incomplete experimental sketch.
|
8
|
+
|
9
|
+
The adapter spec passes with the generic movies dataset distributed with Neo4j, but that's about all at this point.
|
10
|
+
|
11
|
+
## Install
|
12
|
+
|
13
|
+
Right now, the fastest way to get started is to run the tests.
|
14
|
+
|
15
|
+
You’ll need to have Neo4j installed on your system. If it’s not already running, start the database server with:
|
16
|
+
|
17
|
+
```
|
18
|
+
neo4j start
|
19
|
+
```
|
20
|
+
|
21
|
+
To load the sample movies graph, go to `http://localhost:7474/browser/` and click through the instructions or type `:play movie graph` in the console to start.
|
22
|
+
|
23
|
+
Once the movies graph is loaded, the integration specs should run:
|
24
|
+
|
25
|
+
```
|
26
|
+
rspec specs/integration
|
27
|
+
```
|
28
|
+
|
29
|
+
## Examples
|
30
|
+
|
31
|
+
### Cypher DSL
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
setup.relation(:movies) do
|
35
|
+
matches m: :Movie
|
36
|
+
returns m: [:title, :released, :tagline]
|
37
|
+
|
38
|
+
def titled(title)
|
39
|
+
where('m.title' => title)
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
movie = rom.read(:movies).titled('The Matrix').first
|
45
|
+
movie.title # => "The Matrix"
|
46
|
+
movie.updated # => 1999
|
47
|
+
```
|
48
|
+
|
49
|
+
### Raw Cypher Queries
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
setup.relation(:directors) do
|
53
|
+
matches '(director:Person)-[:DIRECTED]->(movie:Movie)'
|
54
|
+
returns 'DISTINCT director.name as name'
|
55
|
+
|
56
|
+
def by_movie(title)
|
57
|
+
where('movie.title' => title)
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
director = rom.read(:directors).by_movie('RescueDawn').first
|
63
|
+
director.name # => "Werner Herzog"
|
64
|
+
```
|
65
|
+
|
66
|
+
## Roadmap
|
67
|
+
|
68
|
+
A work in progress.
|
data/lib/rom-neo4j.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'rom/neo4j'
|
data/lib/rom/neo4j.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
module ROM
|
2
|
+
module Neo4j
|
3
|
+
# A dataset represents a collection returned from a query traversal over a
|
4
|
+
# sub-graph.
|
5
|
+
#
|
6
|
+
# Datasets are Enumerable objects and can be manipulated using the standard
|
7
|
+
# methods, `each`, `map`, `inject`, and so forth.
|
8
|
+
class Dataset
|
9
|
+
include Enumerable
|
10
|
+
|
11
|
+
# @see http://www.rubydoc.info/gems/neo4j-core/Neo4j/Core/Query
|
12
|
+
# @param query [Neo4j::Core::Query] Query object returned from a Neo4j connection
|
13
|
+
def initialize(query)
|
14
|
+
@query = query
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_cypher
|
18
|
+
@query.to_cypher
|
19
|
+
end
|
20
|
+
|
21
|
+
def each(&iter)
|
22
|
+
@query.each(&iter)
|
23
|
+
end
|
24
|
+
|
25
|
+
def where(*conditions)
|
26
|
+
self.class.new(@query.where(*conditions))
|
27
|
+
end
|
28
|
+
|
29
|
+
def start(*conditions)
|
30
|
+
self.class.new(@query.start(*conditions))
|
31
|
+
end
|
32
|
+
|
33
|
+
def match(*conditions)
|
34
|
+
self.class.new(@query.match(*conditions))
|
35
|
+
end
|
36
|
+
|
37
|
+
def return(*conditions)
|
38
|
+
self.class.new(@query.return(*conditions))
|
39
|
+
end
|
40
|
+
|
41
|
+
def limit(*conditions)
|
42
|
+
self.class.new(@query.limit(*conditions))
|
43
|
+
end
|
44
|
+
|
45
|
+
def merge(*conditions)
|
46
|
+
self.class.new(@query.merge(*conditions))
|
47
|
+
end
|
48
|
+
|
49
|
+
def order(*conditions)
|
50
|
+
self.class.new(@query.order(*conditions))
|
51
|
+
end
|
52
|
+
|
53
|
+
def optional_match(*conditions)
|
54
|
+
self.class.new(@query.optional_match(*conditions))
|
55
|
+
end
|
56
|
+
|
57
|
+
def params(*conditions)
|
58
|
+
self.class.new(@query.params(*conditions))
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module ROM
|
2
|
+
module Neo4j
|
3
|
+
# Relation supporting Cypher graph traversals. Configure the sub-graph
|
4
|
+
# for the relation by specifying a `match` pattern, and collect a dataset
|
5
|
+
# for mapping by specifying nodes, edges and properties in the `returns`.
|
6
|
+
class Relation < ROM::Relation
|
7
|
+
|
8
|
+
# TODO: document these methods
|
9
|
+
forward(
|
10
|
+
:start, :match, :where, :return, :limit, :merge, :order,
|
11
|
+
:optional_match, :params
|
12
|
+
)
|
13
|
+
|
14
|
+
# The row iterator. Calling this kicks off the actual query to the
|
15
|
+
# database server.
|
16
|
+
#
|
17
|
+
# Before triggering the enumerator, it rebuilds the dataset with the
|
18
|
+
# default traversal configured by the relation DSL.
|
19
|
+
#
|
20
|
+
def each(&iter)
|
21
|
+
# Configure the default traversal
|
22
|
+
unless @configured
|
23
|
+
@configured = true
|
24
|
+
self.class.traversal.each do |query_method, conditions|
|
25
|
+
@dataset = @dataset.send(query_method.to_sym, *conditions) if conditions
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
@dataset.each(&iter)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Builds data structures to configure the relation DSL.
|
33
|
+
# @api private
|
34
|
+
def self.inherited(klass)
|
35
|
+
klass.class_eval do
|
36
|
+
class << self
|
37
|
+
attr_reader :traversal
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
klass.instance_variable_set('@traversal', {
|
42
|
+
start: false,
|
43
|
+
match: false,
|
44
|
+
return: false
|
45
|
+
})
|
46
|
+
|
47
|
+
super
|
48
|
+
end
|
49
|
+
|
50
|
+
# Specify a `START` node for the for the relation's graph traversal. This
|
51
|
+
# is only required for legacy indexes. In most cases Cypher can infer the
|
52
|
+
# starting points to anchor a graph traversal from the pattern specified
|
53
|
+
# in a `MATCH` clause.
|
54
|
+
#
|
55
|
+
# @see http://neo4j.com/docs/stable/query-start.html
|
56
|
+
#
|
57
|
+
def self.start(*conditions)
|
58
|
+
@traversal[:start] = conditions
|
59
|
+
end
|
60
|
+
|
61
|
+
# Specify a `MATCH` clause for the relation's graph traversal. If you’re
|
62
|
+
# coming from the SQL world, you can think of this as similar to a
|
63
|
+
# `SELECT FROM`, except that it matches on a topological structure rather
|
64
|
+
# than a schema.
|
65
|
+
#
|
66
|
+
# @example Reproduce SQL style projections by passing node labels directly.
|
67
|
+
#
|
68
|
+
# class Movies < ROM::Relation[:neo4j]
|
69
|
+
# matches m: :movie
|
70
|
+
# end
|
71
|
+
#
|
72
|
+
# @example Specify topological matches using Cypher's ASCII-art syntax.
|
73
|
+
#
|
74
|
+
# class Actors < ROM::Relation[:neo4j]
|
75
|
+
# matches '(actor:Person)-[:ACTED_IN]->(movie)'
|
76
|
+
# end
|
77
|
+
#
|
78
|
+
# @see http://neo4j.com/docs/stable/query-match.html
|
79
|
+
#
|
80
|
+
def self.matches(*conditions)
|
81
|
+
@traversal[:match] = conditions
|
82
|
+
end
|
83
|
+
|
84
|
+
# Specify a `RETURN` clause for the relation. This will define the
|
85
|
+
# structure of objects in the returned dataset.
|
86
|
+
#
|
87
|
+
# Any combination of nodes, edges and properties can be selected, as well
|
88
|
+
# as custom aliases and distinct objects.
|
89
|
+
#
|
90
|
+
# @see http://neo4j.com/docs/stable/query-return.html
|
91
|
+
#
|
92
|
+
def self.returns(*conditions)
|
93
|
+
@traversal[:return] = conditions
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module ROM
|
2
|
+
module Neo4j
|
3
|
+
class Repository < ROM::Repository
|
4
|
+
attr_reader :sets
|
5
|
+
|
6
|
+
def initialize(uri, options={})
|
7
|
+
@connection = ::Neo4j::Session.open(:server_db, uri, options)
|
8
|
+
@sets = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def dataset(name)
|
12
|
+
sets[name] = Dataset.new(@connection.query)
|
13
|
+
end
|
14
|
+
|
15
|
+
def dataset?(name)
|
16
|
+
sets.key?(name)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# Extensions to the Neo4j::Core library making it easier to integrate with ROM.
|
2
|
+
module Neo4j
|
3
|
+
module Core
|
4
|
+
# DSL for generating Cypher queries and enumerating their results
|
5
|
+
#
|
6
|
+
# @see http://www.rubydoc.info/gems/neo4j-core/Neo4j/Core/Query
|
7
|
+
class Query
|
8
|
+
# def each
|
9
|
+
# response = self.response
|
10
|
+
# if response.is_a?(Neo4j::Server::CypherResponse)
|
11
|
+
# response.to_node_enumeration
|
12
|
+
# else
|
13
|
+
# Neo4j::Embedded::ResultWrapper.new(response, to_cypher)
|
14
|
+
# end.each { |object| yield object }
|
15
|
+
# end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
module Server
|
19
|
+
class CypherResponse
|
20
|
+
# Coerces result objects from structs to hashes in results.
|
21
|
+
class HashEnumeration
|
22
|
+
def each(&block)
|
23
|
+
@response.each_data_row do |row|
|
24
|
+
yield(row.each_with_index.each_with_object(struct.new) do |(value, i), result|
|
25
|
+
result[columns[i].to_sym] = value
|
26
|
+
end.to_h)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
# Coerces result objects from structs to hashes in results.
|
31
|
+
def to_node_enumeration(cypher = '', session = Neo4j::Session.current)
|
32
|
+
Enumerator.new do |yielder|
|
33
|
+
@result_index = 0
|
34
|
+
to_struct_enumeration(cypher).each do |row|
|
35
|
+
@row_index = 0
|
36
|
+
yielder << row.each_pair.each_with_object(@struct.new) do |(column, value), result|
|
37
|
+
result[column] = map_row_value(value, session)
|
38
|
+
@row_index += 1
|
39
|
+
end.to_h
|
40
|
+
@result_index += 1
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/rom-neo4j.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'rom/neo4j/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'rom-neo4j'
|
8
|
+
spec.version = ROM::Neo4j::VERSION.dup
|
9
|
+
spec.authors = ['Mark Rickerby']
|
10
|
+
spec.email = ['me@maetl.net']
|
11
|
+
spec.summary = 'Neo4j graph relations for Ruby Object Mapper'
|
12
|
+
spec.description = spec.summary
|
13
|
+
spec.homepage = 'https://rom-rb.org/'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_runtime_dependency 'rom', '~> 0.6'
|
22
|
+
spec.add_runtime_dependency 'neo4j-core', '~> 4.0'
|
23
|
+
|
24
|
+
spec.add_development_dependency 'bundler'
|
25
|
+
spec.add_development_dependency 'rake'
|
26
|
+
spec.add_development_dependency 'rubocop', '~> 0.28.0'
|
27
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rom/lint/spec'
|
3
|
+
|
4
|
+
describe 'Neo4j adapter' do
|
5
|
+
let(:dsn) { 'http://localhost:7474' }
|
6
|
+
let(:setup) { ROM.setup(:neo4j, dsn) }
|
7
|
+
|
8
|
+
context 'with movies relation and mapper' do
|
9
|
+
let(:rom) do
|
10
|
+
setup.relation(:movies) do
|
11
|
+
matches m: :Movie
|
12
|
+
#returns m: [:title, :released, :tagline]
|
13
|
+
returns ['m.title AS title', 'm.released AS released', 'm.tagline as tagline']
|
14
|
+
|
15
|
+
def by_title(title)
|
16
|
+
where('m.title' => title)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
setup.mappers do
|
21
|
+
define(:movies) do
|
22
|
+
relation :movies
|
23
|
+
model name: 'Movie'
|
24
|
+
#prefix :m
|
25
|
+
#prefix_separator '.'
|
26
|
+
attribute :title
|
27
|
+
attribute :released
|
28
|
+
attribute :tagline
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
setup.finalize
|
33
|
+
end
|
34
|
+
|
35
|
+
let(:movies) do
|
36
|
+
rom.relation(:movies)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'maps movies #by_title' do
|
40
|
+
movies.by_title('The Matrix').as(:movies).first.tap do |movie|
|
41
|
+
expect(movie).to be_a(Movie)
|
42
|
+
expect(movie.title).to eql('The Matrix')
|
43
|
+
expect(movie.released).to eql(1999)
|
44
|
+
expect(movie.tagline).to eql('Welcome to the Real World')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'with directors relation and mapper' do
|
51
|
+
let(:rom) do
|
52
|
+
setup.relation(:directors) do
|
53
|
+
matches '(director:Person)-[:DIRECTED]->(movie:Movie)'
|
54
|
+
returns 'DISTINCT director.name AS name'
|
55
|
+
|
56
|
+
def by_movie(title)
|
57
|
+
where('movie.title' => title)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
setup.mappers do
|
62
|
+
define(:directors) do
|
63
|
+
relation :directors
|
64
|
+
model name: 'Director'
|
65
|
+
attribute :name
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
setup.finalize
|
70
|
+
end
|
71
|
+
|
72
|
+
let(:directors) do
|
73
|
+
rom.relation(:directors)
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'maps directors #by_movie_title' do
|
77
|
+
directors.by_movie('RescueDawn').as(:directors).first.tap do |director|
|
78
|
+
expect(director).to be_a(Director)
|
79
|
+
expect(director.name).to eql('Werner Herzog')
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'rom-neo4j'
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rom/memory/dataset'
|
3
|
+
|
4
|
+
describe ROM::Neo4j::Relation do
|
5
|
+
|
6
|
+
describe '#where' do
|
7
|
+
xit 'where equals' do
|
8
|
+
expect(relation.to_a).to eql([matrix, reloaded])
|
9
|
+
end
|
10
|
+
|
11
|
+
xit 'where not equals' do
|
12
|
+
expect(relation.to_a).to eql([matrix, reloaded])
|
13
|
+
end
|
14
|
+
|
15
|
+
xit 'where gte' do
|
16
|
+
expect(relation.to_a).to eql([matrix, reloaded])
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#limit' do
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#merge' do
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#order' do
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#order' do
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rom/memory/dataset'
|
3
|
+
|
4
|
+
describe ROM::Neo4j::Relation do
|
5
|
+
subject(:relation) { Class.new(ROM::Neo4j::Relation).new(dataset) }
|
6
|
+
|
7
|
+
let(:dataset) { ROM::Memory::Dataset.new([matrix, reloaded]) }
|
8
|
+
|
9
|
+
let(:matrix) { { title: 'The Matrix', released: 1999 } }
|
10
|
+
let(:reloaded) { { title: 'The Matrix Reloaded', released: 2003 } }
|
11
|
+
|
12
|
+
describe '#each' do
|
13
|
+
it 'yields all objects' do
|
14
|
+
result = []
|
15
|
+
|
16
|
+
relation.each do |user|
|
17
|
+
result << user
|
18
|
+
end
|
19
|
+
|
20
|
+
expect(result).to eql([matrix, reloaded])
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'returns an enumerator if block is not provided' do
|
24
|
+
expect(relation.each).to be_instance_of(Enumerator)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#to_a' do
|
29
|
+
it 'materializes relation to an array' do
|
30
|
+
expect(relation.to_a).to eql([matrix, reloaded])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
metadata
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rom-neo4j
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mark Rickerby
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-04-01 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rom
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.6'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: neo4j-core
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '4.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '4.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.28.0
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.28.0
|
83
|
+
description: Neo4j graph relations for Ruby Object Mapper
|
84
|
+
email:
|
85
|
+
- me@maetl.net
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- ".gitignore"
|
91
|
+
- Gemfile
|
92
|
+
- README.md
|
93
|
+
- lib/rom-neo4j.rb
|
94
|
+
- lib/rom/neo4j.rb
|
95
|
+
- lib/rom/neo4j/dataset.rb
|
96
|
+
- lib/rom/neo4j/relation.rb
|
97
|
+
- lib/rom/neo4j/repository.rb
|
98
|
+
- lib/rom/neo4j/support/core_ext.rb
|
99
|
+
- lib/rom/neo4j/version.rb
|
100
|
+
- rom-neo4j.gemspec
|
101
|
+
- spec/integration/adapter_spec.rb
|
102
|
+
- spec/spec_helper.rb
|
103
|
+
- spec/unit/query_spec.rb
|
104
|
+
- spec/unit/relation_spec.rb
|
105
|
+
homepage: https://rom-rb.org/
|
106
|
+
licenses:
|
107
|
+
- MIT
|
108
|
+
metadata: {}
|
109
|
+
post_install_message:
|
110
|
+
rdoc_options: []
|
111
|
+
require_paths:
|
112
|
+
- lib
|
113
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
123
|
+
requirements: []
|
124
|
+
rubyforge_project:
|
125
|
+
rubygems_version: 2.4.2
|
126
|
+
signing_key:
|
127
|
+
specification_version: 4
|
128
|
+
summary: Neo4j graph relations for Ruby Object Mapper
|
129
|
+
test_files:
|
130
|
+
- spec/integration/adapter_spec.rb
|
131
|
+
- spec/spec_helper.rb
|
132
|
+
- spec/unit/query_spec.rb
|
133
|
+
- spec/unit/relation_spec.rb
|
134
|
+
has_rdoc:
|