Class: Neo4j::Server::CypherResponse

Inherits:
Object
  • Object
show all
Defined in:
lib/neo4j-server/cypher_response.rb

Defined Under Namespace

Classes: ConstraintViolationError, HashEnumeration, ResponseError

Constant Summary collapse

EMPTY_STRING =
''
RETRYABLE_ERROR_STATUSES =
%w(DeadlockDetectedException AcquireLockTimeoutException ExternalResourceFailureException UnknownFailureException)
CONSTRAINT_ERROR =
'Neo.ClientError.Schema.ConstraintViolation'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(response, uncommited = false) ⇒ CypherResponse

Returns a new instance of CypherResponse.



139
140
141
142
# File 'lib/neo4j-server/cypher_response.rb', line 139

def initialize(response, uncommited = false)
  @response = response
  @uncommited = uncommited
end

Instance Attribute Details

#columnsObject (readonly)

Returns the value of attribute columns.



4
5
6
# File 'lib/neo4j-server/cypher_response.rb', line 4

def columns
  @columns
end

#dataObject (readonly)

Returns the value of attribute data.



4
5
6
# File 'lib/neo4j-server/cypher_response.rb', line 4

def data
  @data
end

#error_codeObject (readonly)

Returns the value of attribute error_code.



4
5
6
# File 'lib/neo4j-server/cypher_response.rb', line 4

def error_code
  @error_code
end

#error_msgObject (readonly)

Returns the value of attribute error_msg.



4
5
6
# File 'lib/neo4j-server/cypher_response.rb', line 4

def error_msg
  @error_msg
end

#error_statusObject (readonly)

Returns the value of attribute error_status.



4
5
6
# File 'lib/neo4j-server/cypher_response.rb', line 4

def error_status
  @error_status
end

#responseObject (readonly)

Returns the value of attribute response.



4
5
6
# File 'lib/neo4j-server/cypher_response.rb', line 4

def response
  @response
end

#structObject (readonly)

Returns the value of attribute struct.



137
138
139
# File 'lib/neo4j-server/cypher_response.rb', line 137

def struct
  @struct
end

Class Method Details

.create_with_no_tx(response) ⇒ Object



236
237
238
239
240
241
242
243
244
245
# File 'lib/neo4j-server/cypher_response.rb', line 236

def self.create_with_no_tx(response)
  case response.status
  when 200
    new(response).set_data(response.body)
  when 400
    new(response).set_error(response.body)
  else
    fail "Unknown response code #{response.status} for #{response.env[:url]}"
  end
end

.create_with_tx(response) ⇒ Object



247
248
249
250
251
252
253
254
# File 'lib/neo4j-server/cypher_response.rb', line 247

def self.create_with_tx(response)
  fail "Unknown response code #{response.status} for #{response.request_uri}" unless response.status == 200

  new(response, true).tap do |cr|
    body = response.body
    body[:errors].empty? ? cr.set_data(body[:results].first) : cr.set_error(body[:errors].first)
  end
end

.id_from_url(url) ⇒ Object



271
272
273
# File 'lib/neo4j-server/cypher_response.rb', line 271

def id_from_url(url)
  url.split('/')[-1].to_i
end

Instance Method Details

#add_entity_id(data) ⇒ Object



164
165
166
167
168
169
170
171
# File 'lib/neo4j-server/cypher_response.rb', line 164

def add_entity_id(data)
  data[:id] = if data[:metadata] && data[:metadata][:id]
                data[:metadata][:id]
              else
                self.class.id_from_url(data[:self])
              end
  data
end

#add_transaction_entity_idObject



173
174
175
176
# File 'lib/neo4j-server/cypher_response.rb', line 173

def add_transaction_entity_id
  mapped_rest_data[:id] = mapped_rest_data[:self].split('/').last.to_i
  mapped_rest_data
end

#constraint_error?Boolean

Returns:

  • (Boolean)


226
227
228
# File 'lib/neo4j-server/cypher_response.rb', line 226

def constraint_error?
  @error_code == CONSTRAINT_ERROR || @error_msg.include?('already exists with')
end

#data?Boolean

Returns:

  • (Boolean)


188
189
190
# File 'lib/neo4j-server/cypher_response.rb', line 188

def data?
  !response.body[:data].nil?
end

#each_data_rowObject



196
197
198
199
200
201
202
# File 'lib/neo4j-server/cypher_response.rb', line 196

def each_data_row
  if @uncommited
    data.each { |r| yield r[:row] }
  else
    data.each { |r| yield r }
  end
end

#entity_data(id = nil) ⇒ Object



144
145
146
147
148
149
150
151
152
# File 'lib/neo4j-server/cypher_response.rb', line 144

def entity_data(id = nil)
  if @uncommited
    data = @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
  end
end

#error?Boolean

Returns:

  • (Boolean)


178
179
180
# File 'lib/neo4j-server/cypher_response.rb', line 178

def error?
  !!@error
end

#first_dataObject



154
155
156
157
158
159
160
161
162
# File 'lib/neo4j-server/cypher_response.rb', line 154

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
  end
end

#hash_value_as_object(value, session) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/neo4j-server/cypher_response.rb', line 88

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

  basic_obj = (node?(value) ? CypherNode : CypherRelationship).new(session, data)
  unwrapped? ? basic_obj : basic_obj.wrapper
end

#identify_entity(data) ⇒ Object



103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/neo4j-server/cypher_response.rb', line 103

def identify_entity(data)
  self_string = data[:self]
  if self_string
    type = self_string.split('/')[-2]
    if type == 'node'
      :node
    elsif type == 'relationship'
      :relationship
    end
  elsif [:nodes, :relationships, :start, :end, :length].all? { |k| data.key?(k) }
    :path
  end
end

#looks_like_an_object?(value) ⇒ Boolean

Returns:

  • (Boolean)


117
118
119
120
121
122
123
# File 'lib/neo4j-server/cypher_response.rb', line 117

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
end

#map_row_value(value, session) ⇒ Object



78
79
80
81
82
83
84
85
86
# File 'lib/neo4j-server/cypher_response.rb', line 78

def map_row_value(value, session)
  if value.is_a?(Hash) && looks_like_an_object?(value)
    hash_value_as_object(value, session)
  elsif value.is_a?(Array)
    value.map! { |v| map_row_value(v, session) }
  else
    value
  end
end

#node?(value) ⇒ Boolean

Returns:

  • (Boolean)


133
134
135
# File 'lib/neo4j-server/cypher_response.rb', line 133

def node?(value)
  transaction_response? ? !mapped_rest_data[:start] : value[:labels]
end

#raise_cypher_errorObject



230
231
232
233
# File 'lib/neo4j-server/cypher_response.rb', line 230

def raise_cypher_error
  fail 'Tried to raise error without an error' unless @error
  fail Neo4j::Session::CypherError.new(@error_msg, @error_code, @error_status)
end

#raise_errorObject



220
221
222
223
224
# File 'lib/neo4j-server/cypher_response.rb', line 220

def raise_error
  fail 'Tried to raise error without an error' unless @error
  error_class = constraint_error? ? ConstraintViolationError : ResponseError
  fail error_class.new(@error_msg, @error_status, @error_code)
end

#raise_unless_response_code(code) ⇒ Object



192
193
194
# File 'lib/neo4j-server/cypher_response.rb', line 192

def raise_unless_response_code(code)
  fail "Response code #{response.status}, expected #{code} for #{response.headers[:location]}, #{response.body}" unless response.status == code
end

#rest_dataObject



260
261
262
263
# File 'lib/neo4j-server/cypher_response.rb', line 260

def rest_data
  @result_index = @row_index = 0
  mapped_rest_data
end

#rest_data_with_idObject



265
266
267
268
# File 'lib/neo4j-server/cypher_response.rb', line 265

def rest_data_with_id
  rest_data[:id] = mapped_rest_data[:self].split('/').last.to_i
  rest_data
end

#retryable_error?Boolean

Returns:

  • (Boolean)


183
184
185
186
# File 'lib/neo4j-server/cypher_response.rb', line 183

def retryable_error?
  return unless error?
  RETRYABLE_ERROR_STATUSES.include?(@error_status)
end

#row_pair_in_struct(row, session) ⇒ Object



69
70
71
72
73
74
75
76
# File 'lib/neo4j-server/cypher_response.rb', line 69

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

#set_data(response) ⇒ Object



204
205
206
207
208
209
# File 'lib/neo4j-server/cypher_response.rb', line 204

def set_data(response)
  @data = response[:data]
  @columns = response[:columns]
  @struct = @columns.empty? ? Object.new : Struct.new(*@columns.map(&:to_sym))
  self
end

#set_error(error) ⇒ Object



211
212
213
214
215
216
217
# File 'lib/neo4j-server/cypher_response.rb', line 211

def set_error(error)
  @error = true
  @error_msg = error[:message]
  @error_status = error[:status] || error[:exception] || error[:code]
  @error_code = error[:code] || error[:fullname]
  self
end

#to_node_enumeration(cypher = EMPTY_STRING, session = Neo4j::Session.current) ⇒ Object



58
59
60
61
62
63
64
65
66
67
# File 'lib/neo4j-server/cypher_response.rb', line 58

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

#to_struct_enumeration(cypher = EMPTY_STRING) ⇒ Object



54
55
56
# File 'lib/neo4j-server/cypher_response.rb', line 54

def to_struct_enumeration(cypher = EMPTY_STRING)
  HashEnumeration.new(self, cypher)
end

#transaction_response?Boolean

Returns:

  • (Boolean)


256
257
258
# File 'lib/neo4j-server/cypher_response.rb', line 256

def transaction_response?
  response.respond_to?(:body) && !response.body[:commit].nil?
end

#unwrapped!Object



125
126
127
# File 'lib/neo4j-server/cypher_response.rb', line 125

def unwrapped!
  @_unwrapped_obj = true
end

#unwrapped?Boolean

Returns:

  • (Boolean)


129
130
131
# File 'lib/neo4j-server/cypher_response.rb', line 129

def unwrapped?
  !!@_unwrapped_obj
end