neo4j_bolt 0.1.2 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +39 -16
- data/lib/neo4j_bolt/version.rb +1 -1
- data/lib/neo4j_bolt.rb +30 -16
- 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: 8ae1844c42fe992c5b95ada1c349eb6fe8b02d4d35a674d79d9bd28f88baaa3e
|
4
|
+
data.tar.gz: dafa87f4bc3aecc3e21f42371bc85a53bc6705c6c41bb9bcb83b1e53a8d96ebe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 003f8f4267f6a1a9dd2eeea2209709943aeb7a6158c2f44d4a723bb5d9bd63c2b0ae368aabdec46d5ed96f19c65ad7e739b25e698403c845db1d4bd89dd127f4
|
7
|
+
data.tar.gz: ef34750c3f5fd4c04f2a93a54aa19e9c36962039501691e620145319613ec5bf4766d481e1a6b2b14f683e09003eb61932f5676da40108b082ea2a6a07addeb1
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,16 +1,6 @@
|
|
1
1
|
# Neo4jBolt
|
2
2
|
|
3
|
-
A Neo4j/Bolt driver written in pure Ruby.
|
4
|
-
|
5
|
-
🚀 **Streaming support!** Neo4j sends responses in chunks of max. 64 kb. When running queries, specify a block to obtain rows as soon as they arrive.
|
6
|
-
|
7
|
-
## Supported and unsupported aspects
|
8
|
-
|
9
|
-
| | Supported | Unsupported |
|
10
|
-
|-|-|-
|
11
|
-
| Neo4j | 4.4 | 1.x 2.x 3.x <br /> 4.0 4.1 4.2 4.3 <br /> 5.x |
|
12
|
-
| Bolt | 4.4 | 1 2 3 4.0 4.1 4.2 4.3 |
|
13
|
-
|
3
|
+
A Neo4j/Bolt driver written in pure Ruby. Currently only supporting Neo4j 4.4.
|
14
4
|
|
15
5
|
## Installation
|
16
6
|
|
@@ -36,23 +26,56 @@ In order to use this gem, you need a running Neo4j database. You can start one u
|
|
36
26
|
docker run --rm --env NEO4J_AUTH=none --publish 7687:7687 neo4j:4.4-community
|
37
27
|
```
|
38
28
|
|
29
|
+
### Connecting to a Neo4j database
|
30
|
+
|
31
|
+
Specify your Bolt host and port (if you omit this it will be localhost:7687 by default):
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
Neo4jBolt.bolt_host = 'localhost'
|
35
|
+
Neo4jBolt.bolt_port = 7687
|
36
|
+
```
|
37
|
+
|
38
|
+
Use `cleanup_neo4j` to disconnect (this is important when running a web app – it might be a good idea to close a socket once we're done with it so we don't run out of ports).
|
39
|
+
|
40
|
+
|
39
41
|
### Running queries
|
40
42
|
|
41
43
|
Use `neo4j_query` to run a query and receive all results:
|
42
44
|
|
43
45
|
```ruby
|
44
|
-
entries = neo4j_query("MATCH (n) RETURN n")
|
46
|
+
entries = neo4j_query("MATCH (n) RETURN n;")
|
45
47
|
```
|
46
48
|
Alternatively, specify a block to make use of Neo4j's streaming capabilities and receive entries one by one:
|
47
49
|
|
48
50
|
```ruby
|
49
|
-
neo4j_query("MATCH (n) RETURN n") do |entry|
|
50
|
-
# entry
|
51
|
+
neo4j_query("MATCH (n) RETURN n;") do |entry|
|
52
|
+
# handle entry here
|
51
53
|
end
|
52
54
|
```
|
53
|
-
Using streaming avoids memory hog since it prevents having to read all entries into memory before handling them.
|
54
55
|
|
55
|
-
|
56
|
+
Using streaming avoids memory hog since it prevents having to read all entries into memory before handling them. Nodes are returned as `Neo4jBolt::Node`, relationships as `Neo4jBolt::Relationship`. Both are subclasses of `Hash`, providing access to all properties plus a few extra details:
|
57
|
+
|
58
|
+
- `Neo4jBolt::Node`: `id`, `labels`
|
59
|
+
- `Neo4jBolt::Relationship`: `id`, `start_node_id`, `end_node_id`, `type`
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
node = neo4j_query_expect_one("CREATE (n:Node {a: 1, b: 2}) RETURN n;")['n']
|
63
|
+
# All nodes returned from Neo4j are a Neo4jBolt::Node
|
64
|
+
# It's a subclass of Hash and it stores all the node's
|
65
|
+
# properties plus two attributes called id and labels:
|
66
|
+
puts node.id
|
67
|
+
puts node.labels
|
68
|
+
puts node.keys
|
69
|
+
node.each_pair { |k, v| puts "#{k}: #{v}" }
|
70
|
+
puts node.to_json
|
71
|
+
```
|
72
|
+
Use `neo4j_query_expect_one` if you want to make sure there's exactly one entry to be returned:
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
node = neo4j_query_expect_one("MATCH (n) RETURN n LIMIT 1;")['n']
|
76
|
+
```
|
77
|
+
|
78
|
+
If there's zero, two, or more results, this will raise a `ExpectedOneResultError`.
|
56
79
|
|
57
80
|
## Development
|
58
81
|
|
data/lib/neo4j_bolt/version.rb
CHANGED
data/lib/neo4j_bolt.rb
CHANGED
@@ -4,6 +4,12 @@ require 'json'
|
|
4
4
|
require 'yaml'
|
5
5
|
|
6
6
|
module Neo4jBolt
|
7
|
+
class << self
|
8
|
+
attr_accessor :bolt_host, :bolt_port
|
9
|
+
end
|
10
|
+
self.bolt_host = 'localhost'
|
11
|
+
self.bolt_port = 7687
|
12
|
+
|
7
13
|
NEO4J_DEBUG = 0
|
8
14
|
|
9
15
|
module ServerState
|
@@ -266,9 +272,7 @@ module Neo4jBolt
|
|
266
272
|
|
267
273
|
class BoltSocket
|
268
274
|
|
269
|
-
def initialize(
|
270
|
-
@host = host
|
271
|
-
@port = port
|
275
|
+
def initialize()
|
272
276
|
@socket = nil
|
273
277
|
@transaction = 0
|
274
278
|
@transaction_failed = false
|
@@ -594,8 +598,13 @@ module Neo4jBolt
|
|
594
598
|
append_uint8(0xb1)
|
595
599
|
append_token(BoltMarker::BOLT_RESET)
|
596
600
|
flush()
|
597
|
-
|
598
|
-
|
601
|
+
read_response() do |data|
|
602
|
+
if data[:marker] == BoltMarker::BOLT_SUCCESS
|
603
|
+
@state.set(ServerState::READY)
|
604
|
+
else
|
605
|
+
raise UnexpectedServerResponse.new(data[:marker])
|
606
|
+
end
|
607
|
+
end
|
599
608
|
# BoltBuffer.new(@socket).flush()
|
600
609
|
raise bolt_error(response_dict[:data]['code'], response_dict[:data]['message'])
|
601
610
|
end
|
@@ -607,7 +616,7 @@ module Neo4jBolt
|
|
607
616
|
|
608
617
|
def connect()
|
609
618
|
# STDERR.write "Connecting to Neo4j via Bolt..."
|
610
|
-
@socket = TCPSocket.new(
|
619
|
+
@socket = TCPSocket.new(Neo4jBolt.bolt_host, Neo4jBolt.bolt_port)
|
611
620
|
# @socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true)
|
612
621
|
# @socket.setsockopt(Socket::SOL_TCP, Socket::TCP_KEEPIDLE, 50)
|
613
622
|
# @socket.setsockopt(Socket::SOL_TCP, Socket::TCP_KEEPINTVL, 10)
|
@@ -628,7 +637,7 @@ module Neo4jBolt
|
|
628
637
|
data = {
|
629
638
|
:routing => nil,
|
630
639
|
:scheme => 'none',
|
631
|
-
:user_agent => '
|
640
|
+
:user_agent => 'neo4j_bolt/0.1'
|
632
641
|
}
|
633
642
|
append_uint8(0xb1)
|
634
643
|
append_token(BoltMarker::BOLT_HELLO)
|
@@ -651,7 +660,7 @@ module Neo4jBolt
|
|
651
660
|
|
652
661
|
def disconnect()
|
653
662
|
append_uint8(0xb1)
|
654
|
-
append_token(BOLT_GOODBYE)
|
663
|
+
append_token(BoltToken::BOLT_GOODBYE)
|
655
664
|
flush()
|
656
665
|
@state.set(ServerState::DEFUNCT)
|
657
666
|
end
|
@@ -673,6 +682,8 @@ module Neo4jBolt
|
|
673
682
|
@transaction_failed = false
|
674
683
|
elsif data[:marker] == BoltMarker::BOLT_FAILURE
|
675
684
|
@state.set(ServerState::FAILED)
|
685
|
+
else
|
686
|
+
raise UnexpectedServerResponse.new(data[:marker])
|
676
687
|
end
|
677
688
|
end
|
678
689
|
end
|
@@ -709,10 +720,15 @@ module Neo4jBolt
|
|
709
720
|
append_uint8(0xb1)
|
710
721
|
append_token(BoltMarker::BOLT_COMMIT)
|
711
722
|
flush()
|
712
|
-
read_response()
|
713
|
-
|
714
|
-
|
715
|
-
|
723
|
+
read_response() do |data|
|
724
|
+
if data[:marker] == BoltMarker::BOLT_SUCCESS
|
725
|
+
@transaction = 0
|
726
|
+
@transaction_failed = false
|
727
|
+
@state.set(ServerState::READY)
|
728
|
+
else
|
729
|
+
raise UnexpectedServerResponse.new(data[:marker])
|
730
|
+
end
|
731
|
+
end
|
716
732
|
end
|
717
733
|
end
|
718
734
|
|
@@ -779,6 +795,8 @@ module Neo4jBolt
|
|
779
795
|
elsif data[:marker] == BoltMarker::BOLT_SUCCESS
|
780
796
|
# STDERR.puts data.to_yaml
|
781
797
|
@state.set(ServerState::TX_READY)
|
798
|
+
else
|
799
|
+
raise UnexpectedServerResponse.new(data[:marker])
|
782
800
|
end
|
783
801
|
end
|
784
802
|
elsif data[:marker] == BoltMarker::BOLT_FAILURE
|
@@ -811,10 +829,6 @@ module Neo4jBolt
|
|
811
829
|
end
|
812
830
|
end
|
813
831
|
|
814
|
-
def connect_bolt_socket(host, port)
|
815
|
-
@bolt_socket ||= BoltSocket.new(host, port)
|
816
|
-
end
|
817
|
-
|
818
832
|
def transaction(&block)
|
819
833
|
@bolt_socket ||= BoltSocket.new()
|
820
834
|
@bolt_socket.transaction { yield }
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: neo4j_bolt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Specht
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-10-
|
11
|
+
date: 2022-10-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|