Class: Neo4j::Server::CypherSession
Constant Summary
collapse
- DEFAULT_RETRY_COUNT =
ENV['NEO4J_RETRY_COUNT'].nil? ? 10 : ENV['NEO4J_RETRY_COUNT'].to_i
- EMPTY =
''
- NEWLINE_W_SPACES =
"\n "
Instance Attribute Summary collapse
Attributes included from Resource
#resource_data, #resource_url
Class Method Summary
collapse
Instance Method Summary
collapse
-
#_query(query, params = {}, options = {}) ⇒ Object
-
#_query_data(query) ⇒ Object
-
#_query_entity_data(query, id = nil, params = {}) ⇒ Object
-
#_query_or_fail(query, single_row = false, params = {}, retry_count = DEFAULT_RETRY_COUNT) ⇒ Object
-
#_retry_or_raise(query, params, single_row, retry_count, response) ⇒ Object
-
#create_label(name) ⇒ Object
-
#create_node(props = nil, labels = []) ⇒ Object
-
#current_transaction ⇒ Object
-
#db_type ⇒ Object
-
#find_all_nodes(label_name) ⇒ Object
-
#find_nodes(label_name, key, value) ⇒ Object
-
#indexes(label) ⇒ Object
-
#initialize(data_url, connection) ⇒ CypherSession
constructor
A new instance of CypherSession.
-
#initialize_resource(data_url) ⇒ Object
-
#inspect ⇒ Object
-
#load_node(neo_id) ⇒ Object
-
#load_relationship(neo_id) ⇒ Object
-
#query(*args) ⇒ Object
-
#query_and_params(query_or_query_string, params) ⇒ Object
-
#schema_properties(query_string) ⇒ Object
-
#search_result_to_enumerable_first_column(response) ⇒ Object
-
#super_query ⇒ Object
-
#to_s ⇒ Object
-
#transaction ⇒ Object
Duplicate of CypherSession::Adaptor::Base#transaction.
-
#uniqueness_constraints(label) ⇒ Object
-
#version ⇒ Object
Methods included from Resource
#convert_from_json_value, #expect_response_code!, #handle_response_error!, #init_resource_data, #resource_headers, #resource_url_id, #response_exception, #wrap_resource
_listeners, _notify_listeners, add_listener, #auto_commit?, clear_listeners, #close, create_session, current, current!, inspect, named, on_next_session_available, query, register, register_db, #running, set_current, #shutdown, #start, #transaction_class, unregister, user_agent_string, validate_session_num!
Constructor Details
#initialize(data_url, connection) ⇒ CypherSession
Returns a new instance of CypherSession.
15
16
17
18
19
20
|
# File 'lib/neo4j-server/cypher_session.rb', line 15
def initialize(data_url, connection)
@connection = connection
Neo4j::Session.register(self)
initialize_resource(data_url)
Neo4j::Session._notify_listeners(:session_available, self)
end
|
Instance Attribute Details
#connection ⇒ Object
Returns the value of attribute connection.
13
14
15
|
# File 'lib/neo4j-server/cypher_session.rb', line 13
def connection
@connection
end
|
Class Method Details
.create_connection(params, url = nil) ⇒ Faraday
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
# File 'lib/neo4j-server/cypher_session.rb', line 25
def self.create_connection(params, url = nil)
init_params = params[:initialize] && params.delete(:initialize)
conn = Faraday.new(url, init_params) do |b|
b.request :basic_auth, params[:basic_auth][:username], params[:basic_auth][:password] if params[:basic_auth]
b.request :multi_json
b.response :multi_json, symbolize_keys: true, content_type: 'application/json'
b.use Faraday::Adapter::NetHttpPersistent
end
conn. = {'Content-Type' => 'application/json', 'User-Agent' => ::Neo4j::Session.user_agent_string}
conn
end
|
.establish_session(root_data, connection) ⇒ Object
55
56
57
58
59
|
# File 'lib/neo4j-server/cypher_session.rb', line 55
def self.establish_session(root_data, connection)
data_url = root_data[:data]
data_url << '/' unless data_url.nil? || data_url.end_with?('/')
CypherSession.new(data_url, connection)
end
|
.log_with ⇒ Object
250
251
252
253
254
255
256
257
258
|
# File 'lib/neo4j-server/cypher_session.rb', line 250
def self.log_with
ActiveSupport::Notifications.subscribe('neo4j.cypher_query') do |_, start, finish, _id, payload|
ms = (finish - start) * 1000
params_string = (payload[:params] && !payload[:params].empty? ? "| #{payload[:params].inspect}" : EMPTY)
cypher = payload[:pretty_cypher] ? NEWLINE_W_SPACES + payload[:pretty_cypher].gsub(/\n/, NEWLINE_W_SPACES) : payload[:cypher]
yield(" #{ANSI::CYAN}#{payload[:context] || 'CYPHER'}#{ANSI::CLEAR} #{ANSI::YELLOW}#{ms.round}ms#{ANSI::CLEAR} #{cypher} #{params_string}")
end
end
|
.open(endpoint_url = nil, params = {}) ⇒ Object
Opens a session to the database
46
47
48
49
50
51
52
53
|
# File 'lib/neo4j-server/cypher_session.rb', line 46
def self.open(endpoint_url = nil, params = {})
(endpoint_url, params)
url = endpoint_url || 'http://localhost:7474'
connection = params[:connection] || create_connection(params, url)
response = connection.get(url)
fail "Server not available on #{url} (response code #{response.status})" unless response.status == 200
establish_session(response.body, connection)
end
|
.transaction_class ⇒ Object
Instance Method Details
#_query(query, params = {}, options = {}) ⇒ Object
213
214
215
216
217
218
219
220
221
222
223
224
225
226
|
# File 'lib/neo4j-server/cypher_session.rb', line 213
def _query(query, params = {}, options = {})
query, params = query_and_params(query, params)
ActiveSupport::Notifications.instrument('neo4j.cypher_query', params: params, context: options[:context],
cypher: query, pretty_cypher: options[:pretty_cypher]) do
if current_transaction
current_transaction._query(query, params)
else
query = params.nil? ? {'query' => query} : {'query' => query, 'params' => params}
response = @connection.post(resource_url(:cypher), query)
CypherResponse.create_with_no_tx(response)
end
end
end
|
#_query_data(query) ⇒ Object
177
178
179
180
|
# File 'lib/neo4j-server/cypher_session.rb', line 177
def _query_data(query)
r = _query_or_fail(query, true)
Neo4j::Transaction.current ? r : r[:data]
end
|
#_query_entity_data(query, id = nil, params = {}) ⇒ Object
209
210
211
|
# File 'lib/neo4j-server/cypher_session.rb', line 209
def _query_entity_data(query, id = nil, params = {})
_query(query, params).tap(&:raise_if_cypher_error!).entity_data(id)
end
|
#_query_or_fail(query, single_row = false, params = {}, retry_count = DEFAULT_RETRY_COUNT) ⇒ Object
184
185
186
187
188
189
190
191
192
193
|
# File 'lib/neo4j-server/cypher_session.rb', line 184
def _query_or_fail(query, single_row = false, params = {}, retry_count = DEFAULT_RETRY_COUNT)
query, params = query_and_params(query, params)
response = _query(query, params)
if response.error?
_retry_or_raise(query, params, single_row, retry_count, response)
else
single_row ? response.first_data : response
end
end
|
#_retry_or_raise(query, params, single_row, retry_count, response) ⇒ Object
204
205
206
207
|
# File 'lib/neo4j-server/cypher_session.rb', line 204
def _retry_or_raise(query, params, single_row, retry_count, response)
response.raise_error unless response.retryable_error?
retry_count > 0 ? _query_or_fail(query, single_row, params, retry_count - 1) : response.raise_error
end
|
#create_label(name) ⇒ Object
137
138
139
|
# File 'lib/neo4j-server/cypher_session.rb', line 137
def create_label(name)
CypherLabel.new(self, name)
end
|
#create_node(props = nil, labels = []) ⇒ Object
114
115
116
117
118
119
120
121
122
123
|
# File 'lib/neo4j-server/cypher_session.rb', line 114
def create_node(props = nil, labels = [])
label_string = labels.empty? ? '' : (':' + labels.map { |k| "`#{k}`" }.join(':'))
if !props.nil?
prop = '{props}'
props.each_key { |k| props.delete(k) if props[k].nil? }
end
id = _query_or_fail("CREATE (n#{label_string} #{prop}) RETURN ID(n)", true, props: props)
CypherNode.new(self, props.nil? ? id : {id: id, metadata: {labels: labels}, data: props})
end
|
#current_transaction ⇒ Object
#db_type ⇒ Object
68
69
70
|
# File 'lib/neo4j-server/cypher_session.rb', line 68
def db_type
:server_db
end
|
#find_all_nodes(label_name) ⇒ Object
155
156
157
|
# File 'lib/neo4j-server/cypher_session.rb', line 155
def find_all_nodes(label_name)
search_result_to_enumerable_first_column(_query_or_fail("MATCH (n:`#{label_name}`) RETURN ID(n)"))
end
|
#find_nodes(label_name, key, value) ⇒ Object
159
160
161
162
163
164
|
# File 'lib/neo4j-server/cypher_session.rb', line 159
def find_nodes(label_name, key, value)
value = "'#{value}'" if value.is_a? String
response = _query_or_fail("MATCH (n:`#{label_name}`) WHERE n.#{key} = #{value} RETURN ID(n)")
search_result_to_enumerable_first_column(response)
end
|
#indexes(label) ⇒ Object
145
146
147
|
# File 'lib/neo4j-server/cypher_session.rb', line 145
def indexes(label)
schema_properties("/db/data/schema/index/#{label}")
end
|
#initialize_resource(data_url) ⇒ Object
84
85
86
87
88
89
90
91
|
# File 'lib/neo4j-server/cypher_session.rb', line 84
def initialize_resource(data_url)
response = @connection.get(data_url)
expect_response_code!(response, 200)
data_resource = response.body
fail "No data_resource for #{response.body}" unless data_resource
init_resource_data(data_resource, data_url)
end
|
#inspect ⇒ Object
76
77
78
|
# File 'lib/neo4j-server/cypher_session.rb', line 76
def inspect
"#{self} version: '#{version}'"
end
|
#load_node(neo_id) ⇒ Object
125
126
127
|
# File 'lib/neo4j-server/cypher_session.rb', line 125
def load_node(neo_id)
query.unwrapped.match(:n).where(n: {neo_id: neo_id}).pluck(:n).first
end
|
#load_relationship(neo_id) ⇒ Object
129
130
131
132
133
134
135
|
# File 'lib/neo4j-server/cypher_session.rb', line 129
def load_relationship(neo_id)
query.unwrapped.optional_match('(n)-[r]-()').where(r: {neo_id: neo_id}).pluck(:r).first
rescue Neo4j::Session::CypherError => cypher_error
return nil if cypher_error.message =~ /not found$/
raise cypher_error
end
|
#query(*args) ⇒ Object
166
167
168
169
170
171
172
173
174
175
|
# File 'lib/neo4j-server/cypher_session.rb', line 166
def query(*args)
if [[String], [String, Hash]].include?(args.map(&:class))
response = _query(*args)
response.raise_error if response.error?
response.to_node_enumeration(args[0])
else
options = args[0] || {}
Neo4j::Core::Query.new(options.merge(session: self))
end
end
|
#query_and_params(query_or_query_string, params) ⇒ Object
195
196
197
198
199
200
201
202
|
# File 'lib/neo4j-server/cypher_session.rb', line 195
def query_and_params(query_or_query_string, params)
if query_or_query_string.is_a?(::Neo4j::Core::Query)
cypher = query_or_query_string.to_cypher
[cypher, query_or_query_string.send(:merge_params).merge(params)]
else
[query_or_query_string, params]
end
end
|
#schema_properties(query_string) ⇒ Object
149
150
151
152
153
|
# File 'lib/neo4j-server/cypher_session.rb', line 149
def schema_properties(query_string)
response = @connection.get(query_string)
expect_response_code!(response, 200)
{property_keys: response.body.map! { |row| row[:property_keys].map(&:to_sym) }}
end
|
#search_result_to_enumerable_first_column(response) ⇒ Object
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
|
# File 'lib/neo4j-server/cypher_session.rb', line 228
def search_result_to_enumerable_first_column(response)
return [] unless response.data
Enumerator.new do |yielder|
response.data.each do |data|
if current_transaction
data[:row].each do |id|
yielder << CypherNode.new(self, id).wrapper
end
else
yielder << CypherNode.new(self, data[0]).wrapper
end
end
end
end
|
#super_query ⇒ Object
12
|
# File 'lib/neo4j-server/cypher_session.rb', line 12
alias super_query query
|
#to_s ⇒ Object
72
73
74
|
# File 'lib/neo4j-server/cypher_session.rb', line 72
def to_s
"#{self.class} url: '#{@resource_url}'"
end
|
#transaction ⇒ Object
Duplicate of CypherSession::Adaptor::Base#transaction
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
# File 'lib/neo4j-server/cypher_session.rb', line 98
def transaction
return self.class.transaction_class.new(self) if !block_given?
begin
tx = transaction
yield tx
rescue Exception => e tx.mark_failed
raise e
ensure
tx.close
end
end
|
#uniqueness_constraints(label) ⇒ Object
141
142
143
|
# File 'lib/neo4j-server/cypher_session.rb', line 141
def uniqueness_constraints(label)
schema_properties("/db/data/schema/constraint/#{label}/uniqueness")
end
|
#version ⇒ Object
80
81
82
|
# File 'lib/neo4j-server/cypher_session.rb', line 80
def version
resource_data ? resource_data[:neo4j_version] : ''
end
|