From 2c17e5d0e5a3767071d10c588ddb0469a4531e0a Mon Sep 17 00:00:00 2001 From: Chris Grigg Date: Fri, 29 Jan 2016 12:37:04 -0500 Subject: [PATCH] simplifies transaction response parse, fixes path/nodes bug --- CHANGELOG.md | 6 +++ lib/neo4j-server/cypher_response.rb | 63 ++++++++-------------------- spec/shared_examples/node_with_tx.rb | 17 ++++++++ 3 files changed, 40 insertions(+), 46 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2168cb9f..1990f604 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file. This file should follow the standards specified on [http://keepachangelog.com/] This project adheres to [Semantic Versioning](http://semver.org/). +## Unreleased + +### Fixed + +- Returning paths within transactions in Server mode could result in incorrectly wrapped nodes. + ## [6.1.0] - 2016-01-01 ### Fixed diff --git a/lib/neo4j-server/cypher_response.rb b/lib/neo4j-server/cypher_response.rb index 6d77850a..03a28865 100644 --- a/lib/neo4j-server/cypher_response.rb +++ b/lib/neo4j-server/cypher_response.rb @@ -55,11 +55,8 @@ def to_struct_enumeration(cypher = EMPTY_STRING) def to_node_enumeration(cypher = EMPTY_STRING, session = Neo4j::Session.current) Enumerator.new do |yielder| - @result_index = 0 to_struct_enumeration(cypher).each do |row| - @row_index = 0 yielder << row_pair_in_struct(row, session) - @result_index += 1 end end end @@ -68,7 +65,6 @@ def row_pair_in_struct(row, session) @struct.new.tap do |result| row.each_pair do |column, value| result[column] = map_row_value(value, session) - @row_index += 1 end end end @@ -84,17 +80,10 @@ def map_row_value(value, session) end def hash_value_as_object(value, session) - if transaction_response? - add_transaction_entity_id - data = mapped_rest_data - elsif [:node, :relationship].include?(identify_entity(value)) - add_entity_id(value) - data = value - else - return value - end + return value unless [:node, :relationship].include?(identify_entity(value)) + add_entity_id(value) - basic_obj = (node?(value) ? CypherNode : CypherRelationship).new(session, data) + basic_obj = (node?(value) ? CypherNode : CypherRelationship).new(session, value) unwrapped? ? basic_obj : basic_obj.wrapper end @@ -112,11 +101,7 @@ def identify_entity(data) end def looks_like_an_object?(value) - if transaction_response? - mapped_rest_data[:outgoing_relationships] || (mapped_rest_data[:start] && mapped_rest_data[:properties]) - else - value[:labels] || value[:type] - end + value[:labels] || value[:type] end def unwrapped! @@ -128,7 +113,7 @@ def unwrapped? end def node?(value) - transaction_response? ? !mapped_rest_data[:start] : value[:labels] + value[:labels] end attr_reader :struct @@ -151,7 +136,6 @@ def entity_data(id = nil) def first_data if @uncommited @data.first[:row].first - # data.is_a?(Hash) ? {'data' => data, 'id' => id} : data else data = @data[0][0] data.is_a?(Hash) ? add_entity_id(data) : data @@ -167,11 +151,6 @@ def add_entity_id(data) data end - def add_transaction_entity_id - mapped_rest_data[:id] = mapped_rest_data[:self].split('/').last.to_i - mapped_rest_data - end - def error? !!@error end @@ -191,9 +170,18 @@ def raise_unless_response_code(code) end def each_data_row - data.each { |r| yield (@uncommited ? r[:row] : r) } + data.each do |r| + yieldable = if @uncommitted + r[:row] + else + transaction_row?(r) ? r[:rest] : r + end + yield yieldable + end end + + def set_data(response) @data = response[:data] @columns = response[:columns] @@ -244,27 +232,10 @@ def self.create_with_tx(response) end end - def transaction_response? - response.respond_to?(:body) && !response.body[:commit].nil? - end - - def rest_data - @result_index = @row_index = 0 - mapped_rest_data - end - - def rest_data_with_id - rest_data[:id] = mapped_rest_data[:self].split('/').last.to_i - rest_data - end - private - attr_reader :row_index, :result_index - - def mapped_rest_data - data = response.body[:results][0][:data][result_index][:rest][row_index] - data.is_a?(Array) ? data.first : data + def transaction_row?(row) + row.is_a?(Hash) && row[:rest] && row[:row] end end end diff --git a/spec/shared_examples/node_with_tx.rb b/spec/shared_examples/node_with_tx.rb index 6c6529d7..766e4b84 100644 --- a/spec/shared_examples/node_with_tx.rb +++ b/spec/shared_examples/node_with_tx.rb @@ -118,6 +118,23 @@ end end end + + describe 'returning a path from cypher' do + before do + Neo4j::Session.current + .query("CREATE (:Person {name: 'son'})<-[:PARENT_OF]-(:Person {name: 'father'})<-[:PARENT_OF]-(:Person {name: 'grandfather'})") + end + let(:names) do + Neo4j::Session.current + .query + .match("p=(:Person {name: 'son'})<-[PARENT_OF*]-(:Person {name: 'grandfather'})") + .pluck('nodes(p)')[0].map { |n| n.props[:name] } + end + + it 'correctly wraps nodes' do + expect(Neo4j::Transaction.run { names }).to eq %w(son father grandfather) + end + end end end