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 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.create_class(CLASS) do |c|
22
- c.property 'prop1', :integer, :notnull => true, :min => 1, :max => 99
23
- c.property 'prop2', :string, :mandatory => true
24
- c.link 'users', :linkset, 'OUser' # by default: :mandatory => false, :notnull => false
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
@@ -0,0 +1,8 @@
1
+ 0.3.0 07/x/12
2
+ ===============
3
+ - 'rest-client' replaced by 'excon' for HTTP communication with Keep-Alive
4
+ - introduced support for distributed server
5
+
6
+ 0.3.0 07/07/12
7
+ - changed design to support distributed server
8
+ - added method Client#class_exists?
@@ -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 NotFoundError
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 = @resource["connect/#{@database}"].get
150
- connect_info = process_response(response, :mode => :strict)
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 :host, :port, :ssl, :user, :password, :database, :session_id
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
- @host = options[:host]
22
- @port = options[:port]
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 = ::RestClient::Request.new(:method => :get, :url => "#{url}/connect/#{@database}", \
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
- @resource = nil
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
- response = @resource['disconnect'].get
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
- @resource = nil
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
- response = resource['server'].get
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
- response = resource["database/#{options[:database]}/#{options[:type]}"].post ''
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
- response = resource["database/#{options[:database]}"].get
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
- response = @resource["query/#{@database}/sql/#{CGI::escape(sql)}#{limit}"].get
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
- #puts "REQ command/#{@database}/sql/#{CGI::escape(sql)}"
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 = @resource["class/#{@database}/#{name}"].get
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, :mode => :strict)
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
- response = @resource["connect/#{@database}"].get
209
- connect_info = process_response(response, :mode => :strict)
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 = @resource["document/#{@database}"].post doc.to_json, :content_type => 'application/json'
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 = @resource["document/#{@database}/#{rid}"].get
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
- @resource["document/#{@database}/#{rid}"].put doc.to_json, :content_type => 'application/json'
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 = @resource["document/#{@database}/#{rid}"].delete
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
- # Gets URL of the REST interface.
297
- def url
298
- "http#{'s' if ssl}://#{host}:#{port}"
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
- # ==== options
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
@@ -37,7 +37,7 @@ module Orientdb4r
37
37
  ###
38
38
  # Checks if a given string is either 'nil' or empty string.
39
39
  def blank?(str)
40
- str.nil? or str.strip.empty?
40
+ str.nil? or (str.is_a? String and str.strip.empty?)
41
41
  end
42
42
 
43
43
  ###
@@ -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 'rest_client'
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
- # * :force => true
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.current[:orientdb_client] ||= RestClient.new options
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'
@@ -6,10 +6,12 @@
6
6
 
7
7
  client.connect :database => 'temp', :user => 'admin', :password => 'admin'
8
8
 
9
- client.create_class(CLASS) do |c|
10
- c.property 'prop1', :integer, :notnull => true, :min => 1, :max => 99
11
- c.property 'prop2', :string, :mandatory => true
12
- c.link 'users', :linkset, 'OUser' # by default: :mandatory => false, :notnull => false
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]
@@ -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::ConnectionError do
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::ConnectionError do
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 @client.get_database 'UniT'; end
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::NotFoundError do @client.get_database :database => 'UnknownDB'; end
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.6
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-03 00:00:00.000000000 Z
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.23
83
+ rubygems_version: 1.8.19
80
84
  signing_key:
81
85
  specification_version: 3
82
86
  summary: Ruby binding for Orient DB.