neo4j-core 5.0.10 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +0 -4
- data/README.md +32 -6
- data/lib/neo4j/label.rb +0 -1
- data/lib/neo4j/node.rb +6 -1
- data/lib/neo4j-core/helpers.rb +2 -7
- data/lib/neo4j-core/query.rb +25 -5
- data/lib/neo4j-core/query_clauses.rb +136 -39
- data/lib/neo4j-core/version.rb +1 -1
- data/lib/neo4j-core.rb +0 -1
- data/lib/neo4j-embedded/embedded_session.rb +15 -9
- data/lib/neo4j-embedded.rb +1 -1
- data/lib/neo4j-server/cypher_node.rb +8 -6
- data/lib/neo4j-server/cypher_relationship.rb +11 -5
- data/lib/neo4j-server/cypher_response.rb +9 -6
- data/lib/neo4j-server/cypher_session.rb +18 -14
- data/lib/neo4j-server/cypher_transaction.rb +0 -1
- data/lib/neo4j-server.rb +0 -1
- data/neo4j-core.gemspec +1 -2
- metadata +6 -25
- data/lib/neo4j/tasks/config_server.rb +0 -36
- data/lib/neo4j/tasks/neo4j_server.rake +0 -258
- data/lib/neo4j-core/cypher_translator.rb +0 -76
- data/lib/neo4j-core/hash_with_indifferent_access.rb +0 -174
- data/lib/neo4j-server/cypher_node_uncommited.rb +0 -14
|
@@ -13,6 +13,7 @@ module Neo4j
|
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
+
class ConstraintViolationError < ResponseError; end
|
|
16
17
|
|
|
17
18
|
class HashEnumeration
|
|
18
19
|
include Enumerable
|
|
@@ -201,9 +202,15 @@ module Neo4j
|
|
|
201
202
|
self
|
|
202
203
|
end
|
|
203
204
|
|
|
205
|
+
CONSTRAINT_ERROR = 'Neo.ClientError.Schema.ConstraintViolation'
|
|
204
206
|
def raise_error
|
|
205
207
|
fail 'Tried to raise error without an error' unless @error
|
|
206
|
-
|
|
208
|
+
error_class = constraint_error? ? ConstraintViolationError : ResponseError
|
|
209
|
+
fail error_class.new(@error_msg, @error_status, @error_code)
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def constraint_error?
|
|
213
|
+
@error_code == CONSTRAINT_ERROR || @error_msg.include?('already exists with')
|
|
207
214
|
end
|
|
208
215
|
|
|
209
216
|
def raise_cypher_error
|
|
@@ -228,11 +235,7 @@ module Neo4j
|
|
|
228
235
|
|
|
229
236
|
new(response, true).tap do |cr|
|
|
230
237
|
body = response.body
|
|
231
|
-
|
|
232
|
-
cr.set_data(body[:results].first)
|
|
233
|
-
else
|
|
234
|
-
cr.set_error(body[:errors].first)
|
|
235
|
-
end
|
|
238
|
+
body[:errors].empty? ? cr.set_data(body[:results].first) : cr.set_error(body[:errors].first)
|
|
236
239
|
end
|
|
237
240
|
end
|
|
238
241
|
|
|
@@ -8,7 +8,6 @@ module Neo4j
|
|
|
8
8
|
|
|
9
9
|
class CypherSession < Neo4j::Session
|
|
10
10
|
include Resource
|
|
11
|
-
include Neo4j::Core::CypherTranslator
|
|
12
11
|
|
|
13
12
|
alias_method :super_query, :query
|
|
14
13
|
attr_reader :connection
|
|
@@ -102,9 +101,14 @@ module Neo4j
|
|
|
102
101
|
end
|
|
103
102
|
|
|
104
103
|
def create_node(props = nil, labels = [])
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
104
|
+
label_string = labels.empty? ? '' : (':' + labels.map { |k| "`#{k}`" }.join(':'))
|
|
105
|
+
if !props.nil?
|
|
106
|
+
prop = '{props}'
|
|
107
|
+
props.each_key { |k| props.delete(k) if props[k].nil? }
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
id = _query_or_fail("CREATE (n#{label_string} #{prop}) RETURN ID(n)", true, props: props)
|
|
111
|
+
CypherNode.new(self, props.nil? ? id : {id: id, metadata: {labels: labels}, data: props})
|
|
108
112
|
end
|
|
109
113
|
|
|
110
114
|
def load_node(neo_id)
|
|
@@ -114,11 +118,9 @@ module Neo4j
|
|
|
114
118
|
def load_relationship(neo_id)
|
|
115
119
|
query.unwrapped.optional_match('(n)-[r]-()').where(r: {neo_id: neo_id}).pluck(:r).first
|
|
116
120
|
rescue Neo4j::Session::CypherError => cypher_error
|
|
117
|
-
if cypher_error.message.match(/not found$/)
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
raise cypher_error
|
|
121
|
-
end
|
|
121
|
+
return nil if cypher_error.message.match(/not found$/)
|
|
122
|
+
|
|
123
|
+
raise cypher_error
|
|
122
124
|
end
|
|
123
125
|
|
|
124
126
|
def create_label(name)
|
|
@@ -206,13 +208,13 @@ module Neo4j
|
|
|
206
208
|
query, params = query_and_params(query, params)
|
|
207
209
|
|
|
208
210
|
curr_tx = Neo4j::Transaction.current
|
|
209
|
-
ActiveSupport::Notifications.instrument('neo4j.cypher_query', context: options[:context]
|
|
211
|
+
ActiveSupport::Notifications.instrument('neo4j.cypher_query', params: params, context: options[:context],
|
|
212
|
+
cypher: query, pretty_cypher: options[:pretty_cypher]) do
|
|
210
213
|
if curr_tx
|
|
211
214
|
curr_tx._query(query, params)
|
|
212
215
|
else
|
|
213
|
-
url = resource_url(:cypher)
|
|
214
216
|
query = params.nil? ? {'query' => query} : {'query' => query, 'params' => params}
|
|
215
|
-
response = @connection.post(
|
|
217
|
+
response = @connection.post(resource_url(:cypher), query)
|
|
216
218
|
CypherResponse.create_with_no_tx(response)
|
|
217
219
|
end
|
|
218
220
|
end
|
|
@@ -235,12 +237,14 @@ module Neo4j
|
|
|
235
237
|
end
|
|
236
238
|
|
|
237
239
|
EMPTY = ''
|
|
240
|
+
NEWLINE_W_SPACES = "\n "
|
|
238
241
|
def self.log_with
|
|
239
|
-
clear, yellow, cyan = %W(\e[0m \e[33m \e[36m)
|
|
240
242
|
ActiveSupport::Notifications.subscribe('neo4j.cypher_query') do |_, start, finish, _id, payload|
|
|
241
243
|
ms = (finish - start) * 1000
|
|
242
244
|
params_string = (payload[:params] && payload[:params].size > 0 ? "| #{payload[:params].inspect}" : EMPTY)
|
|
243
|
-
|
|
245
|
+
cypher = payload[:pretty_cypher] ? NEWLINE_W_SPACES + payload[:pretty_cypher].gsub(/\n/, NEWLINE_W_SPACES) : payload[:cypher]
|
|
246
|
+
|
|
247
|
+
yield(" #{ANSI::CYAN}#{payload[:context] || 'CYPHER'}#{ANSI::CLEAR} #{ANSI::YELLOW}#{ms.round}ms#{ANSI::CLEAR} #{cypher} #{params_string}")
|
|
244
248
|
end
|
|
245
249
|
end
|
|
246
250
|
end
|
|
@@ -9,7 +9,6 @@ module Neo4j
|
|
|
9
9
|
# If a transaction is created and then closed without performing any queries, an OpenStruct is returned that behaves like a successfully closed query.
|
|
10
10
|
class CypherTransaction
|
|
11
11
|
include Neo4j::Transaction::Instance
|
|
12
|
-
include Neo4j::Core::CypherTranslator
|
|
13
12
|
include Resource
|
|
14
13
|
|
|
15
14
|
attr_reader :commit_url, :query_url, :base_url, :connection
|
data/lib/neo4j-server.rb
CHANGED
|
@@ -7,7 +7,6 @@ require 'neo4j-server/cypher_node'
|
|
|
7
7
|
require 'neo4j-server/cypher_label'
|
|
8
8
|
require 'neo4j-server/label'
|
|
9
9
|
require 'neo4j-server/cypher_session'
|
|
10
|
-
require 'neo4j-server/cypher_node_uncommited'
|
|
11
10
|
require 'neo4j-server/cypher_relationship'
|
|
12
11
|
require 'neo4j-server/cypher_response'
|
|
13
12
|
require 'neo4j-server/cypher_transaction'
|
data/neo4j-core.gemspec
CHANGED
|
@@ -30,11 +30,10 @@ Neo4j-core provides classes and methods to work with the graph database Neo4j.
|
|
|
30
30
|
s.add_dependency('httpclient')
|
|
31
31
|
s.add_dependency('faraday_middleware', '~> 0.9.1')
|
|
32
32
|
s.add_dependency('json')
|
|
33
|
-
s.add_dependency('os') # for Rake task
|
|
34
|
-
s.add_dependency('zip') # for Rake task
|
|
35
33
|
s.add_dependency('activesupport') # For ActiveSupport::Notifications
|
|
36
34
|
s.add_dependency('multi_json')
|
|
37
35
|
s.add_dependency('faraday_middleware-multi_json')
|
|
36
|
+
s.add_dependency('neo4j-rake_tasks')
|
|
38
37
|
|
|
39
38
|
s.add_development_dependency('pry')
|
|
40
39
|
s.add_development_dependency('yard')
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: neo4j-core
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 5.0
|
|
4
|
+
version: 5.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andreas Ronge, Chris Grigg, Brian Underwood
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2015-08-
|
|
11
|
+
date: 2015-08-17 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: httparty
|
|
@@ -95,21 +95,7 @@ dependencies:
|
|
|
95
95
|
- !ruby/object:Gem::Version
|
|
96
96
|
version: '0'
|
|
97
97
|
- !ruby/object:Gem::Dependency
|
|
98
|
-
name:
|
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
|
100
|
-
requirements:
|
|
101
|
-
- - ">="
|
|
102
|
-
- !ruby/object:Gem::Version
|
|
103
|
-
version: '0'
|
|
104
|
-
type: :runtime
|
|
105
|
-
prerelease: false
|
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
-
requirements:
|
|
108
|
-
- - ">="
|
|
109
|
-
- !ruby/object:Gem::Version
|
|
110
|
-
version: '0'
|
|
111
|
-
- !ruby/object:Gem::Dependency
|
|
112
|
-
name: zip
|
|
98
|
+
name: activesupport
|
|
113
99
|
requirement: !ruby/object:Gem::Requirement
|
|
114
100
|
requirements:
|
|
115
101
|
- - ">="
|
|
@@ -123,7 +109,7 @@ dependencies:
|
|
|
123
109
|
- !ruby/object:Gem::Version
|
|
124
110
|
version: '0'
|
|
125
111
|
- !ruby/object:Gem::Dependency
|
|
126
|
-
name:
|
|
112
|
+
name: multi_json
|
|
127
113
|
requirement: !ruby/object:Gem::Requirement
|
|
128
114
|
requirements:
|
|
129
115
|
- - ">="
|
|
@@ -137,7 +123,7 @@ dependencies:
|
|
|
137
123
|
- !ruby/object:Gem::Version
|
|
138
124
|
version: '0'
|
|
139
125
|
- !ruby/object:Gem::Dependency
|
|
140
|
-
name: multi_json
|
|
126
|
+
name: faraday_middleware-multi_json
|
|
141
127
|
requirement: !ruby/object:Gem::Requirement
|
|
142
128
|
requirements:
|
|
143
129
|
- - ">="
|
|
@@ -151,7 +137,7 @@ dependencies:
|
|
|
151
137
|
- !ruby/object:Gem::Version
|
|
152
138
|
version: '0'
|
|
153
139
|
- !ruby/object:Gem::Dependency
|
|
154
|
-
name:
|
|
140
|
+
name: neo4j-rake_tasks
|
|
155
141
|
requirement: !ruby/object:Gem::Requirement
|
|
156
142
|
requirements:
|
|
157
143
|
- - ">="
|
|
@@ -261,8 +247,6 @@ files:
|
|
|
261
247
|
- lib/ext/kernel.rb
|
|
262
248
|
- lib/neo4j-core.rb
|
|
263
249
|
- lib/neo4j-core/active_entity.rb
|
|
264
|
-
- lib/neo4j-core/cypher_translator.rb
|
|
265
|
-
- lib/neo4j-core/hash_with_indifferent_access.rb
|
|
266
250
|
- lib/neo4j-core/helpers.rb
|
|
267
251
|
- lib/neo4j-core/label.rb
|
|
268
252
|
- lib/neo4j-core/query.rb
|
|
@@ -285,7 +269,6 @@ files:
|
|
|
285
269
|
- lib/neo4j-server.rb
|
|
286
270
|
- lib/neo4j-server/cypher_label.rb
|
|
287
271
|
- lib/neo4j-server/cypher_node.rb
|
|
288
|
-
- lib/neo4j-server/cypher_node_uncommited.rb
|
|
289
272
|
- lib/neo4j-server/cypher_relationship.rb
|
|
290
273
|
- lib/neo4j-server/cypher_response.rb
|
|
291
274
|
- lib/neo4j-server/cypher_session.rb
|
|
@@ -300,8 +283,6 @@ files:
|
|
|
300
283
|
- lib/neo4j/property_validator.rb
|
|
301
284
|
- lib/neo4j/relationship.rb
|
|
302
285
|
- lib/neo4j/session.rb
|
|
303
|
-
- lib/neo4j/tasks/config_server.rb
|
|
304
|
-
- lib/neo4j/tasks/neo4j_server.rake
|
|
305
286
|
- lib/neo4j/transaction.rb
|
|
306
287
|
- neo4j-core.gemspec
|
|
307
288
|
homepage: https://github.com/neo4jrb/neo4j-core
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
module Neo4j
|
|
2
|
-
module Tasks
|
|
3
|
-
module ConfigServer
|
|
4
|
-
def config(source_text, port)
|
|
5
|
-
s = set_property(source_text, 'org.neo4j.server.webserver.https.enabled', 'false')
|
|
6
|
-
set_property(s, 'org.neo4j.server.webserver.port', port)
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
def set_property(source_text, property, value)
|
|
10
|
-
source_text.gsub(/#{property}\s*=\s*(\w+)/, "#{property}=#{value}")
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
# Toggles the status of Neo4j 2.2's basic auth
|
|
14
|
-
def toggle_auth(status, source_text)
|
|
15
|
-
status_string = status == :enable ? 'true' : 'false'
|
|
16
|
-
%w(dbms.security.authorization_enabled dbms.security.auth_enabled).each do |key|
|
|
17
|
-
source_text = set_property(source_text, key, status_string)
|
|
18
|
-
end
|
|
19
|
-
source_text
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
# POSTs to an endpoint with the form required to change a Neo4j password
|
|
23
|
-
# @param [String] target_address The server address, with protocol and port, against which the form should be POSTed
|
|
24
|
-
# @param [String] old_password The existing password for the "neo4j" user account
|
|
25
|
-
# @param [String] new_password The new password you want to use. Shocking, isn't it?
|
|
26
|
-
# @return [Hash] The response from the server indicating success/failure.
|
|
27
|
-
def change_password(target_address, old_password, new_password)
|
|
28
|
-
uri = URI.parse("#{target_address}/user/neo4j/password")
|
|
29
|
-
response = Net::HTTP.post_form(uri, 'password' => old_password, 'new_password' => new_password)
|
|
30
|
-
JSON.parse(response.body)
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
extend self
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|
|
@@ -1,258 +0,0 @@
|
|
|
1
|
-
# :nocov:
|
|
2
|
-
# borrowed from architect4r
|
|
3
|
-
require 'os'
|
|
4
|
-
require 'httparty'
|
|
5
|
-
require 'zip'
|
|
6
|
-
require 'httparty'
|
|
7
|
-
require File.expand_path('../config_server', __FILE__)
|
|
8
|
-
|
|
9
|
-
namespace :neo4j do
|
|
10
|
-
def file_name
|
|
11
|
-
OS::Underlying.windows? ? 'neo4j.zip' : 'neo4j-unix.tar.gz'
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def download_url(edition)
|
|
15
|
-
"http://dist.neo4j.org/neo4j-#{edition}-#{OS::Underlying.windows? ? 'windows.zip' : 'unix.tar.gz'}"
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def download_neo4j_unless_exists(edition)
|
|
19
|
-
download_neo4j(edition) unless File.exist?(file_name)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def download_neo4j(edition)
|
|
23
|
-
success = false
|
|
24
|
-
|
|
25
|
-
File.open(file_name, 'wb') do |file|
|
|
26
|
-
file << request_url(download_url(edition))
|
|
27
|
-
success = true
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
file_name
|
|
31
|
-
ensure
|
|
32
|
-
File.delete(file_name) unless success
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def request_url(url)
|
|
36
|
-
status = HTTParty.head(url).code
|
|
37
|
-
fail "#{edition} is not available to download, try a different version" if status < 200 || status >= 300
|
|
38
|
-
|
|
39
|
-
HTTParty.get(url)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def get_environment(args)
|
|
43
|
-
args[:environment] || 'development'
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def install_location(args)
|
|
47
|
-
FileUtils.mkdir_p('db/neo4j')
|
|
48
|
-
"db/neo4j/#{get_environment(args)}"
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def config_location(args)
|
|
52
|
-
"#{install_location(args)}/conf/neo4j-server.properties"
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def start_server(command, args)
|
|
56
|
-
puts "Starting Neo4j #{get_environment(args)}..."
|
|
57
|
-
if OS::Underlying.windows?
|
|
58
|
-
start_windows_server(command, args)
|
|
59
|
-
else
|
|
60
|
-
start_starnix_server(command, args)
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def system_or_fail(command)
|
|
65
|
-
system(command) or fail "Unable to run: #{command}" # rubocop:disable Style/AndOr
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def start_windows_server(command, args)
|
|
69
|
-
if system_or_fail!('reg query "HKU\\S-1-5-19"').size > 0
|
|
70
|
-
system_or_fail("#{install_location(args)}/bin/Neo4j.bat #{command}") # start service
|
|
71
|
-
else
|
|
72
|
-
puts 'Starting Neo4j directly, not as a service.'
|
|
73
|
-
system_or_fail("#{install_location(args)}/bin/Neo4j.bat")
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
def start_starnix_server(command, args)
|
|
78
|
-
system_or_fail("#{install_location(args)}/bin/neo4j #{command}")
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
def get_edition(args)
|
|
82
|
-
edition_string = args[:edition]
|
|
83
|
-
|
|
84
|
-
edition_string.gsub(/-latest$/) do
|
|
85
|
-
require 'open-uri'
|
|
86
|
-
puts 'Retrieving latest version...'
|
|
87
|
-
latest_version = JSON.parse(open('https://api.github.com/repos/neo4j/neo4j/releases/latest').read)['tag_name']
|
|
88
|
-
puts "Latest version is: #{latest_version}"
|
|
89
|
-
"-#{latest_version}"
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
desc 'Install Neo4j with auth disabled in v2.2+, example neo4j:install[community-latest,development]'
|
|
94
|
-
task :install, :edition, :environment do |_, args|
|
|
95
|
-
args.with_default_arguments(edition: 'community-latest', environment: 'development')
|
|
96
|
-
edition = get_edition(args)
|
|
97
|
-
environment = get_environment(args)
|
|
98
|
-
puts "Installing Neo4j-#{edition} environment: #{environment}"
|
|
99
|
-
|
|
100
|
-
downloaded_file = download_neo4j_unless_exists edition
|
|
101
|
-
|
|
102
|
-
if OS::Underlying.windows?
|
|
103
|
-
# Extract and move to neo4j directory
|
|
104
|
-
unless File.exist?(install_location(args))
|
|
105
|
-
Zip::ZipFile.open(downloaded_file) do |zip_file|
|
|
106
|
-
zip_file.each do |f|
|
|
107
|
-
f_path = File.join('.', f.name)
|
|
108
|
-
FileUtils.mkdir_p(File.dirname(f_path))
|
|
109
|
-
begin
|
|
110
|
-
zip_file.extract(f, f_path) unless File.exist?(f_path)
|
|
111
|
-
rescue
|
|
112
|
-
puts "#{f.name} failed to extract."
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
FileUtils.mv "neo4j-#{edition}", install_location(args)
|
|
117
|
-
FileUtils.rm downloaded_file
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
# Install if running with Admin Privileges
|
|
121
|
-
if system_or_fail('reg query "HKU\\S-1-5-19"').size > 0
|
|
122
|
-
system_or_fail("\"#{install_location(args)}/bin/neo4j install\"")
|
|
123
|
-
puts 'Neo4j Installed as a service.'
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
else
|
|
127
|
-
system_or_fail("tar -xvf #{downloaded_file}")
|
|
128
|
-
system_or_fail("mv neo4j-#{edition} #{install_location(args)}")
|
|
129
|
-
system_or_fail("rm #{downloaded_file}")
|
|
130
|
-
puts 'Neo4j Installed in to neo4j directory.'
|
|
131
|
-
end
|
|
132
|
-
rake_auth_toggle(args, :disable) unless /-2\.0|1\.[0-9]/.match(args[:edition])
|
|
133
|
-
puts "Type 'rake neo4j:start' or 'rake neo4j:start[ENVIRONMENT]' to start it\nType 'neo4j:config[ENVIRONMENT,PORT]' for changing server port, (default 7474)"
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
desc 'Start the Neo4j Server'
|
|
137
|
-
task :start, :environment do |_, args|
|
|
138
|
-
start_server('start', args)
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
desc 'Start the Neo4j Server asynchronously'
|
|
142
|
-
task :start_no_wait, :environment do |_, args|
|
|
143
|
-
start_server('start-no-wait', args)
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
desc 'Configure Server, e.g. rake neo4j:config[development,8888]'
|
|
147
|
-
task :config, :environment, :port do |_, args|
|
|
148
|
-
port = args[:port]
|
|
149
|
-
fail 'no port given' unless port
|
|
150
|
-
puts "Config Neo4j #{get_environment(args)} for port #{port}"
|
|
151
|
-
location = config_location(args)
|
|
152
|
-
text = File.read(location)
|
|
153
|
-
replace = Neo4j::Tasks::ConfigServer.config(text, port)
|
|
154
|
-
File.open(location, 'w') { |file| file.puts replace }
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
def validate_is_system_admin!
|
|
158
|
-
return unless OS::Underlying.windows?
|
|
159
|
-
return if system_or_fail("reg query \"HKU\\S-1-5-19\"").size > 0
|
|
160
|
-
|
|
161
|
-
fail 'You do not have administrative rights to stop the Neo4j Service'
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
def run_neo4j_command_or_fail!(args, command)
|
|
165
|
-
binary = OS::Underlying.windows? ? 'Neo4j.bat' : 'neo4j'
|
|
166
|
-
|
|
167
|
-
system_or_fail("#{install_location(args)}/bin/#{binary} #{command}")
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
desc 'Stop the Neo4j Server'
|
|
171
|
-
task :stop, :environment do |_, args|
|
|
172
|
-
puts "Stopping Neo4j #{get_environment(args)}..."
|
|
173
|
-
validate_is_system_admin!
|
|
174
|
-
|
|
175
|
-
run_neo4j_command_or_fail!(args, :stop)
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
desc 'Get info the Neo4j Server'
|
|
179
|
-
task :info, :environment do |_, args|
|
|
180
|
-
puts "Info from Neo4j #{get_environment(args)}..."
|
|
181
|
-
validate_is_system_admin!
|
|
182
|
-
|
|
183
|
-
run_neo4j_command_or_fail!(args, :info)
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
desc 'Restart the Neo4j Server'
|
|
187
|
-
task :restart, :environment do |_, args|
|
|
188
|
-
puts "Restarting Neo4j #{get_environment(args)}..."
|
|
189
|
-
validate_is_system_admin!
|
|
190
|
-
|
|
191
|
-
run_neo4j_command_or_fail!(args, :restart)
|
|
192
|
-
end
|
|
193
|
-
|
|
194
|
-
desc 'Reset the Neo4j Server'
|
|
195
|
-
task :reset_yes_i_am_sure, :environment do |_, args|
|
|
196
|
-
validate_is_system_admin!
|
|
197
|
-
|
|
198
|
-
run_neo4j_command_or_fail!(args, :stop)
|
|
199
|
-
|
|
200
|
-
# Reset the database
|
|
201
|
-
FileUtils.rm_rf("#{install_location(args)}/data/graph.db")
|
|
202
|
-
FileUtils.mkdir("#{install_location(args)}/data/graph.db")
|
|
203
|
-
|
|
204
|
-
# Remove log files
|
|
205
|
-
FileUtils.rm_rf("#{install_location(args)}/data/log")
|
|
206
|
-
FileUtils.mkdir("#{install_location(args)}/data/log")
|
|
207
|
-
|
|
208
|
-
run_neo4j_command_or_fail!(args, :start)
|
|
209
|
-
end
|
|
210
|
-
|
|
211
|
-
desc 'Neo4j 2.2: Change connection password'
|
|
212
|
-
task :change_password do
|
|
213
|
-
puts 'This will change the password for a Neo4j server'
|
|
214
|
-
puts 'Enter target IP address or host name without protocal and port, press enter for http://localhost:7474'
|
|
215
|
-
address = STDIN.gets.chomp
|
|
216
|
-
target_address = address.empty? ? 'http://localhost:7474' : address
|
|
217
|
-
|
|
218
|
-
puts 'Input current password. Leave blank if this is a fresh installation of Neo4j.'
|
|
219
|
-
password = STDIN.gets.chomp
|
|
220
|
-
old_password = password.empty? ? 'neo4j' : password
|
|
221
|
-
|
|
222
|
-
puts 'Input new password.'
|
|
223
|
-
new_password = STDIN.gets.chomp
|
|
224
|
-
fail 'A new password is required' if new_password.empty?
|
|
225
|
-
|
|
226
|
-
body = Neo4j::Tasks::ConfigServer.change_password(target_address, old_password, new_password)
|
|
227
|
-
if body['errors']
|
|
228
|
-
puts "An error was returned: #{body['errors'][0]['message']}"
|
|
229
|
-
else
|
|
230
|
-
puts 'Password changed successfully! Please update your app to use:'
|
|
231
|
-
puts 'username: neo4j'
|
|
232
|
-
puts "password: #{new_password}"
|
|
233
|
-
end
|
|
234
|
-
end
|
|
235
|
-
|
|
236
|
-
def rake_auth_toggle(args, status)
|
|
237
|
-
location = config_location(args)
|
|
238
|
-
text = File.read(location)
|
|
239
|
-
replace = Neo4j::Tasks::ConfigServer.toggle_auth(status, text)
|
|
240
|
-
File.open(location, 'w') { |file| file.puts replace }
|
|
241
|
-
end
|
|
242
|
-
|
|
243
|
-
def auth_toggle_complete(status)
|
|
244
|
-
puts "Neo4j basic authentication #{status}. Restart server to apply."
|
|
245
|
-
end
|
|
246
|
-
|
|
247
|
-
desc 'Neo4j 2.2: Enable Auth'
|
|
248
|
-
task :enable_auth, :environment do |_, args|
|
|
249
|
-
rake_auth_toggle(args, :enable)
|
|
250
|
-
auth_toggle_complete('enabled')
|
|
251
|
-
end
|
|
252
|
-
|
|
253
|
-
desc 'Neo4j 2.2: Disable Auth'
|
|
254
|
-
task :disable_auth, :environment do |_, args|
|
|
255
|
-
rake_auth_toggle(args, :disable)
|
|
256
|
-
auth_toggle_complete('disabled')
|
|
257
|
-
end
|
|
258
|
-
end
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
module Neo4j
|
|
2
|
-
module Core
|
|
3
|
-
module CypherTranslator
|
|
4
|
-
# Cypher Helper
|
|
5
|
-
def escape_value(value)
|
|
6
|
-
if value.is_a?(String) || value.is_a?(Symbol)
|
|
7
|
-
"'#{escape_quotes(sanitize_escape_sequences(value.to_s))}'"
|
|
8
|
-
else
|
|
9
|
-
value
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
# Like escape_value but it does not wrap the value in quotes
|
|
14
|
-
def create_escape_value(value)
|
|
15
|
-
if value.is_a?(String) || value.is_a?(Symbol)
|
|
16
|
-
"#{sanitize_escape_sequences(value.to_s)}"
|
|
17
|
-
else
|
|
18
|
-
value
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
# Only following escape sequence characters are allowed in Cypher:
|
|
23
|
-
#
|
|
24
|
-
# \t Tab
|
|
25
|
-
# \b Backspace
|
|
26
|
-
# \n Newline
|
|
27
|
-
# \r Carriage return
|
|
28
|
-
# \f Form feed
|
|
29
|
-
# \' Single quote
|
|
30
|
-
# \" Double quote
|
|
31
|
-
# \\ Backslash
|
|
32
|
-
#
|
|
33
|
-
# From:
|
|
34
|
-
# http://docs.neo4j.org/chunked/stable/cypher-expressions.html#_note_on_string_literals
|
|
35
|
-
SANITIZE_ESCAPED_REGEXP = /(?<!\\)\\(\\\\)*(?![futbnr'"\\])/
|
|
36
|
-
EMPTY_PROPS = ''
|
|
37
|
-
|
|
38
|
-
def sanitize_escape_sequences(s)
|
|
39
|
-
s.gsub SANITIZE_ESCAPED_REGEXP, EMPTY_PROPS
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def escape_quotes(s)
|
|
43
|
-
s.gsub("'", %q(\\\'))
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
# Cypher Helper
|
|
47
|
-
def cypher_prop_list!(props)
|
|
48
|
-
return nil unless props
|
|
49
|
-
props.reject! { |_, v| v.nil? }
|
|
50
|
-
{props: props.each { |k, v| props[k] = create_escape_value(v) }}
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
# Stolen from keymaker
|
|
54
|
-
# https://github.com/therubymug/keymaker/blob/master/lib/keymaker/parsers/cypher_response_parser.rb
|
|
55
|
-
def self.translate_response(response_body, result)
|
|
56
|
-
Hashie::Mash.new(Hash[sanitized_column_names(response_body).zip(result)])
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def self.sanitized_column_names(response_body)
|
|
60
|
-
response_body.columns.map { |column| column[/[^\.]+$/] }
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def cypher_string(labels, props)
|
|
64
|
-
"CREATE (n#{label_string(labels)} #{prop_identifier(props)}) RETURN ID(n)"
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def label_string(labels)
|
|
68
|
-
labels.empty? ? '' : ":#{labels.map { |k| "`#{k}`" }.join(':')}"
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def prop_identifier(props)
|
|
72
|
-
'{props}' unless props.nil?
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
end
|