orientdb_client 0.0.1 → 0.0.2
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/.travis.yml +4 -0
- data/README.md +5 -1
- data/lib/orientdb_client.rb +26 -14
- data/lib/orientdb_client/errors.rb +4 -0
- data/lib/orientdb_client/version.rb +1 -1
- data/spec/orientdb_client_spec.rb +105 -50
- data/spec/spec_helper.rb +13 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3b21ad9036b5e5873f1f51dc9508dd386bddd7b0
|
4
|
+
data.tar.gz: 503d006feb63fd5d7ff3ab7994af1e5d86839fed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9eb18afed7dd6191124107a6919df244536c4468e11a599690134f43f150470c20a8d078f3aea3db7131b8c165608cda500fd1a8104182d5385ba6b962480e98
|
7
|
+
data.tar.gz: 252f573b2958cb4ffcbae1b7a71f0cb115d8e5f78e5748c563f5b9d1a41700c30f2629a7f1da8d51e7849b99c0df4bffd397cd37c453b53c15a9d2ab7737e509
|
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# OrientdbClient
|
2
2
|
|
3
|
+
[](https://travis-ci.org/lukeasrodgers/orientdb_client)
|
4
|
+
|
3
5
|
Ruby client for Orientdb. Probably not quite ready for production yet.
|
4
6
|
Inspired by https://github.com/veny/orientdb4r
|
5
7
|
|
@@ -14,6 +16,8 @@ Tested on:
|
|
14
16
|
* 2.0.4
|
15
17
|
* 2.0.2
|
16
18
|
|
19
|
+
CI tests with Travis currently only run non-integration tests (i.e. they don't actually hit an Orientdb server).
|
20
|
+
|
17
21
|
## Installation
|
18
22
|
|
19
23
|
Add this line to your application's Gemfile:
|
@@ -51,7 +55,7 @@ Orientdb::logger = MyLogger.new
|
|
51
55
|
# use a different HttpAdapter
|
52
56
|
require 'orientdb_client'
|
53
57
|
require 'orientdb_client/http_adapters/curb_adapter'
|
54
|
-
client = OrientdbClient.
|
58
|
+
client = OrientdbClient.client(adapter: 'CurbAdapter')
|
55
59
|
```
|
56
60
|
|
57
61
|
## HTTP Adapters
|
data/lib/orientdb_client.rb
CHANGED
@@ -313,21 +313,27 @@ module OrientdbClient
|
|
313
313
|
raise ClientError.new("#{odb_error_class}: #{odb_error_message}", code, body)
|
314
314
|
when /OCommandExecutionException/
|
315
315
|
raise CommandExecutionException.new("#{odb_error_class}: #{odb_error_message}", code, body)
|
316
|
-
when /OSchemaException/
|
316
|
+
when /OSchemaException|OIndexException/
|
317
317
|
raise ClientError.new("#{odb_error_class}: #{odb_error_message}", code, body)
|
318
318
|
when /OConcurrentModification/
|
319
|
-
raise MVCCError.new("#{odb_error_class}: #{odb_error_message}",
|
319
|
+
raise MVCCError.new("#{odb_error_class}: #{odb_error_message}", code, body)
|
320
320
|
when /IllegalStateException/
|
321
|
-
raise ServerError.new("#{odb_error_class}: #{odb_error_message}",
|
321
|
+
raise ServerError.new("#{odb_error_class}: #{odb_error_message}", code, body)
|
322
322
|
when /ORecordDuplicate/
|
323
|
-
raise DuplicateRecordError.new("#{odb_error_class}: #{odb_error_message}",
|
323
|
+
raise DuplicateRecordError.new("#{odb_error_class}: #{odb_error_message}", code, body)
|
324
|
+
when /ODistributedException/
|
325
|
+
if odb_error_message.match(/ORecordDuplicate/)
|
326
|
+
raise DistributedDuplicateRecordError.new("#{odb_error_class}: #{odb_error_message}", code, body)
|
327
|
+
else
|
328
|
+
raise DistributedException.new("#{odb_error_class}: #{odb_error_message}", code, body)
|
329
|
+
end
|
324
330
|
when /OTransactionException/
|
325
331
|
if odb_error_message.match(/ORecordDuplicate/)
|
326
|
-
raise DistributedDuplicateRecordError.new("#{odb_error_class}: #{odb_error_message}",
|
332
|
+
raise DistributedDuplicateRecordError.new("#{odb_error_class}: #{odb_error_message}", code, body)
|
327
333
|
elsif odb_error_message.match(/distributed/)
|
328
|
-
raise DistributedTransactionException.new("#{odb_error_class}: #{odb_error_message}",
|
334
|
+
raise DistributedTransactionException.new("#{odb_error_class}: #{odb_error_message}", code, body)
|
329
335
|
else
|
330
|
-
raise TransactionException.new("#{odb_error_class}: #{odb_error_message}",
|
336
|
+
raise TransactionException.new("#{odb_error_class}: #{odb_error_message}", code, body)
|
331
337
|
end
|
332
338
|
when /ODatabaseException/
|
333
339
|
if odb_error_message.match(/already exists/)
|
@@ -335,7 +341,11 @@ module OrientdbClient
|
|
335
341
|
else
|
336
342
|
klass = ServerError
|
337
343
|
end
|
338
|
-
raise klass.new("#{odb_error_class}: #{odb_error_message}",
|
344
|
+
raise klass.new("#{odb_error_class}: #{odb_error_message}", code, body)
|
345
|
+
when /ODistributedRecordLockedException/
|
346
|
+
raise DistributedRecordLockedException.new("#{odb_error_class}: #{odb_error_message}", code, body)
|
347
|
+
when /OSerializationException/
|
348
|
+
raise SerializationException.new("#{odb_error_class}: #{odb_error_message}", code, body)
|
339
349
|
end
|
340
350
|
end
|
341
351
|
|
@@ -343,15 +353,17 @@ module OrientdbClient
|
|
343
353
|
body = response.body
|
344
354
|
json = Oj.load(body)
|
345
355
|
# odb > 2.1 (?) errors are in JSON format
|
346
|
-
matches = json['errors'].first['content'].match(/\A([^:]+)
|
356
|
+
matches = json['errors'].first['content'].match(/\A([^:]+):?\s?(.*)/m)
|
347
357
|
[matches[1], matches[2]]
|
348
358
|
rescue => e
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
raise
|
359
|
+
code = response.response_code
|
360
|
+
body = response.body
|
361
|
+
if (body.match(/Database.*already exists/))
|
362
|
+
raise ConflictError.new(e.message, code, body)
|
363
|
+
elsif (body.match(/NegativeArraySizeException/))
|
364
|
+
raise NegativeArraySizeException.new(e.message, code, body)
|
353
365
|
else
|
354
|
-
raise OrientdbError.new("Could not parse Orientdb server error
|
366
|
+
raise OrientdbError.new("Could not parse Orientdb server error: #{code}, #{body}")
|
355
367
|
end
|
356
368
|
end
|
357
369
|
|
@@ -17,12 +17,16 @@ module OrientdbClient
|
|
17
17
|
class TransactionException < ServerError; end
|
18
18
|
class DistributedTransactionException < TransactionException; end
|
19
19
|
class MVCCError < ServerError; end
|
20
|
+
class DistributedRecordLockedException < TransactionException; end
|
21
|
+
# Generic DistributedException, generally a more specific error is preferable.
|
22
|
+
class DistributedException < ServerError; end
|
20
23
|
|
21
24
|
# ClientError: you did something wrong
|
22
25
|
class ClientError < OrientdbError; end
|
23
26
|
class UnauthorizedError < ClientError; end
|
24
27
|
class IllegalArgumentException < ClientError; end
|
25
28
|
class CommandExecutionException < ClientError; end
|
29
|
+
class SerializationException < ClientError; end
|
26
30
|
|
27
31
|
# ConflictError: you tried to create something that already exists
|
28
32
|
class ConflictError < ClientError; end
|
@@ -13,16 +13,16 @@ RSpec.describe OrientdbClient do
|
|
13
13
|
let(:db) { OrientdbClient::Test::DatabaseName }
|
14
14
|
let(:temp_db_name) { "#{OrientdbClient::Test::DatabaseName}_temp" }
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
client.
|
19
|
-
|
20
|
-
|
21
|
-
client.
|
16
|
+
describe 'integration specs', type: :integration do
|
17
|
+
after(:each) do
|
18
|
+
if client.connected?
|
19
|
+
client.disconnect
|
20
|
+
end
|
21
|
+
if client.database_exists?(temp_db_name)
|
22
|
+
client.delete_database(temp_db_name, username: valid_username, password: valid_password)
|
23
|
+
end
|
22
24
|
end
|
23
|
-
end
|
24
25
|
|
25
|
-
describe 'integration specs', type: :integration do
|
26
26
|
describe '#connect' do
|
27
27
|
subject { client.connect(username: username, password: password, db: db) }
|
28
28
|
|
@@ -91,7 +91,7 @@ RSpec.describe OrientdbClient do
|
|
91
91
|
before do
|
92
92
|
client.connect(username: username, password: password, db: db)
|
93
93
|
end
|
94
|
-
|
94
|
+
|
95
95
|
context 'with valid database parameters' do
|
96
96
|
it 'creates a database' do
|
97
97
|
client.create_database(temp_db_name, 'plocal', 'document')
|
@@ -128,55 +128,57 @@ RSpec.describe OrientdbClient do
|
|
128
128
|
end
|
129
129
|
|
130
130
|
describe '#delete_database' do
|
131
|
-
|
132
|
-
|
133
|
-
client.
|
134
|
-
|
135
|
-
end
|
136
|
-
|
137
|
-
context 'without existing connection' do
|
138
|
-
context 'with valid authentication options' do
|
139
|
-
it 'deletes the database' do
|
140
|
-
client.delete_database(temp_db_name, username: username, password: password)
|
141
|
-
expect(client.database_exists?(temp_db_name)).to be false
|
131
|
+
if !$distributed_mode
|
132
|
+
before(:each) do
|
133
|
+
if !client.database_exists?(temp_db_name)
|
134
|
+
client.create_database(temp_db_name, 'plocal', 'document', username: valid_username, password: valid_password)
|
142
135
|
end
|
143
136
|
end
|
144
137
|
|
145
|
-
context '
|
146
|
-
|
147
|
-
|
148
|
-
client.delete_database(temp_db_name, username:
|
149
|
-
|
138
|
+
context 'without existing connection' do
|
139
|
+
context 'with valid authentication options' do
|
140
|
+
it 'deletes the database' do
|
141
|
+
client.delete_database(temp_db_name, username: username, password: password)
|
142
|
+
expect(client.database_exists?(temp_db_name)).to be false
|
143
|
+
end
|
150
144
|
end
|
151
145
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
146
|
+
context 'with invalid authentication options' do
|
147
|
+
it 'raises UnauthorizedError' do
|
148
|
+
expect do
|
149
|
+
client.delete_database(temp_db_name, username: 'foo', password: 'bar')
|
150
|
+
end.to raise_exception(OrientdbClient::UnauthorizedError)
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'does not delete the database' do
|
154
|
+
begin
|
155
|
+
client.delete_database(temp_db_name, username: 'foo', password: 'bar')
|
156
|
+
rescue
|
157
|
+
ensure
|
158
|
+
expect(client.database_exists?(temp_db_name)).to be true
|
159
|
+
end
|
158
160
|
end
|
159
161
|
end
|
160
162
|
end
|
161
|
-
end
|
162
163
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
end
|
167
|
-
|
168
|
-
context 'with valid database parameters' do
|
169
|
-
it 'deletes the database' do
|
170
|
-
client.delete_database(temp_db_name)
|
171
|
-
expect(client.database_exists?(temp_db_name)).to be false
|
164
|
+
context 'with existing connection' do
|
165
|
+
before do
|
166
|
+
client.connect(username: username, password: password, db: db)
|
172
167
|
end
|
173
|
-
end
|
174
168
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
client.
|
179
|
-
end
|
169
|
+
context 'with valid database parameters' do
|
170
|
+
it 'deletes the database' do
|
171
|
+
client.delete_database(temp_db_name)
|
172
|
+
expect(client.database_exists?(temp_db_name)).to be false
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
context 'with no matching database' do
|
177
|
+
it 'raises a ClientError' do
|
178
|
+
expect do
|
179
|
+
client.delete_database(temp_db_name + 'baz')
|
180
|
+
end.to raise_exception(OrientdbClient::ClientError, /OConfigurationException/)
|
181
|
+
end
|
180
182
|
end
|
181
183
|
end
|
182
184
|
end
|
@@ -228,9 +230,25 @@ RSpec.describe OrientdbClient do
|
|
228
230
|
end
|
229
231
|
end
|
230
232
|
|
233
|
+
context 'with invalid JSON' do
|
234
|
+
it 'raises SerializationException' do
|
235
|
+
expect do
|
236
|
+
client.command('insert into OUser CONTENT ' + Oj.dump({a:1}))
|
237
|
+
end.to raise_exception(OrientdbClient::SerializationException)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
context 'creating index for property that does not exist' do
|
242
|
+
it 'raises a ClientError' do
|
243
|
+
expect do
|
244
|
+
client.command('create index UserIdx on OUser (user_id) unique')
|
245
|
+
end.to raise_exception(OrientdbClient::ClientError)
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
231
249
|
context 'with invalid query' do
|
232
250
|
it 'returns result' do
|
233
|
-
expect { client.
|
251
|
+
expect { client.command('select * crumb') }.to raise_exception(OrientdbClient::ClientError, /OCommandSQLParsingException/)
|
234
252
|
end
|
235
253
|
end
|
236
254
|
end
|
@@ -358,6 +376,7 @@ RSpec.describe OrientdbClient do
|
|
358
376
|
end
|
359
377
|
end
|
360
378
|
|
379
|
+
# This spec sometimes fails on Orientdb 2.1.X
|
361
380
|
context 'when class does not exist' do
|
362
381
|
it 'raises exception' do
|
363
382
|
expect do
|
@@ -635,6 +654,32 @@ RSpec.describe OrientdbClient do
|
|
635
654
|
end
|
636
655
|
end
|
637
656
|
|
657
|
+
describe 'duplicate record creation violating index constraint' do
|
658
|
+
before do
|
659
|
+
client.connect(username: username, password: password, db: db)
|
660
|
+
if client.has_class?('Person')
|
661
|
+
client.command('delete vertex Person')
|
662
|
+
client.drop_class('Person')
|
663
|
+
end
|
664
|
+
end
|
665
|
+
after do
|
666
|
+
client.command('delete vertex Person')
|
667
|
+
client.drop_class('Person')
|
668
|
+
end
|
669
|
+
|
670
|
+
it 'raises DuplicateRecordError' do
|
671
|
+
error_klass = $distributed_mode ? OrientdbClient::DistributedDuplicateRecordError : OrientdbClient:: DuplicateRecordError
|
672
|
+
client.create_class('Person', extends: 'V') do |c|
|
673
|
+
c.property('user_id', 'integer')
|
674
|
+
end
|
675
|
+
client.command('create index PersonIdx on Person (user_id) unique')
|
676
|
+
client.command('insert into Person CONTENT ' + Oj.dump({'user_id' => 1}))
|
677
|
+
expect do
|
678
|
+
client.command('insert into Person CONTENT ' + Oj.dump({'user_id' => 1}))
|
679
|
+
end.to raise_exception(error_klass)
|
680
|
+
end
|
681
|
+
end
|
682
|
+
|
638
683
|
end
|
639
684
|
|
640
685
|
# These specs will sometimes fail, not too much we can do about that, depends
|
@@ -674,7 +719,8 @@ RSpec.describe OrientdbClient do
|
|
674
719
|
jim_rid = jim['result'][0]['@rid']
|
675
720
|
bob_rid = bob['result'][0]['@rid']
|
676
721
|
thrs = []
|
677
|
-
|
722
|
+
err = nil
|
723
|
+
begin
|
678
724
|
thrs << Thread.new do
|
679
725
|
100.times do
|
680
726
|
client.command("create edge Friend from #{jim_rid} to #{bob_rid}")
|
@@ -688,7 +734,16 @@ RSpec.describe OrientdbClient do
|
|
688
734
|
end
|
689
735
|
end
|
690
736
|
thrs.each { |t| t.join }
|
691
|
-
|
737
|
+
rescue => e
|
738
|
+
err = e
|
739
|
+
ensure
|
740
|
+
if $distributed_mode
|
741
|
+
correct_error_raised = err.is_a?(OrientdbClient::MVCCError) || err.is_a?(OrientdbClient::DistributedRecordLockedException)
|
742
|
+
else
|
743
|
+
correct_error_raised = err.is_a?(OrientdbClient::MVCCError)
|
744
|
+
end
|
745
|
+
expect(correct_error_raised).to be true
|
746
|
+
end
|
692
747
|
end
|
693
748
|
end
|
694
749
|
|
data/spec/spec_helper.rb
CHANGED
@@ -25,6 +25,19 @@ require 'webmock/rspec'
|
|
25
25
|
WebMock.disable_net_connect!(:allow_localhost => true)
|
26
26
|
|
27
27
|
$db = ENV['ORIENTDB_TEST_DATABASENAME'] || OrientdbClient::Test::DatabaseName
|
28
|
+
begin
|
29
|
+
r = `ps aux | grep -E "server.*orient.*distributed=true" | grep -v grep | wc -l`;
|
30
|
+
$distributed_mode = r.strip.chomp.to_i == 1
|
31
|
+
rescue
|
32
|
+
puts "Could not determine Orientdb distributed/standalone mode, assuming standalone"
|
33
|
+
$distributed_mode = false
|
34
|
+
ensure
|
35
|
+
if $distributed_mode
|
36
|
+
# Orientdb distributed mode does not support db deletion.
|
37
|
+
# https://github.com/orientechnologies/orientdb/issues/3746
|
38
|
+
puts "Orientdb is running in distributed mode; skipping some tests."
|
39
|
+
end
|
40
|
+
end
|
28
41
|
|
29
42
|
RSpec.configure do |config|
|
30
43
|
# rspec-expectations config goes here. You can use an alternate
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: orientdb_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luke Rodgers
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-11-
|
11
|
+
date: 2015-11-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: typhoeus
|
@@ -146,6 +146,7 @@ extra_rdoc_files: []
|
|
146
146
|
files:
|
147
147
|
- ".gitignore"
|
148
148
|
- ".rspec"
|
149
|
+
- ".travis.yml"
|
149
150
|
- Gemfile
|
150
151
|
- LICENSE.txt
|
151
152
|
- README.md
|
@@ -194,3 +195,4 @@ test_files:
|
|
194
195
|
- spec/spec_helper.rb
|
195
196
|
- spec/support/shared_examples_for_http_adapter.rb
|
196
197
|
- spec/typhoeus_adapter_spec.rb
|
198
|
+
has_rdoc:
|