orientdb4r 0.2.6 → 0.2.7
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.
- data/README.rdoc +6 -4
- data/changelog.txt +8 -0
- data/lib/orientdb4r/client.rb +23 -3
- data/lib/orientdb4r/node.rb +36 -0
- data/lib/orientdb4r/rest/client.rb +85 -67
- data/lib/orientdb4r/rest/node.rb +79 -0
- data/lib/orientdb4r/rest/restclient_node.rb +70 -0
- data/lib/orientdb4r/utils.rb +1 -1
- data/lib/orientdb4r/version.rb +1 -0
- data/lib/orientdb4r.rb +14 -3
- data/test/readme_sample.rb +6 -4
- data/test/test_database.rb +14 -12
- data/test/test_ddo.rb +5 -0
- data/test/test_dmo.rb +24 -0
- metadata +7 -3
data/README.rdoc
CHANGED
@@ -18,10 +18,12 @@ see Wiki page for more sample at https://github.com/veny/orientdb4r/wiki
|
|
18
18
|
|
19
19
|
client.connect :database => 'temp', :user => 'admin', :password => 'admin'
|
20
20
|
|
21
|
-
client.
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
unless client.class_exists? CLASS
|
22
|
+
client.create_class(CLASS) do |c|
|
23
|
+
c.property 'prop1', :integer, :notnull => true, :min => 1, :max => 99
|
24
|
+
c.property 'prop2', :string, :mandatory => true
|
25
|
+
c.link 'users', :linkset, 'OUser' # by default: :mandatory => false, :notnull => false
|
26
|
+
end
|
25
27
|
end
|
26
28
|
|
27
29
|
admin = client.query("SELECT FROM OUser WHERE name = 'admin'")[0]
|
data/changelog.txt
ADDED
data/lib/orientdb4r/client.rb
CHANGED
@@ -6,6 +6,7 @@ module Orientdb4r
|
|
6
6
|
# Server version used if no concrete version identified.
|
7
7
|
DEFAULT_SERVER_VERSION = '1.0.0--'
|
8
8
|
|
9
|
+
# # Regexp to validate format of providet version.
|
9
10
|
SERVER_VERSION_PATTERN = /^\d+\.\d+\.\d+/
|
10
11
|
|
11
12
|
attr_reader :server_version
|
@@ -13,6 +14,7 @@ module Orientdb4r
|
|
13
14
|
###
|
14
15
|
# Constructor.
|
15
16
|
def initialize
|
17
|
+
@nodes = []
|
16
18
|
@connected = false
|
17
19
|
end
|
18
20
|
|
@@ -75,7 +77,7 @@ module Orientdb4r
|
|
75
77
|
rslt = true
|
76
78
|
begin
|
77
79
|
get_database options
|
78
|
-
rescue
|
80
|
+
rescue OrientdbError
|
79
81
|
rslt = false
|
80
82
|
end
|
81
83
|
rslt
|
@@ -137,6 +139,19 @@ module Orientdb4r
|
|
137
139
|
end
|
138
140
|
|
139
141
|
|
142
|
+
###
|
143
|
+
# Checks existence of a given class.
|
144
|
+
def class_exists?(name)
|
145
|
+
rslt = true
|
146
|
+
begin
|
147
|
+
get_class name
|
148
|
+
rescue NotFoundError
|
149
|
+
rslt = false
|
150
|
+
end
|
151
|
+
rslt
|
152
|
+
end
|
153
|
+
|
154
|
+
|
140
155
|
###
|
141
156
|
# Removes a class from the schema.
|
142
157
|
def drop_class(name, options={})
|
@@ -146,8 +161,8 @@ module Orientdb4r
|
|
146
161
|
opt_pattern = { :mode => :nil }
|
147
162
|
verify_options(options, opt_pattern)
|
148
163
|
if :strict == options[:mode]
|
149
|
-
response =
|
150
|
-
connect_info = process_response
|
164
|
+
response = a_node.request(:method => :get, :uri => "connect/#{@database}") # TODO there cannot be REST
|
165
|
+
connect_info = process_response response
|
151
166
|
children = connect_info['classes'].select { |i| i['superClass'] == name }
|
152
167
|
unless children.empty?
|
153
168
|
raise OrientdbError, "class is super-class, cannot be deleted, name=#{name}"
|
@@ -221,6 +236,11 @@ module Orientdb4r
|
|
221
236
|
|
222
237
|
protected
|
223
238
|
|
239
|
+
def a_node
|
240
|
+
@nodes[0]
|
241
|
+
end
|
242
|
+
|
243
|
+
|
224
244
|
###
|
225
245
|
# Asserts if the client is connected and raises an error if not.
|
226
246
|
def assert_connected
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Orientdb4r
|
2
|
+
|
3
|
+
###
|
4
|
+
# This class represents a single sever/node
|
5
|
+
# in the Distributed Multi-Master Architecture.
|
6
|
+
class Node
|
7
|
+
include Utils
|
8
|
+
|
9
|
+
attr_reader :host, :port # they are immutable
|
10
|
+
|
11
|
+
###
|
12
|
+
# Constructor.
|
13
|
+
def initialize(host, port)
|
14
|
+
raise ArgumentError, 'host cannot be blank' if blank? host
|
15
|
+
raise ArgumentError, 'port cannot be blank' if blank? port
|
16
|
+
@host = host
|
17
|
+
@port = port
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
###
|
22
|
+
# Cleans up resources used by the node.
|
23
|
+
def cleanup
|
24
|
+
raise NotImplementedError, 'this should be overridden by subclass'
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
###
|
29
|
+
# Gets URL of the remote node.
|
30
|
+
def url
|
31
|
+
raise NotImplementedError, 'this should be overridden by subclass'
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -3,24 +3,21 @@ module Orientdb4r
|
|
3
3
|
class RestClient < Client
|
4
4
|
include Aop2
|
5
5
|
|
6
|
-
# Name of cookie that represents a session.
|
7
|
-
SESSION_COOKIE_NAME = 'OSESSIONID'
|
8
6
|
|
9
7
|
before [:query, :command], :assert_connected
|
10
8
|
before [:create_class, :get_class, :drop_class, :create_property], :assert_connected
|
11
9
|
before [:create_document, :get_document, :update_document, :delete_document], :assert_connected
|
12
10
|
around [:query, :command], :time_around
|
13
11
|
|
14
|
-
attr_reader :
|
12
|
+
attr_reader :user, :password, :database
|
15
13
|
|
16
14
|
|
17
15
|
def initialize(options) #:nodoc:
|
18
16
|
super()
|
19
17
|
options_pattern = { :host => 'localhost', :port => 2480, :ssl => false }
|
20
18
|
verify_and_sanitize_options(options, options_pattern)
|
21
|
-
|
22
|
-
@
|
23
|
-
@ssl = options[:ssl]
|
19
|
+
|
20
|
+
@nodes << RestClientNode.new(options[:host], options[:port], options[:ssl])
|
24
21
|
end
|
25
22
|
|
26
23
|
|
@@ -33,40 +30,35 @@ module Orientdb4r
|
|
33
30
|
@user = options[:user]
|
34
31
|
@password = options[:password]
|
35
32
|
|
36
|
-
|
33
|
+
node = a_node
|
37
34
|
begin
|
38
|
-
response =
|
39
|
-
:user => user, :password => password).execute
|
40
|
-
@session_id = response.cookies[SESSION_COOKIE_NAME]
|
41
|
-
rslt = process_response(response, :mode => :strict)
|
42
|
-
|
43
|
-
# resource used for all request
|
44
|
-
@resource = ::RestClient::Resource.new(url, \
|
45
|
-
:user => user, :password => password, :cookies => { SESSION_COOKIE_NAME => session_id})
|
46
|
-
|
47
|
-
decorate_classes_with_model(rslt['classes'])
|
48
|
-
|
49
|
-
# try to read server version
|
50
|
-
if rslt.include? 'server'
|
51
|
-
@server_version = rslt['server']['version']
|
52
|
-
else
|
53
|
-
@server_version = DEFAULT_SERVER_VERSION
|
54
|
-
end
|
55
|
-
raise OrientdbError, "bad version format, version=#{server_version}" unless server_version =~ SERVER_VERSION_PATTERN
|
56
|
-
Orientdb4r::logger.debug "successfully connected to server, version=#{server_version}, session=#{session_id}"
|
57
|
-
|
58
|
-
@connected = true
|
59
|
-
@session_id = response.cookies[SESSION_COOKIE_NAME]
|
35
|
+
response = node.oo_request(:method => :get, :uri => "connect/#{@database}", :user => user, :password => password)
|
60
36
|
rescue
|
61
37
|
@connected = false
|
62
|
-
@session_id = nil
|
63
38
|
@server_version = nil
|
64
39
|
@user = nil
|
65
40
|
@password = nil
|
66
41
|
@database = nil
|
67
|
-
@
|
42
|
+
@nodes.each { |node| node.cleanup }
|
68
43
|
raise ConnectionError
|
69
44
|
end
|
45
|
+
rslt = process_response response
|
46
|
+
node.post_connect(user, password, response)
|
47
|
+
decorate_classes_with_model(rslt['classes'])
|
48
|
+
|
49
|
+
# try to read server version
|
50
|
+
if rslt.include? 'server'
|
51
|
+
@server_version = rslt['server']['version']
|
52
|
+
else
|
53
|
+
@server_version = DEFAULT_SERVER_VERSION
|
54
|
+
end
|
55
|
+
unless server_version =~ SERVER_VERSION_PATTERN
|
56
|
+
Orientdb4r::logger.warn "bad version format, version=#{server_version}"
|
57
|
+
@server_version = DEFAULT_SERVER_VERSION
|
58
|
+
end
|
59
|
+
|
60
|
+
Orientdb4r::logger.debug "successfully connected to server, version=#{server_version}, session=#{node.session_id}"
|
61
|
+
@connected = true
|
70
62
|
rslt
|
71
63
|
end
|
72
64
|
|
@@ -75,35 +67,31 @@ module Orientdb4r
|
|
75
67
|
return unless @connected
|
76
68
|
|
77
69
|
begin
|
78
|
-
|
79
|
-
rescue ::RestClient::Unauthorized
|
70
|
+
a_node.request(:method => :get, :uri => 'disconnect')
|
80
71
|
# https://groups.google.com/forum/?fromgroups#!topic/orient-database/5MAMCvFavTc
|
81
72
|
# Disconnect doesn't require you're authenticated.
|
82
73
|
# It always returns 401 because some browsers intercept this and avoid to reuse the same session again.
|
83
74
|
ensure
|
84
75
|
@connected = false
|
85
76
|
@server_version = nil
|
86
|
-
@session_id = nil
|
87
77
|
@user = nil
|
88
78
|
@password = nil
|
89
79
|
@database = nil
|
90
|
-
@
|
80
|
+
@nodes.each { |node| node.cleanup }
|
91
81
|
Orientdb4r::logger.debug 'disconnected from server'
|
92
82
|
end
|
93
83
|
end
|
94
84
|
|
95
85
|
|
96
86
|
def server(options={}) #:nodoc:
|
97
|
-
# 'server' does NOT use the RestClient Resource to construct the HTTP request
|
98
|
-
|
99
87
|
options_pattern = { :user => :optional, :password => :optional }
|
100
88
|
verify_options(options, options_pattern)
|
101
89
|
|
102
90
|
u = options.include?(:user) ? options[:user] : user
|
103
91
|
p = options.include?(:password) ? options[:password] : password
|
104
|
-
resource = ::RestClient::Resource.new(url, :user => u, :password => p)
|
105
92
|
begin
|
106
|
-
|
93
|
+
# uses one-off request because of additional authentication to the server
|
94
|
+
response = a_node.oo_request :method => :get, :user => u, :password => p, :uri => 'server'
|
107
95
|
rescue
|
108
96
|
raise OrientdbError
|
109
97
|
end
|
@@ -122,9 +110,10 @@ module Orientdb4r
|
|
122
110
|
|
123
111
|
u = options.include?(:user) ? options[:user] : user
|
124
112
|
p = options.include?(:password) ? options[:password] : password
|
125
|
-
resource = ::RestClient::Resource.new(url, :user => u, :password => p)
|
126
113
|
begin
|
127
|
-
|
114
|
+
# uses one-off request because of additional authentication to the server
|
115
|
+
response = a_node.oo_request :method => :post, :user => u, :password => p, \
|
116
|
+
:uri => "database/#{options[:database]}/#{options[:type]}"
|
128
117
|
rescue
|
129
118
|
raise OrientdbError
|
130
119
|
end
|
@@ -146,9 +135,10 @@ module Orientdb4r
|
|
146
135
|
|
147
136
|
u = options.include?(:user) ? options[:user] : user
|
148
137
|
p = options.include?(:password) ? options[:password] : password
|
149
|
-
resource = ::RestClient::Resource.new(url, :user => u, :password => p)
|
150
138
|
begin
|
151
|
-
|
139
|
+
# uses one-off request because of additional authentication to the server
|
140
|
+
response = a_node.oo_request :method => :get, :user => u, :password => p, \
|
141
|
+
:uri => "database/#{options[:database]}"
|
152
142
|
rescue
|
153
143
|
raise NotFoundError
|
154
144
|
end
|
@@ -166,7 +156,11 @@ module Orientdb4r
|
|
166
156
|
|
167
157
|
limit = ''
|
168
158
|
limit = "/#{options[:limit]}" if !options.nil? and options.include?(:limit)
|
169
|
-
|
159
|
+
begin
|
160
|
+
response = a_node.request(:method => :get, :uri => "query/#{@database}/sql/#{CGI::escape(sql)}#{limit}")
|
161
|
+
rescue
|
162
|
+
raise NotFoundError
|
163
|
+
end
|
170
164
|
entries = process_response(response)
|
171
165
|
rslt = entries['result']
|
172
166
|
# mixin all document entries (they have '@class' attribute)
|
@@ -178,14 +172,11 @@ module Orientdb4r
|
|
178
172
|
def command(sql) #:nodoc:
|
179
173
|
raise ArgumentError, 'command is blank' if blank? sql
|
180
174
|
begin
|
181
|
-
|
182
|
-
response = @resource["command/#{@database}/sql/#{CGI::escape(sql)}"].post ''
|
183
|
-
rslt = process_response(response)
|
184
|
-
rslt
|
185
|
-
#puts "RESP #{response.body}"
|
175
|
+
response = a_node.request(:method => :post, :uri => "command/#{@database}/sql/#{CGI::escape(sql)}")
|
186
176
|
rescue
|
187
177
|
raise OrientdbError
|
188
178
|
end
|
179
|
+
process_response(response)
|
189
180
|
end
|
190
181
|
|
191
182
|
|
@@ -196,17 +187,21 @@ module Orientdb4r
|
|
196
187
|
|
197
188
|
if compare_versions(server_version, '1.1.0') >= 0
|
198
189
|
begin
|
199
|
-
response =
|
190
|
+
response = a_node.request(:method => :get, :uri => "class/#{@database}/#{name}")
|
200
191
|
rescue
|
201
192
|
raise NotFoundError
|
202
193
|
end
|
203
|
-
rslt = process_response(response
|
194
|
+
rslt = process_response(response)
|
204
195
|
classes = [rslt]
|
205
196
|
else
|
206
197
|
# there is bug in REST API [v1.0.0, fixed in r5902], only data are returned
|
207
198
|
# workaround - use metadate delivered by 'connect'
|
208
|
-
|
209
|
-
|
199
|
+
begin
|
200
|
+
response = a_node.request(:method => :get, :uri => "connect/#{@database}")
|
201
|
+
rescue
|
202
|
+
raise NotFoundError
|
203
|
+
end
|
204
|
+
connect_info = process_response response
|
210
205
|
|
211
206
|
classes = connect_info['classes'].select { |i| i['name'] == name }
|
212
207
|
raise NotFoundError, "class not found, name=#{name}" unless 1 == classes.size
|
@@ -231,7 +226,8 @@ module Orientdb4r
|
|
231
226
|
|
232
227
|
def create_document(doc)
|
233
228
|
begin
|
234
|
-
response =
|
229
|
+
response = a_node.request(:method => :post, :uri => "document/#{@database}", \
|
230
|
+
:content_type => 'application/json', :data => doc.to_json)
|
235
231
|
rescue
|
236
232
|
raise DataError
|
237
233
|
end
|
@@ -247,7 +243,7 @@ module Orientdb4r
|
|
247
243
|
rid = rid[1..-1] if rid.start_with? '#'
|
248
244
|
|
249
245
|
begin
|
250
|
-
response =
|
246
|
+
response = a_node.request(:method => :get, :uri => "document/#{@database}/#{rid}")
|
251
247
|
rescue
|
252
248
|
raise NotFoundError
|
253
249
|
end
|
@@ -266,7 +262,8 @@ module Orientdb4r
|
|
266
262
|
rid = rid[1..-1] if rid.start_with? '#'
|
267
263
|
|
268
264
|
begin
|
269
|
-
|
265
|
+
a_node.request(:method => :put, :uri => "document/#{@database}/#{rid}", \
|
266
|
+
:content_type => 'application/json', :data => doc.to_json)
|
270
267
|
rescue
|
271
268
|
raise DataError
|
272
269
|
end
|
@@ -280,8 +277,7 @@ module Orientdb4r
|
|
280
277
|
rid = rid[1..-1] if rid.start_with? '#'
|
281
278
|
|
282
279
|
begin
|
283
|
-
response =
|
284
|
-
puts "DELETE '#{response}'"
|
280
|
+
response = a_node.request(:method => :delete, :uri => "document/#{@database}/#{rid}")
|
285
281
|
rescue
|
286
282
|
raise DataError
|
287
283
|
end
|
@@ -292,17 +288,39 @@ module Orientdb4r
|
|
292
288
|
|
293
289
|
private
|
294
290
|
|
295
|
-
|
296
|
-
#
|
297
|
-
def
|
298
|
-
|
291
|
+
####
|
292
|
+
# Processes a HTTP response.
|
293
|
+
def process_response(response)
|
294
|
+
raise ArgumentError, 'response is null' if response.nil?
|
295
|
+
|
296
|
+
# return code
|
297
|
+
if 200 != response.code and 2 == (response.code / 100)
|
298
|
+
Orientdb4r::logger.warn "expected return code 200, but received #{response.code}"
|
299
|
+
elsif 401 == response.code
|
300
|
+
raise UnauthorizedError, '401 Unauthorized'
|
301
|
+
elsif 200 != response.code
|
302
|
+
msg = response.body.gsub("\n", ' ')
|
303
|
+
msg = "#{msg[0..100]} ..." if msg.size > 100
|
304
|
+
raise OrientdbError, "unexpected return code, code=#{response.code}, body=#{msg}"
|
305
|
+
end
|
306
|
+
|
307
|
+
content_type = response.headers[:content_type]
|
308
|
+
content_type ||= 'text/plain'
|
309
|
+
|
310
|
+
rslt = case
|
311
|
+
when content_type.start_with?('text/plain')
|
312
|
+
response.body
|
313
|
+
when content_type.start_with?('application/json')
|
314
|
+
::JSON.parse(response.body)
|
315
|
+
else
|
316
|
+
raise OrientdbError, "unsuported content type: #{content_type}"
|
317
|
+
end
|
318
|
+
|
319
|
+
rslt
|
299
320
|
end
|
300
321
|
|
301
|
-
|
302
|
-
|
303
|
-
# * strict
|
304
|
-
# * warning
|
305
|
-
def process_response(response, options={})
|
322
|
+
# @deprecated
|
323
|
+
def process_restclient_response(response, options={})
|
306
324
|
raise ArgumentError, 'response is null' if response.nil?
|
307
325
|
|
308
326
|
# raise problem if other code than 200
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Orientdb4r
|
2
|
+
|
3
|
+
###
|
4
|
+
# This class represents a single sever/node in the Distributed Multi-Master Architecture
|
5
|
+
# accessible view REST API.
|
6
|
+
class RestNode < Node
|
7
|
+
|
8
|
+
# Name of cookie that represents a session.
|
9
|
+
SESSION_COOKIE_NAME = 'OSESSIONID'
|
10
|
+
|
11
|
+
attr_reader :ssl
|
12
|
+
|
13
|
+
###
|
14
|
+
# Constructor.
|
15
|
+
def initialize(host, port, ssl)
|
16
|
+
super(host, port)
|
17
|
+
raise ArgumentError, 'ssl flag cannot be blank' if blank?(ssl)
|
18
|
+
@ssl = ssl
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
def url #:nodoc:
|
23
|
+
"http#{'s' if ssl}://#{host}:#{port}"
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
# ----------------------------------------------------------- RestNode Stuff
|
28
|
+
|
29
|
+
###
|
30
|
+
# Initializes a long life connection with credentials and session ID
|
31
|
+
# after successful connect.
|
32
|
+
def post_connect(user, password, http_response)
|
33
|
+
raise NotImplementedError, 'this should be overridden by subclass'
|
34
|
+
|
35
|
+
# excon
|
36
|
+
# cookies = CGI::Cookie::parse(http_response.headers['Set-Cookie'])
|
37
|
+
# @session_id = cookies[SESSION_COOKIE_NAME][0]
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
###
|
42
|
+
# Sends an one-off request to the remote server.
|
43
|
+
def oo_request(options)
|
44
|
+
raise NotImplementedError, 'this should be overridden by subclass'
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
###
|
49
|
+
# Sends a request to the remote server
|
50
|
+
# based on a connection object which is reusable across multiple requests.
|
51
|
+
def request(options)
|
52
|
+
raise NotImplementedError, 'this should be overridden by subclass'
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
###
|
57
|
+
# Gets value of the Basic Auth header.
|
58
|
+
def basic_auth_header(user, password)
|
59
|
+
b64 = Base64.encode64("#{user}:#{password}").delete("\r\n")
|
60
|
+
"Basic #{b64}"
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
# excon ###
|
65
|
+
# # Get request headers prepared with session ID and Basic Auth.
|
66
|
+
# def headers
|
67
|
+
# {'Authorization' => @basic_auth, 'Cookie' => "#{SESSION_COOKIE_NAME}=#{session_id}"}
|
68
|
+
# end
|
69
|
+
|
70
|
+
# excon ###
|
71
|
+
# # Gets a connection object which is reusable across multiple requests.
|
72
|
+
# def connection
|
73
|
+
# @connection = Excon.new(url) if @connection.nil?
|
74
|
+
# @connection
|
75
|
+
# end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Orientdb4r
|
2
|
+
|
3
|
+
###
|
4
|
+
# This class represents a single sever/node in the Distributed Multi-Master Architecture
|
5
|
+
# accessible view REST API and 'rest-client' library on the client side.
|
6
|
+
class RestClientNode < RestNode
|
7
|
+
|
8
|
+
attr_reader :session_id
|
9
|
+
|
10
|
+
|
11
|
+
def oo_request(options) #:nodoc:
|
12
|
+
begin
|
13
|
+
options[:url] = "#{url}/#{options[:uri]}"
|
14
|
+
options.delete :uri
|
15
|
+
response = ::RestClient::Request.new(options).execute
|
16
|
+
rescue ::RestClient::Unauthorized
|
17
|
+
# fake the response object
|
18
|
+
response = "401 Unauthorized"
|
19
|
+
def response.code
|
20
|
+
401
|
21
|
+
end
|
22
|
+
end
|
23
|
+
response
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
def request(options) #:nodoc:
|
28
|
+
raise OrientdbError, 'long life connection not initialized' if @resource.nil?
|
29
|
+
|
30
|
+
data = options[:data]
|
31
|
+
options.delete :data
|
32
|
+
data = '' if data.nil? and :post == options[:method] # POST has to have data
|
33
|
+
begin
|
34
|
+
# e.g. @resource['disconnect'].get
|
35
|
+
if data.nil?
|
36
|
+
response = @resource[options[:uri]].send options[:method].to_sym
|
37
|
+
else
|
38
|
+
response = @resource[options[:uri]].send options[:method].to_sym, data
|
39
|
+
end
|
40
|
+
rescue ::RestClient::Unauthorized
|
41
|
+
# fake the response object
|
42
|
+
response = "401 Unauthorized"
|
43
|
+
def response.code
|
44
|
+
401
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
response
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
def post_connect(user, password, http_response) #:nodoc:
|
53
|
+
@basic_auth = basic_auth_header(user, password)
|
54
|
+
@session_id = http_response.cookies[SESSION_COOKIE_NAME]
|
55
|
+
|
56
|
+
@resource = ::RestClient::Resource.new(url, \
|
57
|
+
:user => user, :password => password, \
|
58
|
+
:cookies => { SESSION_COOKIE_NAME => session_id})
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
def cleanup #:nodoc:
|
63
|
+
@session_id = nil
|
64
|
+
@basic_auth = nil
|
65
|
+
@resource = nil
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
data/lib/orientdb4r/utils.rb
CHANGED
data/lib/orientdb4r/version.rb
CHANGED
@@ -2,6 +2,7 @@ module Orientdb4r
|
|
2
2
|
|
3
3
|
# Version history.
|
4
4
|
VERSION_HISTORY = [
|
5
|
+
['0.2.7', '2012-07-07', "Added method Client#class_exists?"],
|
5
6
|
['0.2.6', '2012-07-03', "BF #8, BF #6"],
|
6
7
|
['0.2.5', '2012-07-01', "Added 'get_database' into database CRUD"],
|
7
8
|
# v-- https://groups.google.com/forum/?fromgroups#!topic/orient-database/5MAMCvFavTc
|
data/lib/orientdb4r.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'json'
|
2
|
-
require '
|
2
|
+
require 'base64'
|
3
3
|
require 'logger'
|
4
|
+
require 'rest_client'
|
4
5
|
require 'orientdb4r/version'
|
5
6
|
|
6
7
|
|
@@ -14,6 +15,9 @@ module Orientdb4r
|
|
14
15
|
autoload :HashExtension, 'orientdb4r/rest/model'
|
15
16
|
autoload :OClass, 'orientdb4r/rest/model'
|
16
17
|
autoload :ChainedError, 'orientdb4r/chained_error'
|
18
|
+
autoload :Node, 'orientdb4r/node'
|
19
|
+
autoload :RestNode, 'orientdb4r/rest/node'
|
20
|
+
autoload :RestClientNode, 'orientdb4r/rest/restclient_node'
|
17
21
|
|
18
22
|
|
19
23
|
class << self
|
@@ -21,14 +25,16 @@ module Orientdb4r
|
|
21
25
|
###
|
22
26
|
# Gets a new database client or an existing for the current thread.
|
23
27
|
# === options
|
24
|
-
# * :
|
28
|
+
# * :instance => :new
|
25
29
|
def client options={}
|
26
30
|
if :new == options[:instance]
|
27
31
|
options.delete :instance
|
28
32
|
return RestClient.new options
|
29
33
|
end
|
30
34
|
|
31
|
-
Thread.
|
35
|
+
Thread.exclusive {
|
36
|
+
Thread.current[:orientdb_client] ||= RestClient.new options
|
37
|
+
}
|
32
38
|
end
|
33
39
|
|
34
40
|
###
|
@@ -48,6 +54,10 @@ module Orientdb4r
|
|
48
54
|
include ChainedError
|
49
55
|
end
|
50
56
|
|
57
|
+
###
|
58
|
+
# Error indicating that access to the resource requires user authentication.
|
59
|
+
class UnauthorizedError < OrientdbError; end
|
60
|
+
|
51
61
|
###
|
52
62
|
# Error indicating problems with communicating with the database.
|
53
63
|
class ConnectionError < OrientdbError; end
|
@@ -72,5 +82,6 @@ Orientdb4r::logger.info \
|
|
72
82
|
"Orientdb4r #{Orientdb4r::VERSION}, running on Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
|
73
83
|
|
74
84
|
|
85
|
+
#Orientdb4r::logger.level = Logger::DEBUG
|
75
86
|
#client = Orientdb4r.client
|
76
87
|
#client.connect :database => 'temp', :user => 'admin', :password => 'admin'
|
data/test/readme_sample.rb
CHANGED
@@ -6,10 +6,12 @@
|
|
6
6
|
|
7
7
|
client.connect :database => 'temp', :user => 'admin', :password => 'admin'
|
8
8
|
|
9
|
-
client.
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
unless client.class_exists? CLASS
|
10
|
+
client.create_class(CLASS) do |c|
|
11
|
+
c.property 'prop1', :integer, :notnull => true, :min => 1, :max => 99
|
12
|
+
c.property 'prop2', :string, :mandatory => true
|
13
|
+
c.link 'users', :linkset, 'OUser' # by default: :mandatory => false, :notnull => false
|
14
|
+
end
|
13
15
|
end
|
14
16
|
|
15
17
|
admin = client.query("SELECT FROM OUser WHERE name = 'admin'")[0]
|
data/test/test_database.rb
CHANGED
@@ -23,13 +23,13 @@ class TestDatabase < Test::Unit::TestCase
|
|
23
23
|
assert rslt.size > 0
|
24
24
|
assert rslt.include? 'classes'
|
25
25
|
|
26
|
-
assert_equal 'localhost', @client.host
|
27
|
-
assert_equal 2480, @client.port
|
28
|
-
assert_equal false, @client.ssl
|
26
|
+
#assert_equal 'localhost', @client.host # TODO moved to Node; mock?
|
27
|
+
#assert_equal 2480, @client.port
|
28
|
+
#assert_equal false, @client.ssl
|
29
29
|
assert_equal 'admin', @client.user
|
30
30
|
assert_equal 'admin', @client.password
|
31
31
|
assert_equal 'temp', @client.database
|
32
|
-
assert_not_nil @client.session_id
|
32
|
+
#assert_not_nil @client.session_id
|
33
33
|
assert_not_nil @client.server_version
|
34
34
|
|
35
35
|
# connection refused
|
@@ -39,11 +39,11 @@ class TestDatabase < Test::Unit::TestCase
|
|
39
39
|
end
|
40
40
|
|
41
41
|
# bad DB name
|
42
|
-
assert_raise Orientdb4r::
|
42
|
+
assert_raise Orientdb4r::UnauthorizedError do
|
43
43
|
@client.connect :database => 'unknown_db', :user => 'admin', :password => 'admin'
|
44
44
|
end
|
45
45
|
# bad credentials
|
46
|
-
assert_raise Orientdb4r::
|
46
|
+
assert_raise Orientdb4r::UnauthorizedError do
|
47
47
|
@client.connect :database => 'temp', :user => 'admin1', :password => 'admin'
|
48
48
|
end
|
49
49
|
end
|
@@ -59,13 +59,13 @@ class TestDatabase < Test::Unit::TestCase
|
|
59
59
|
# unable to query after disconnect
|
60
60
|
assert_raise Orientdb4r::ConnectionError do @client.query 'SELECT FROM OUser'; end
|
61
61
|
|
62
|
-
assert_equal 'localhost', @client.host
|
63
|
-
assert_equal 2480, @client.port
|
64
|
-
assert_equal false, @client.ssl
|
62
|
+
#assert_equal 'localhost', @client.host # TODO moved to Node; mock?
|
63
|
+
#assert_equal 2480, @client.port
|
64
|
+
#assert_equal false, @client.ssl
|
65
65
|
assert_nil @client.user
|
66
66
|
assert_nil @client.password
|
67
67
|
assert_nil @client.database
|
68
|
-
assert_nil @client.session_id
|
68
|
+
#assert_nil @client.session_id
|
69
69
|
assert_nil @client.server_version
|
70
70
|
end
|
71
71
|
|
@@ -75,7 +75,9 @@ class TestDatabase < Test::Unit::TestCase
|
|
75
75
|
# Temporary disabled because of unknown way how to drop a new created datatabse.
|
76
76
|
def xtest_create_database
|
77
77
|
@client.create_database :database => 'UniT', :user => 'root', :password => 'root'
|
78
|
-
assert_nothing_thrown do
|
78
|
+
assert_nothing_thrown do
|
79
|
+
@client.get_database :database => 'UniT', :user => 'admin', :password => 'admin'
|
80
|
+
end
|
79
81
|
# creating an existing DB
|
80
82
|
assert_raise Orientdb4r::OrientdbError do
|
81
83
|
@client.create_database :database => 'UniT', :user => 'root', :password => 'root'
|
@@ -110,7 +112,7 @@ class TestDatabase < Test::Unit::TestCase
|
|
110
112
|
assert @client.database_exists?(:database => 'temp') # use credentials of logged in user
|
111
113
|
|
112
114
|
# bad databases
|
113
|
-
assert_raise Orientdb4r::
|
115
|
+
assert_raise Orientdb4r::UnauthorizedError do @client.get_database :database => 'UnknownDB'; end
|
114
116
|
assert_raise Orientdb4r::NotFoundError do @client.get_database :database => 'temp/admin'; end
|
115
117
|
assert !@client.database_exists?(:database => 'UnknownDB')
|
116
118
|
assert !@client.database_exists?(:database => 'temp/admin')
|
data/test/test_ddo.rb
CHANGED
@@ -54,13 +54,18 @@ class TestDdo < Test::Unit::TestCase
|
|
54
54
|
assert_nil prop.min
|
55
55
|
assert_nil prop.min
|
56
56
|
assert prop.kind_of? Orientdb4r::Property
|
57
|
+
|
58
|
+
assert @client.class_exists?('OUser')
|
59
|
+
assert !@client.class_exists?('UnknownClass')
|
57
60
|
end
|
58
61
|
|
59
62
|
|
60
63
|
###
|
61
64
|
# CREATE CLASS
|
62
65
|
def test_create_class
|
66
|
+
assert !@client.class_exists?(CLASS)
|
63
67
|
assert_nothing_thrown do @client.create_class(CLASS); end
|
68
|
+
assert @client.class_exists?(CLASS)
|
64
69
|
assert_nothing_thrown do @client.get_class(CLASS); end # raises an Error if no class found
|
65
70
|
# already exist
|
66
71
|
assert_raise Orientdb4r::OrientdbError do @client.create_class(CLASS); end
|
data/test/test_dmo.rb
CHANGED
@@ -51,6 +51,17 @@ class TestDmo < Test::Unit::TestCase
|
|
51
51
|
end
|
52
52
|
assert_equal urids.size, @client.query("SELECT FROM #{CLASS} WHERE prop2 = 'linkset'")[0]['friends'].size
|
53
53
|
|
54
|
+
# table doesn't exist
|
55
|
+
assert_raise Orientdb4r::OrientdbError do
|
56
|
+
@client.command "INSERT INTO #{CLASS}x (prop1, prop2, friends) VALUES (1, 'linkset', [#{urids.join(',')}])"
|
57
|
+
end
|
58
|
+
# bad syntax
|
59
|
+
assert_raise Orientdb4r::OrientdbError do
|
60
|
+
@client.command 'xxx'
|
61
|
+
end
|
62
|
+
|
63
|
+
# used for SELECT
|
64
|
+
assert_equal @client.query('SELECT FROM OUser'), @client.command('SELECT FROM OUser')['result']
|
54
65
|
end
|
55
66
|
|
56
67
|
|
@@ -81,6 +92,19 @@ class TestDmo < Test::Unit::TestCase
|
|
81
92
|
assert_equal 1, gr.select { |e| e if e['@class'] == CLASS }.size
|
82
93
|
assert_equal 1, gr.select { |e| e if e['@class'] == 'OUser' }.size
|
83
94
|
assert_equal 1, gr.select { |e| e if e['@class'] == 'ORole' }.size
|
95
|
+
|
96
|
+
# table doesn't exist
|
97
|
+
assert_raise Orientdb4r::NotFoundError do
|
98
|
+
@client.query 'SELECT FROM OUserX'
|
99
|
+
end
|
100
|
+
# bad syntax
|
101
|
+
assert_raise Orientdb4r::NotFoundError do
|
102
|
+
@client.query 'xxx'
|
103
|
+
end
|
104
|
+
# used for INSERT
|
105
|
+
assert_raise Orientdb4r::NotFoundError do
|
106
|
+
@client.query "INSERT INTO #{CLASS} (prop1, prop2, friends) VALUES (0, 'string0', [])"
|
107
|
+
end
|
84
108
|
end
|
85
109
|
|
86
110
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: orientdb4r
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.7
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-07-
|
12
|
+
date: 2012-07-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rest-client
|
@@ -40,11 +40,15 @@ files:
|
|
40
40
|
- LICENSE
|
41
41
|
- README.rdoc
|
42
42
|
- Rakefile
|
43
|
+
- changelog.txt
|
43
44
|
- lib/orientdb4r.rb
|
44
45
|
- lib/orientdb4r/chained_error.rb
|
45
46
|
- lib/orientdb4r/client.rb
|
47
|
+
- lib/orientdb4r/node.rb
|
46
48
|
- lib/orientdb4r/rest/client.rb
|
47
49
|
- lib/orientdb4r/rest/model.rb
|
50
|
+
- lib/orientdb4r/rest/node.rb
|
51
|
+
- lib/orientdb4r/rest/restclient_node.rb
|
48
52
|
- lib/orientdb4r/utils.rb
|
49
53
|
- lib/orientdb4r/version.rb
|
50
54
|
- orientdb4r.gemspec
|
@@ -76,7 +80,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
76
80
|
version: 1.3.1
|
77
81
|
requirements: []
|
78
82
|
rubyforge_project:
|
79
|
-
rubygems_version: 1.8.
|
83
|
+
rubygems_version: 1.8.19
|
80
84
|
signing_key:
|
81
85
|
specification_version: 3
|
82
86
|
summary: Ruby binding for Orient DB.
|