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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 57cb820dc2f181457f76fa50f72a00d0712ba568aab86af0c156ed072ec05966
4
- data.tar.gz: 7a1fde38c4c94a666226ec5a7136eae9187b592428345ae9178e69aff3b82231
3
+ metadata.gz: 8ae1844c42fe992c5b95ada1c349eb6fe8b02d4d35a674d79d9bd28f88baaa3e
4
+ data.tar.gz: dafa87f4bc3aecc3e21f42371bc85a53bc6705c6c41bb9bcb83b1e53a8d96ebe
5
5
  SHA512:
6
- metadata.gz: 9bba294fea8355bb36e4f73cd9f0abfaeb44289dea42104c477350a7bdd6777987335181fa8cd6732dc388518a058abf57503bbcf2ec1fe8ffc9e0dcd7904f7c
7
- data.tar.gz: a3a3584d8e1edcb24472b7811dd603e416ff45ed09f49f65bbfbd10154b12b197cdbf1752dbfc89a28f81f016cc99746c18836fbd187437889f51b21c4592471
6
+ metadata.gz: 003f8f4267f6a1a9dd2eeea2209709943aeb7a6158c2f44d4a723bb5d9bd63c2b0ae368aabdec46d5ed96f19c65ad7e739b25e698403c845db1d4bd89dd127f4
7
+ data.tar.gz: ef34750c3f5fd4c04f2a93a54aa19e9c36962039501691e620145319613ec5bf4766d481e1a6b2b14f683e09003eb61932f5676da40108b082ea2a6a07addeb1
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- neo4j_bolt (0.1.0)
4
+ neo4j_bolt (0.1.3)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
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['n'] is your node
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
- Use `neo4j_query_expect_one` if you want to make sure there's exactly one entry to be returned. If there's zero, two, or more results, this will raise a `ExpectedOneResultError`.
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
 
@@ -1,3 +1,3 @@
1
1
  module Neo4jBolt
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.4"
3
3
  end
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(host = 'localhost', port = 7687)
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
- @state.set(ServerState::READY)
598
- read_response()
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(@host, @port)
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 => 'qts/0.1'
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
- @transaction = 0
714
- @transaction_failed = false
715
- @state.set(ServerState::READY)
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.2
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-27 00:00:00.000000000 Z
11
+ date: 2022-10-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec