orientdb4r 0.2.6 → 0.2.7
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|