orient_db_client 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +4 -0
  3. data/README.md +71 -0
  4. data/Rakefile +23 -0
  5. data/lib/orient_db_client/connection.rb +141 -0
  6. data/lib/orient_db_client/database_session.rb +107 -0
  7. data/lib/orient_db_client/deserializers/deserializer7.rb +166 -0
  8. data/lib/orient_db_client/exceptions.rb +25 -0
  9. data/lib/orient_db_client/network_message.rb +42 -0
  10. data/lib/orient_db_client/protocol_factory.rb +16 -0
  11. data/lib/orient_db_client/protocols/.DS_Store +0 -0
  12. data/lib/orient_db_client/protocols/protocol7.rb +571 -0
  13. data/lib/orient_db_client/protocols/protocol9.rb +79 -0
  14. data/lib/orient_db_client/rid.rb +39 -0
  15. data/lib/orient_db_client/serializers/serializer7.rb +208 -0
  16. data/lib/orient_db_client/server_session.rb +17 -0
  17. data/lib/orient_db_client/session.rb +10 -0
  18. data/lib/orient_db_client/types.rb +22 -0
  19. data/lib/orient_db_client/version.rb +3 -0
  20. data/lib/orient_db_client.rb +18 -0
  21. data/orient_db_client.gemspec +24 -0
  22. data/test/integration/connection_test.rb +18 -0
  23. data/test/integration/database_session_9_test.rb +82 -0
  24. data/test/integration/database_session_test.rb +222 -0
  25. data/test/integration/open_database_test.rb +28 -0
  26. data/test/integration/open_server_test.rb +24 -0
  27. data/test/integration/server_session_test.rb +37 -0
  28. data/test/support/connection_helper.rb +25 -0
  29. data/test/support/create_database.sql +33 -0
  30. data/test/support/databases.yml +8 -0
  31. data/test/support/expectation_helper.rb +13 -0
  32. data/test/support/protocol_helper.rb +25 -0
  33. data/test/support/server_config.rb +6 -0
  34. data/test/support/servers-template.yml +5 -0
  35. data/test/test_helper.rb +9 -0
  36. data/test/unit/connection_test.rb +84 -0
  37. data/test/unit/deserializers/deserializer7_test.rb +141 -0
  38. data/test/unit/network_message_test.rb +24 -0
  39. data/test/unit/orient_db_client_test.rb +16 -0
  40. data/test/unit/protocol_factory_test.rb +14 -0
  41. data/test/unit/protocols/protocol7_test.rb +658 -0
  42. data/test/unit/protocols/protocol9_test.rb +149 -0
  43. data/test/unit/rid_test.rb +32 -0
  44. data/test/unit/serializers/serializer7_test.rb +72 -0
  45. metadata +167 -0
