vagas-orientdb4r 0.5.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 +7 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +26 -0
- data/.travis.yml +18 -0
- data/Gemfile +9 -0
- data/LICENSE +202 -0
- data/README.rdoc +124 -0
- data/Rakefile +43 -0
- data/changelog.txt +60 -0
- data/ci/initialize-ci.sh +36 -0
- data/fstudy/design_v1.dia +0 -0
- data/fstudy/design_v1.png +0 -0
- data/fstudy/domain_model.dia +0 -0
- data/fstudy/domain_model.png +0 -0
- data/fstudy/flat_class_perf.rb +56 -0
- data/fstudy/sample1_object_diagram.dia +0 -0
- data/fstudy/sample1_object_diagram.png +0 -0
- data/fstudy/study_case.rb +87 -0
- data/fstudy/technical_feasibility.rb +256 -0
- data/lib/orientdb4r.rb +115 -0
- data/lib/orientdb4r/bin/client.rb +86 -0
- data/lib/orientdb4r/bin/connection.rb +29 -0
- data/lib/orientdb4r/bin/constants.rb +20 -0
- data/lib/orientdb4r/bin/io.rb +38 -0
- data/lib/orientdb4r/bin/protocol28.rb +101 -0
- data/lib/orientdb4r/bin/protocol_factory.rb +25 -0
- data/lib/orientdb4r/chained_error.rb +37 -0
- data/lib/orientdb4r/client.rb +364 -0
- data/lib/orientdb4r/load_balancing.rb +113 -0
- data/lib/orientdb4r/node.rb +42 -0
- data/lib/orientdb4r/rest/client.rb +517 -0
- data/lib/orientdb4r/rest/excon_node.rb +115 -0
- data/lib/orientdb4r/rest/model.rb +159 -0
- data/lib/orientdb4r/rest/node.rb +43 -0
- data/lib/orientdb4r/rest/restclient_node.rb +77 -0
- data/lib/orientdb4r/rid.rb +54 -0
- data/lib/orientdb4r/utils.rb +203 -0
- data/lib/orientdb4r/version.rb +39 -0
- data/orientdb4r.gemspec +37 -0
- data/test/bin/test_client.rb +21 -0
- data/test/readme_sample.rb +38 -0
- data/test/test_client.rb +93 -0
- data/test/test_database.rb +261 -0
- data/test/test_ddo.rb +237 -0
- data/test/test_dmo.rb +115 -0
- data/test/test_document_crud.rb +184 -0
- data/test/test_gremlin.rb +52 -0
- data/test/test_helper.rb +10 -0
- data/test/test_loadbalancing.rb +81 -0
- data/test/test_utils.rb +67 -0
- metadata +136 -0
data/lib/orientdb4r.rb
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
require 'base64'
|
|
3
|
+
require 'logger'
|
|
4
|
+
require 'orientdb4r/version'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
###
|
|
8
|
+
# This module represents the entry point for using the Ruby OrientDB client.
|
|
9
|
+
module Orientdb4r
|
|
10
|
+
|
|
11
|
+
module Binary
|
|
12
|
+
autoload :BinClient, 'orientdb4r/bin/client'
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
autoload :Utils, 'orientdb4r/utils'
|
|
16
|
+
autoload :Client, 'orientdb4r/client'
|
|
17
|
+
autoload :RestClient, 'orientdb4r/rest/client'
|
|
18
|
+
autoload :Rid, 'orientdb4r/rid'
|
|
19
|
+
autoload :HashExtension, 'orientdb4r/rest/model'
|
|
20
|
+
autoload :OClass, 'orientdb4r/rest/model'
|
|
21
|
+
autoload :ChainedError, 'orientdb4r/chained_error'
|
|
22
|
+
autoload :Node, 'orientdb4r/node'
|
|
23
|
+
autoload :RestNode, 'orientdb4r/rest/node'
|
|
24
|
+
autoload :RestClientNode, 'orientdb4r/rest/restclient_node'
|
|
25
|
+
autoload :ExconNode, 'orientdb4r/rest/excon_node'
|
|
26
|
+
autoload :Sequence, 'orientdb4r/load_balancing'
|
|
27
|
+
autoload :RoundRobin, 'orientdb4r/load_balancing'
|
|
28
|
+
autoload :DocumentMetadata, 'orientdb4r/rest/model'
|
|
29
|
+
|
|
30
|
+
MUTEX_CLIENT = Mutex.new
|
|
31
|
+
|
|
32
|
+
class << self
|
|
33
|
+
|
|
34
|
+
###
|
|
35
|
+
# Gets a new database client or an existing for the current thread.
|
|
36
|
+
# === options
|
|
37
|
+
# * :instance => :new
|
|
38
|
+
# * :binary => true
|
|
39
|
+
# * :connection_library => :restclient | :excon
|
|
40
|
+
def client options={}
|
|
41
|
+
if :new == options[:instance]
|
|
42
|
+
options.delete :instance
|
|
43
|
+
return options.delete(:binary) ? Binary::BinClient.new(options) : RestClient.new(options)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
MUTEX_CLIENT.synchronize {
|
|
47
|
+
client = options.delete(:binary) ? Binary::BinClient.new(options) : RestClient.new(options)
|
|
48
|
+
Thread.current[:orientdb_client] ||= client
|
|
49
|
+
#Thread.current[:orientdb_client] ||= BinClient.new options
|
|
50
|
+
}
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
###
|
|
54
|
+
# Logger used for logging output
|
|
55
|
+
attr_accessor :logger
|
|
56
|
+
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
###
|
|
61
|
+
# Basic error that indicates an unexpected situation during the client call.
|
|
62
|
+
class OrientdbError < StandardError
|
|
63
|
+
include ChainedError
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
###
|
|
67
|
+
# Error indicating that the request is malformed of invalid somehow.
|
|
68
|
+
class InvalidRequestError < OrientdbError; end
|
|
69
|
+
|
|
70
|
+
###
|
|
71
|
+
# Error indicating that access to the resource requires user authentication.
|
|
72
|
+
class UnauthorizedError < OrientdbError; end
|
|
73
|
+
|
|
74
|
+
###
|
|
75
|
+
# Error indicating a conflict between database state and the request
|
|
76
|
+
class StateConflictError < OrientdbError; end
|
|
77
|
+
|
|
78
|
+
###
|
|
79
|
+
# Error indicating that the server encountered an unexpected condition which prevented it from fulfilling the request.
|
|
80
|
+
class ServerError < OrientdbError; end
|
|
81
|
+
|
|
82
|
+
###
|
|
83
|
+
# Error indicating problems with communicating with the database.
|
|
84
|
+
class ConnectionError < OrientdbError; end
|
|
85
|
+
|
|
86
|
+
###
|
|
87
|
+
# Error raised to inform that an object identified by RID cannot be get.
|
|
88
|
+
class NotFoundError < OrientdbError; end
|
|
89
|
+
|
|
90
|
+
###
|
|
91
|
+
# Error indicating that manipulation against the given data resulted in some illegal operation,
|
|
92
|
+
# mismatched types or incorrect cardinality.
|
|
93
|
+
class DataError < OrientdbError; end
|
|
94
|
+
|
|
95
|
+
# ---------------------------------------------------------- System Exceptions
|
|
96
|
+
|
|
97
|
+
###
|
|
98
|
+
# This exception represents a fatal failure which meens that the node is not accessible more.
|
|
99
|
+
# e.g. connection broken pipe
|
|
100
|
+
class NodeError < OrientdbError; end
|
|
101
|
+
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
# Configuration of logging.
|
|
106
|
+
Orientdb4r::logger = Logger.new(STDOUT)
|
|
107
|
+
Orientdb4r::logger.level = Logger::INFO
|
|
108
|
+
|
|
109
|
+
Orientdb4r::logger.info \
|
|
110
|
+
"Orientdb4r #{Orientdb4r::VERSION}, running on Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
#Orientdb4r::logger.level = Logger::DEBUG
|
|
114
|
+
#client = Orientdb4r.client
|
|
115
|
+
#client.connect :database => 'temp', :user => 'admin', :password => 'admin'
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
require 'socket'
|
|
2
|
+
require 'bindata'
|
|
3
|
+
require 'orientdb4r/bin/constants'
|
|
4
|
+
require 'orientdb4r/bin/protocol_factory'
|
|
5
|
+
require 'orientdb4r/bin/io'
|
|
6
|
+
require 'orientdb4r/bin/connection'
|
|
7
|
+
|
|
8
|
+
module Orientdb4r
|
|
9
|
+
|
|
10
|
+
module Binary
|
|
11
|
+
|
|
12
|
+
###
|
|
13
|
+
# This client implements the binary protocol.
|
|
14
|
+
class BinClient < Client
|
|
15
|
+
include Binary::Constants
|
|
16
|
+
include Binary::OIO
|
|
17
|
+
|
|
18
|
+
attr_reader :server_connection
|
|
19
|
+
attr_reader :db_connection
|
|
20
|
+
attr_reader :protocol
|
|
21
|
+
attr_reader :protocol_version
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def initialize(options) #:nodoc:
|
|
25
|
+
super()
|
|
26
|
+
options_pattern = {
|
|
27
|
+
:host => 'localhost', :port => 2424
|
|
28
|
+
}
|
|
29
|
+
verify_and_sanitize_options(options, options_pattern)
|
|
30
|
+
|
|
31
|
+
@host = options[:host]
|
|
32
|
+
@port = options[:port]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
# --------------------------------------------------------------- CONNECTION
|
|
37
|
+
|
|
38
|
+
def connect options #:nodoc:
|
|
39
|
+
options_pattern = { :database => :mandatory, :user => :mandatory, :password => :mandatory, :session => :optional, :db_type => 'document' }
|
|
40
|
+
verify_and_sanitize_options(options, options_pattern)
|
|
41
|
+
|
|
42
|
+
@socket = TCPSocket.open(@host, @port)
|
|
43
|
+
@protocol_version = BinData::Int16be.read(@socket).to_i
|
|
44
|
+
|
|
45
|
+
Orientdb4r::logger.info "Binary protocol version: #{@protocol_version}"
|
|
46
|
+
|
|
47
|
+
# check minimal protocol version which is supported
|
|
48
|
+
@protocol = ProtocolFactory.get_protocol(protocol_version)
|
|
49
|
+
|
|
50
|
+
command = protocol::DbOpenRequest.new(:protocol_version => protocol_version, :db_name => options[:database], :user => options[:user], :password => options[:password])
|
|
51
|
+
|
|
52
|
+
resp = req_resp(@socket, command, protocol::DbOpenResponse.new)
|
|
53
|
+
db_connection = Orientdb4r::Binary::Connection.new(resp.session, options)
|
|
54
|
+
Orientdb4r::logger.info "Database connected, session=#{db_connection.session_id}"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def disconnect #:nodoc:
|
|
59
|
+
@socket.close
|
|
60
|
+
@protocol = nil
|
|
61
|
+
@protocol_version = 0
|
|
62
|
+
@db_connection.close unless @db_connection.nil?
|
|
63
|
+
@server_connection.close unless @server_connection.nil?
|
|
64
|
+
@db_connection = nil
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def server(options={})
|
|
69
|
+
raise NotImplementedError, 'this should be overridden by concrete client'
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
# ------------------------------------------------------------------ Helpers
|
|
74
|
+
|
|
75
|
+
private
|
|
76
|
+
|
|
77
|
+
# Gets a hash of parameters.
|
|
78
|
+
def params(args = {})
|
|
79
|
+
args.merge({ session: connection.session })
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Orientdb4r
|
|
2
|
+
|
|
3
|
+
module Binary
|
|
4
|
+
|
|
5
|
+
class Connection
|
|
6
|
+
|
|
7
|
+
attr_reader :session_id
|
|
8
|
+
attr_reader :params
|
|
9
|
+
|
|
10
|
+
def initialize(session_id, params)
|
|
11
|
+
@session_id = session_id
|
|
12
|
+
@params = params
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def connected?
|
|
16
|
+
!session_id.nil? and session_id < 0
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def close
|
|
20
|
+
@params.clear
|
|
21
|
+
@params = nil
|
|
22
|
+
@session_id = 0
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Orientdb4r
|
|
2
|
+
|
|
3
|
+
module Binary
|
|
4
|
+
|
|
5
|
+
module Constants
|
|
6
|
+
|
|
7
|
+
MINIMAL_PROTOCOL_VERSION = 28 # ODB v2.0.5
|
|
8
|
+
|
|
9
|
+
REQUEST_SHUTDOWN = 1
|
|
10
|
+
REQUEST_CONNECT = 2
|
|
11
|
+
REQUEST_DB_OPEN = 3
|
|
12
|
+
|
|
13
|
+
STATUS_OK = 0
|
|
14
|
+
STATUS_ERROR = 1
|
|
15
|
+
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require 'bindata'
|
|
2
|
+
require 'orientdb4r/bin/constants'
|
|
3
|
+
|
|
4
|
+
module Orientdb4r
|
|
5
|
+
|
|
6
|
+
module Binary
|
|
7
|
+
|
|
8
|
+
module OIO
|
|
9
|
+
|
|
10
|
+
def req_resp(socket, req, resp)
|
|
11
|
+
req.write(socket)
|
|
12
|
+
|
|
13
|
+
status = BinData::Int8.read(socket).to_i
|
|
14
|
+
if ::Orientdb4r::Binary::Constants::STATUS_ERROR == status
|
|
15
|
+
errors = protocol::Errors.read(socket)
|
|
16
|
+
exceptions = errors[:exceptions]
|
|
17
|
+
Orientdb4r::logger.error "exception(s): #{exceptions}"
|
|
18
|
+
|
|
19
|
+
# if exceptions[0] && exceptions[0][:exception_class] == "com.orientechnologies.orient.core.exception.ORecordNotFoundException"
|
|
20
|
+
# raise RecordNotFound.new(session)
|
|
21
|
+
# else
|
|
22
|
+
# raise ServerError.new(session, *exceptions)
|
|
23
|
+
# end
|
|
24
|
+
raise ServerError, exceptions[0..-2]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
BinData::trace_reading do
|
|
28
|
+
resp.read(socket)
|
|
29
|
+
end
|
|
30
|
+
resp
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
require 'bindata'
|
|
2
|
+
|
|
3
|
+
module Orientdb4r
|
|
4
|
+
|
|
5
|
+
module Binary
|
|
6
|
+
|
|
7
|
+
class Protocol28
|
|
8
|
+
|
|
9
|
+
# Common Constructs -----------------------------------------------------
|
|
10
|
+
|
|
11
|
+
class ProtocolString < BinData::Primitive
|
|
12
|
+
endian :big
|
|
13
|
+
|
|
14
|
+
int32 :len, :value => lambda { data.length }
|
|
15
|
+
string :data, :read_length => :len, :onlyif => :not_blank?
|
|
16
|
+
|
|
17
|
+
def get; self.data; end
|
|
18
|
+
def set(v) self.data = v; end
|
|
19
|
+
|
|
20
|
+
def not_blank?
|
|
21
|
+
len > 0
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class Errors < BinData::Record
|
|
27
|
+
endian :big
|
|
28
|
+
|
|
29
|
+
int32 :session
|
|
30
|
+
array :exceptions, read_until: -> { element[:is_error] < 1 } do
|
|
31
|
+
int8 :is_error
|
|
32
|
+
protocol_string :exception_class, onlyif: -> { 1 == is_error }
|
|
33
|
+
protocol_string :exception_message, onlyif: -> { 1 == is_error }
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
int32 :len
|
|
37
|
+
skip :length => :len
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# -----------------------------------------------------------------------
|
|
41
|
+
|
|
42
|
+
class DbOpenRequest < BinData::Record
|
|
43
|
+
endian :big
|
|
44
|
+
|
|
45
|
+
int8 :operation, :value => ::Orientdb4r::Binary::Constants::REQUEST_DB_OPEN
|
|
46
|
+
int32 :session, :value => -123456
|
|
47
|
+
|
|
48
|
+
protocol_string :driver_name, :value => Orientdb4r::DRIVER_NAME
|
|
49
|
+
protocol_string :driver_version, :value => Orientdb4r::VERSION
|
|
50
|
+
int16 :protocol_version
|
|
51
|
+
protocol_string :client_id
|
|
52
|
+
protocol_string :serialization_impl, :value => 'ORecordDocument2csv'
|
|
53
|
+
int8 :token_based, :value => 0
|
|
54
|
+
protocol_string :db_name
|
|
55
|
+
protocol_string :db_type, :value => 'document'
|
|
56
|
+
protocol_string :user
|
|
57
|
+
protocol_string :password
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
class DbOpenResponse < BinData::Record
|
|
61
|
+
endian :big
|
|
62
|
+
|
|
63
|
+
int32 :session
|
|
64
|
+
skip :length => 8
|
|
65
|
+
int16 :num_of_clusters
|
|
66
|
+
array :clusters, :initial_length => :num_of_clusters do
|
|
67
|
+
protocol_string :name
|
|
68
|
+
int16 :cluster_id
|
|
69
|
+
end
|
|
70
|
+
#int8 :cluster_config_bytes
|
|
71
|
+
protocol_string :cluster_config_bytes
|
|
72
|
+
#skip :length => 4
|
|
73
|
+
#protocol_string :neco
|
|
74
|
+
protocol_string :orientdb_release
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
class Connect < BinData::Record
|
|
78
|
+
endian :big
|
|
79
|
+
|
|
80
|
+
int8 :operation, :value => 2
|
|
81
|
+
int32 :session, :value => -1 #NEW_SESSION
|
|
82
|
+
protocol_string :driver, :value => 'Orientdb4r Ruby Client'
|
|
83
|
+
protocol_string :driver_version, :value => Orientdb4r::VERSION
|
|
84
|
+
int16 :version
|
|
85
|
+
protocol_string :client_id
|
|
86
|
+
protocol_string :user
|
|
87
|
+
protocol_string :password
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
class ConnectAnswer < BinData::Record
|
|
91
|
+
endian :big
|
|
92
|
+
|
|
93
|
+
skip length: 4
|
|
94
|
+
int32 :session
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require 'orientdb4r/bin/protocol28'
|
|
2
|
+
|
|
3
|
+
module Orientdb4r
|
|
4
|
+
|
|
5
|
+
class ProtocolFactory
|
|
6
|
+
|
|
7
|
+
PROTOCOLS = {
|
|
8
|
+
28 => Orientdb4r::Binary::Protocol28
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
def self.get_protocol(version)
|
|
12
|
+
return PROTOCOLS[version] if PROTOCOLS.include? version
|
|
13
|
+
|
|
14
|
+
#search for a smaller one
|
|
15
|
+
PROTOCOLS.keys.sort.each do |key|
|
|
16
|
+
next if key > version
|
|
17
|
+
return if key < version
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
raise OrientdbError, "Unsupported protocol version, desired=#{version}, supported=#{PROTOCOLS.key.sort}"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module Orientdb4r
|
|
2
|
+
|
|
3
|
+
###
|
|
4
|
+
# This mixin extends an error to be able to track a chain of exceptions.
|
|
5
|
+
module ChainedError
|
|
6
|
+
|
|
7
|
+
attr_reader :cause
|
|
8
|
+
|
|
9
|
+
###
|
|
10
|
+
# Constructor.
|
|
11
|
+
def initialize message = nil, cause = $!
|
|
12
|
+
super message unless message.nil?
|
|
13
|
+
super $! if message.nil? and !cause.nil?
|
|
14
|
+
@cause = cause
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
###
|
|
18
|
+
# Modification of original method Error#set_backtrace
|
|
19
|
+
# to descend the full depth of the exception chain.
|
|
20
|
+
def set_backtrace bt
|
|
21
|
+
unless cause.nil?
|
|
22
|
+
cause.backtrace.reverse.each do |line|
|
|
23
|
+
if bt.last == line
|
|
24
|
+
bt.pop
|
|
25
|
+
next
|
|
26
|
+
end
|
|
27
|
+
break
|
|
28
|
+
end
|
|
29
|
+
bt.push "<<<CAUSED BY>>>: #{cause.class}: #{cause.message}"
|
|
30
|
+
bt.concat cause.backtrace
|
|
31
|
+
end
|
|
32
|
+
super bt
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
end
|