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.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.gitignore +26 -0
  4. data/.travis.yml +18 -0
  5. data/Gemfile +9 -0
  6. data/LICENSE +202 -0
  7. data/README.rdoc +124 -0
  8. data/Rakefile +43 -0
  9. data/changelog.txt +60 -0
  10. data/ci/initialize-ci.sh +36 -0
  11. data/fstudy/design_v1.dia +0 -0
  12. data/fstudy/design_v1.png +0 -0
  13. data/fstudy/domain_model.dia +0 -0
  14. data/fstudy/domain_model.png +0 -0
  15. data/fstudy/flat_class_perf.rb +56 -0
  16. data/fstudy/sample1_object_diagram.dia +0 -0
  17. data/fstudy/sample1_object_diagram.png +0 -0
  18. data/fstudy/study_case.rb +87 -0
  19. data/fstudy/technical_feasibility.rb +256 -0
  20. data/lib/orientdb4r.rb +115 -0
  21. data/lib/orientdb4r/bin/client.rb +86 -0
  22. data/lib/orientdb4r/bin/connection.rb +29 -0
  23. data/lib/orientdb4r/bin/constants.rb +20 -0
  24. data/lib/orientdb4r/bin/io.rb +38 -0
  25. data/lib/orientdb4r/bin/protocol28.rb +101 -0
  26. data/lib/orientdb4r/bin/protocol_factory.rb +25 -0
  27. data/lib/orientdb4r/chained_error.rb +37 -0
  28. data/lib/orientdb4r/client.rb +364 -0
  29. data/lib/orientdb4r/load_balancing.rb +113 -0
  30. data/lib/orientdb4r/node.rb +42 -0
  31. data/lib/orientdb4r/rest/client.rb +517 -0
  32. data/lib/orientdb4r/rest/excon_node.rb +115 -0
  33. data/lib/orientdb4r/rest/model.rb +159 -0
  34. data/lib/orientdb4r/rest/node.rb +43 -0
  35. data/lib/orientdb4r/rest/restclient_node.rb +77 -0
  36. data/lib/orientdb4r/rid.rb +54 -0
  37. data/lib/orientdb4r/utils.rb +203 -0
  38. data/lib/orientdb4r/version.rb +39 -0
  39. data/orientdb4r.gemspec +37 -0
  40. data/test/bin/test_client.rb +21 -0
  41. data/test/readme_sample.rb +38 -0
  42. data/test/test_client.rb +93 -0
  43. data/test/test_database.rb +261 -0
  44. data/test/test_ddo.rb +237 -0
  45. data/test/test_dmo.rb +115 -0
  46. data/test/test_document_crud.rb +184 -0
  47. data/test/test_gremlin.rb +52 -0
  48. data/test/test_helper.rb +10 -0
  49. data/test/test_loadbalancing.rb +81 -0
  50. data/test/test_utils.rb +67 -0
  51. metadata +136 -0
@@ -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