@@ -0,0 +1,37 @@
1
+ require File.join File.dirname(__FILE__), '..', 'test_helper'
2
+
3
+ class TestServerSession < MiniTest::Unit::TestCase
4
+ include ServerConfig
5
+ include ConnectionHelper
6
+
7
+ def setup
8
+ @options = SERVER_OPTIONS
9
+ @connection = connect_to_orientdb(SERVER_OPTIONS)
10
+ @session = @connection.open_server({
11
+ :user => @options["server_user"],
12
+ :password => @options["server_password"]
13
+ })
14
+ end
15
+
16
+ def teardown
17
+ @connection.close if @connection
18
+ end
19
+
20
+ def test_database_exists_command
21
+ assert @session.database_exists?(@options["database"])
22
+ refute @session.database_exists?("InvalidDatabase")
23
+ end
24
+
25
+ def test_create_and_delete_local_database_commands
26
+ database = "test_create_local_database"
27
+
28
+ @session.delete_database(database) if @session.database_exists?(database)
29
+
30
+ begin
31
+ @session.create_local_database(database)
32
+ assert @session.database_exists?(database)
33
+ ensure
34
+ @session.delete_database(database) if @session.database_exists?(database)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,25 @@
1
+ module ConnectionHelper
2
+ def connect_to_orientdb(options)
3
+ OrientDbClient.connect(options["host"], {
4
+ port: options["port"]
5
+ })
6
+ end
7
+
8
+ def mock_connect_to_orientdb(version, socket = nil)
9
+ mock_socket = socket || MiniTest::Mock.new
10
+ connection = nil
11
+
12
+ begin
13
+ TCPSocket.stubs(:open).returns(mock_socket)
14
+
15
+ mock_socket.stubs(:read).returns([version].pack('s>'))
16
+ mock_socket.stubs(:close)
17
+
18
+ connection = connect_to_orientdb({})
19
+ ensure
20
+ TCPSocket.unstub(:open)
21
+ end
22
+
23
+ connection
24
+ end
25
+ end
@@ -0,0 +1,33 @@
1
+ # Setting up V prototype database in OrientDB
2
+
3
+ DROP DATABASE remote:localhost/ruby_driver_test root "8F6FB3168FAF265896A3532C83C5E33F8B6A47996229184582D1499D5B3E8C75";
4
+
5
+ CREATE DATABASE remote:localhost/ruby_driver_test root "8F6FB3168FAF265896A3532C83C5E33F8B6A47996229184582D1499D5B3E8C75" local;
6
+
7
+ CONNECT remote:localhost/ruby_driver_test admin admin;
8
+
9
+ CREATE CLUSTER ographvertex PHYSICAL APPEND;
10
+ CREATE CLUSTER ographedge PHYSICAL APPEND;
11
+
12
+ CREATE CLASS OGraphVertex CLUSTER ographvertex;
13
+ ALTER CLASS ographvertex SHORTNAME V;
14
+
15
+ CREATE CLASS OGraphEdge CLUSTER ographedge;
16
+ ALTER CLASS ographedge SHORTNAME E;
17
+
18
+ CREATE PROPERTY OGraphVertex.in LINKSET OGraphEdge;
19
+ CREATE PROPERTY OGraphVertex.out LINKSET OGraphEdge;
20
+
21
+ CREATE PROPERTY OGraphEdge.in LINK OGraphVertex;
22
+ CREATE PROPERTY OGraphEdge.out LINK OGraphVertex;
23
+
24
+ # ----------------------------------------------------------------------
25
+ # DATA
26
+ # ----------------------------------------------------------------------
27
+
28
+ INSERT INTO V (label, in, out) VALUES ('User 1', [], []);
29
+ INSERT INTO V (label, in, out) VALUES ('User 2', [], []);
30
+
31
+ INSERT INTO E (label, out, in) VALUES ('follows', #5:0, #5:1);
32
+ UPDATE #5:0 ADD out = #6:0;
33
+ UPDATE #5:1 ADD in = #6:0;
@@ -0,0 +1,8 @@
1
+ test:
2
+ host: localhost
3
+ port: 2424
4
+ server_user: root
5
+ server_password: 83CACE21A23DB46F93BFD58A3CE48C8D29926C6EF424D7DA9BD725AE070CCDC0
6
+ database: temp
7
+ user: admin
8
+ password: admin
@@ -0,0 +1,13 @@
1
+ module ExpectationHelper
2
+ def expect_sequence(subject, chain, name)
3
+ sequence_instance = sequence(name)
4
+
5
+ chain.each do |step|
6
+ expectation = subject.expects(step[:method])
7
+
8
+ expectation.with(step[:param]) if step[:param]
9
+
10
+ expectation.returns(step[:return]).in_sequence(sequence_instance)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,25 @@
1
+ module ProtocolHelper
2
+ def pack_byte(value)
3
+ if value.is_a?(String)
4
+ value = value.length > 0 ? value[0].ord : 0
5
+ end
6
+
7
+ [ value ].pack('C')
8
+ end
9
+
10
+ def pack_integer(value)
11
+ [ value ].pack('l>')
12
+ end
13
+
14
+ def pack_long(value)
15
+ [ value ].pack('q>')
16
+ end
17
+
18
+ def pack_short(value)
19
+ [ value ].pack('s>')
20
+ end
21
+
22
+ def pack_string(value)
23
+ [ value ].pack('a*')
24
+ end
25
+ end
@@ -0,0 +1,6 @@
1
+ require 'yaml'
2
+
3
+ module ServerConfig
4
+ SERVER_CONFIG = YAML.load_file(File.join(File.dirname(__FILE__), "databases.yml"))
5
+ SERVER_OPTIONS = SERVER_CONFIG["test"]
6
+ end
@@ -0,0 +1,5 @@
1
+ test:
2
+ host: localhost
3
+ port: 2424
4
+ user: root
5
+ password: # Listed in orientdb-server-config.xml of OrientDB server
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ gem 'minitest' # ensures you're using the gem, and not the built in MT
3
+ require 'minitest/autorun'
4
+ require 'mocha'
5
+
6
+ Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','**','*.rb'))].each {|f| require f}
7
+
8
+ require 'orient_db_client'
9
+ require 'orient_db_client/exceptions'
@@ -0,0 +1,84 @@
1
+ require File.join File.dirname(__FILE__), '..', 'test_helper'
2
+
3
+ class TestConnection < MiniTest::Unit::TestCase
4
+ include ConnectionHelper
5
+ include ServerConfig
6
+
7
+ def setup
8
+ @connection = mock_connect_to_orientdb(7, @socket)
9
+ @options = SERVER_OPTIONS
10
+ @session = 25234
11
+ end
12
+
13
+ def test_creating_a_cluster
14
+ expected_cluster_id = 65
15
+
16
+ OrientDbClient::Protocols::Protocol7.stubs(:datacluster_add).returns({
17
+ :session => @session,
18
+ :message_content => { :new_cluster_number => expected_cluster_id }
19
+ })
20
+
21
+ cluster_id = @connection.create_cluster(@session, :physical, "TEST")
22
+
23
+ assert_equal expected_cluster_id, cluster_id
24
+ end
25
+
26
+ def test_creating_a_record
27
+ cluster_id = 5
28
+ expected_cluster_position = 735
29
+
30
+ OrientDbClient::Protocols::Protocol7.stubs(:record_create).returns({
31
+ :session => @session,
32
+ :message_content => { :cluster_id => cluster_id,
33
+ :cluster_position => expected_cluster_position }
34
+ })
35
+
36
+ rid = @connection.create_record(@session, cluster_id, {})
37
+
38
+ assert_equal cluster_id, rid.cluster_id
39
+ assert_equal expected_cluster_position, rid.cluster_position
40
+ end
41
+
42
+ def test_updating_a_record
43
+ expected_version = 1
44
+
45
+ OrientDbClient::Protocols::Protocol7.stubs(:record_update).returns({
46
+ :session => @session,
47
+ :message_content => { :record_version => expected_version }
48
+ })
49
+
50
+ version = @connection.update_record(@session, OrientDbClient::Rid.new(1,0), {}, :none)
51
+
52
+ assert_equal expected_version, version
53
+ end
54
+
55
+ def test_opening_the_server
56
+ OrientDbClient::Protocols::Protocol7.stubs(:connect).returns({
57
+ :session => @session,
58
+ :message_content => { :session => @session }
59
+ })
60
+
61
+ session = @connection.open_server({
62
+ :user => @options["server_user"],
63
+ :password => @options["server_password"]
64
+ })
65
+
66
+ assert_instance_of OrientDbClient::ServerSession, session
67
+ assert_equal @session, session.id
68
+ end
69
+
70
+ def test_opening_a_database
71
+ OrientDbClient::Protocols::Protocol7.stubs(:db_open).returns({
72
+ :session => @session,
73
+ :message_content => { :session => @session, :clusters => [] }
74
+ })
75
+
76
+ session = @connection.open_database(@options["database"], {
77
+ :user => @options["user"],
78
+ :password => @options["password"]
79
+ })
80
+
81
+ assert_instance_of OrientDbClient::DatabaseSession, session
82
+ assert_equal @session, session.id
83
+ end
84
+ end
@@ -0,0 +1,141 @@
1
+ require File.join File.dirname(__FILE__), '..', '..', 'test_helper'
2
+
3
+ class TestDeserializer7 < MiniTest::Unit::TestCase
4
+ def setup
5
+ @deserializer = OrientDbClient::Protocols::Protocol7.deserializer
6
+ end
7
+
8
+ def test_deserialize
9
+ record = %Q{ORole@name:"ORole",id:0,defaultClusterId:3,clusterIds:[3],inheritedRole:#3:2,lastUpdate:1296279468t,buffer:_U2VuZCByZWluZm9yY2VtZW50cw==_,byte:97b,date:1306274400a,float:5.6234f,double:2.67234235d,bignum:6871947673673457345l,bigdec:6.2724522625234c,properties:[(name:"mode",type:17,offset:0,mandatory:false,notNull:false,min:,max:,linkedClass:,linkedType:,index:#),*name:"rules",type:12,offset:1,mandatory:false,notNull:false,min:,max:,linkedClass:,linkedType:17,index:#*]}
10
+
11
+ result = @deserializer.deserialize(record)
12
+
13
+ refute_nil result
14
+
15
+ assert_equal 'ORole', result[:class]
16
+
17
+ refute_nil result[:structure]
18
+
19
+ result[:structure].tap do |s|
20
+ assert_equal :byte, s['byte']
21
+ assert_equal :binary, s['buffer']
22
+ assert_equal :integer, s['id']
23
+ assert_equal :float, s['float']
24
+ assert_equal :double, s['double']
25
+ assert_equal :time, s['lastUpdate']
26
+ assert_equal :long, s['bignum']
27
+ assert_equal :decimal, s['bigdec']
28
+ assert_equal :collection, s['properties']
29
+ end
30
+
31
+ result[:document].tap do |d|
32
+ assert_equal 0, d['id']
33
+ assert_equal 3, d['defaultClusterId']
34
+
35
+ assert d['inheritedRole'].is_a?(OrientDbClient::Rid), "expected Rid, but got #{d.class}"
36
+ assert_equal '#3:2', d['inheritedRole'].to_s
37
+
38
+ assert_equal 5.6234, d['float']
39
+ assert_equal 2.67234235, d['double']
40
+ assert_equal 6.2724522625234, d['bigdec']
41
+
42
+ assert_equal "Send reinforcements", d['buffer']
43
+
44
+ d['byte'].tap do |f|
45
+ assert_equal 97, f
46
+ end
47
+
48
+ d['bignum'].tap do |f|
49
+ assert f.is_a?(Bignum), "expected Bignum, but got #{f.class}"
50
+ assert_equal 6871947673673457345, f
51
+ end
52
+
53
+ d['date'].tap do |f|
54
+ assert f.is_a?(Date), "expected Date, but got #{f.class}"
55
+ assert_equal 2011, f.year
56
+ assert_equal 5, f.month
57
+ assert_equal 24, f.day
58
+ end
59
+
60
+ d['lastUpdate'].tap do |f|
61
+ assert f.is_a?(Time), "expected Time, but got #{f.class}"
62
+ assert_equal 2011, f.year
63
+ assert_equal 1, f.month
64
+ assert_equal 29, f.day
65
+ assert_equal 5, f.hour
66
+ assert_equal 37, f.min
67
+ assert_equal 48, f.sec
68
+ end
69
+
70
+ d['clusterIds'].tap do |f|
71
+ assert f.is_a?(Array), "expected Array, but got #{f.class}"
72
+ assert_equal 1, f.length
73
+ assert_equal 3, f[0]
74
+ end
75
+
76
+ d['properties'].tap do |f|
77
+ assert f.is_a?(Array), "expected Array, but got #{f.class}"
78
+ assert_equal 2, f.length
79
+
80
+ refute_nil f[0][:structure]
81
+
82
+ f[0][:document].tap do |p|
83
+ assert_equal 'mode', p['name']
84
+ assert_equal 17, p['type']
85
+ assert_equal 0, p['offset']
86
+ assert_equal false, p['mandatory']
87
+ assert_equal false, p['notNull']
88
+ assert_nil p['min']
89
+ assert_nil p['max']
90
+ assert_nil p['linkedClass']
91
+ assert_nil p['linkedType']
92
+ assert_nil p['index']
93
+ end
94
+
95
+ f[1][:document].tap do |p|
96
+ assert_equal 'rules', p['name']
97
+ assert_equal 12, p['type']
98
+ assert_equal 1, p['offset']
99
+ assert_equal false, p['mandatory']
100
+ assert_equal false, p['notNull']
101
+ assert_nil p['min']
102
+ assert_nil p['max']
103
+ assert_nil p['linkedClass']
104
+ assert_equal 17, p['linkedType']
105
+ assert_nil p['index']
106
+ end
107
+ end
108
+ end
109
+ end
110
+
111
+ def test_deserialize_with_maps
112
+ record = %Q{ORole@name:"reader",inheritedRole:,mode:0,rules:{"database":null,"database.cluster.internal":2,"database.cluster.orole":3,"database.cluster.ouser":4,"database.class.*":5,"database.cluster.*":6,"database.query":7,"database.command":8,"database.hook.record":9}}
113
+
114
+ result = @deserializer.deserialize(record)
115
+
116
+ refute_nil result
117
+
118
+ assert_equal 'ORole', result[:class]
119
+
120
+ result[:document].tap do |d|
121
+ assert_nil d['inheritedRole']
122
+
123
+ assert_equal 0, d['mode']
124
+
125
+ d['rules'].tap do |f|
126
+ assert f.is_a?(Hash), "expected Hash, but got #{f.class}"
127
+
128
+ assert_nil f['database']
129
+
130
+ assert_equal 2, f['database.cluster.internal']
131
+ assert_equal 3, f['database.cluster.orole']
132
+ assert_equal 4, f['database.cluster.ouser']
133
+ assert_equal 5, f['database.class.*']
134
+ assert_equal 6, f['database.cluster.*']
135
+ assert_equal 7, f['database.query']
136
+ assert_equal 8, f['database.command']
137
+ assert_equal 9, f['database.hook.record']
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,24 @@
1
+ require File.join File.dirname(__FILE__), '..', 'test_helper'
2
+
3
+ class TestNetworkMessage < MiniTest::Unit::TestCase
4
+ def test_pack
5
+ test_string = "This string is automatically preceeded by its size"
6
+
7
+ data = [
8
+ [ :byte, 143 ],
9
+ [ :short, 5000 ],
10
+ [ :integer, 153000 ],
11
+ [ :raw_string, "This is a string" ],
12
+ [ :integer, test_string.length, :skip ],
13
+ [ :string, test_string ]
14
+ ]
15
+
16
+ expected = data.map { |d| d[1] }.pack('C s> l> a* l> a*')
17
+
18
+ message = OrientDbClient::NetworkMessage.new { |m|
19
+ data.each { |d| m.add d[0], d[1] unless d[2] == :skip }
20
+ }
21
+
22
+ assert_equal expected, message.pack
23
+ end
24
+ end
@@ -0,0 +1,16 @@
1
+ require File.join File.dirname(__FILE__), '..', 'test_helper'
2
+ require 'socket'
3
+
4
+ class TestOrientDbClient < MiniTest::Unit::TestCase
5
+ include ConnectionHelper
6
+
7
+ def test_exception_on_unsupported_protocol
8
+ bad_protocol = -1
9
+
10
+ exp = assert_raises(OrientDbClient::UnsupportedProtocolError) do
11
+ mock_connect_to_orientdb(bad_protocol)
12
+ end
13
+
14
+ assert_equal "The host reports protocol version #{bad_protocol}, which is not currently supported by this driver.", exp.message
15
+ end
16
+ end
@@ -0,0 +1,14 @@
1
+ require File.join File.dirname(__FILE__), '..', 'test_helper'
2
+
3
+ require 'orient_db_client/protocol_factory'
4
+
5
+ class TestProtocolFactory < MiniTest::Unit::TestCase
6
+ def test_returns_protocol7_instance
7
+ assert_equal OrientDbClient::Protocols::Protocol7, OrientDbClient::ProtocolFactory.get_protocol(7)
8
+ end
9
+
10
+ def test_returns_protocol9_instance
11
+ assert_equal OrientDbClient::Protocols::Protocol9, OrientDbClient::ProtocolFactory.get_protocol(9)
12
+ end
13
+ end
14
+