diff --git a/lib/orient_db_client/connection.rb b/lib/orient_db_client/connection.rb index b6c4e5c..2907480 100644 --- a/lib/orient_db_client/connection.rb +++ b/lib/orient_db_client/connection.rb @@ -11,7 +11,11 @@ def initialize(socket, protocol_version, options = {}) end def close - @socket.close + @socket.close + end + + def config_get(session, config_name) + @protocol.config_get(@socket, session, config_name) end def close_database(session) @@ -93,6 +97,7 @@ def load_record(session, rid) result = @protocol.record_load(@socket, session, rid) + if result[:message_content] result[:message_content].tap do |r| r[:cluster_id] = rid.cluster_id @@ -115,7 +120,7 @@ def open_database(database, options = {}) response = @protocol.db_open(@socket, database, options) session = response[:session] message_content = response[:message_content] - + @sessions[session] = DatabaseSession.new(message_content[:session], self, message_content[:clusters]) end @@ -126,6 +131,14 @@ def query(session, text, options = {}) result[:message_content] end + + def command(session, text, options = {}) + options[:query_class_name] = :command + + result = @protocol.command(@socket, session, text, options) + + result[:message_content] + end def reload(session) result = @protocol.db_reload(@socket, session) diff --git a/lib/orient_db_client/protocol_factory.rb b/lib/orient_db_client/protocol_factory.rb index 5bede4b..006e0ac 100644 --- a/lib/orient_db_client/protocol_factory.rb +++ b/lib/orient_db_client/protocol_factory.rb @@ -1,5 +1,5 @@ require File.join(File.dirname(__FILE__), 'protocols', 'protocol7') -require File.join(File.dirname(__FILE__), 'protocols', 'protocol9') +require File.join(File.dirname(__FILE__), 'protocols', 'protocol12') module OrientDbClient class ProtocolFactory @@ -10,10 +10,7 @@ class ProtocolFactory PROTOCOLS = { '7' => Protocols::Protocol7, - '9' => Protocols::Protocol9, - '10' => Protocols::Protocol9, - '11' => Protocols::Protocol9, - '12' => Protocols::Protocol9 + '12' => Protocols::Protocol12 } def self.get_protocol(version) diff --git a/lib/orient_db_client/protocols/protocol12.rb b/lib/orient_db_client/protocols/protocol12.rb new file mode 100644 index 0000000..0b88630 --- /dev/null +++ b/lib/orient_db_client/protocols/protocol12.rb @@ -0,0 +1,226 @@ +require 'orient_db_client/network_message' +require 'orient_db_client/version' +require 'bindata' + +module OrientDbClient + module Protocols + class Protocol12 < Protocol7 + VERSION = 12 + + module Commands + class ConfigGet < BinData::Record + endian :big + int8 :operation, :value => Protocol7::Operations::CONFIG_GET + int32 :session + protocol_string :config_name + end + + class DbCreate < BinData::Record + endian :big + + int8 :operation, :value => Protocol7::Operations::DB_CREATE + int32 :session + + protocol_string :database + protocol_string :database_type + protocol_string :storage_type + end + + class DbOpen < BinData::Record + endian :big + + int8 :operation, :value => Protocol7::Operations::DB_OPEN + int32 :session, :value => Protocol7::NEW_SESSION + + protocol_string :driver_name, :value => Protocol7::DRIVER_NAME + protocol_string :driver_version, :value => Protocol7::DRIVER_VERSION + int16 :protocol_version + protocol_string :client_id + protocol_string :database_name + protocol_string :database_type + protocol_string :user_name + protocol_string :user_password + end + + class RecordLoad12 < BinData::Record + endian :big + + int8 :operation, :value => Protocol7::Operations::RECORD_LOAD + int32 :session + + int16 :cluster_id + int64 :cluster_position + protocol_string :fetch_plan + int8 :ignore_cache, :initial_value => 1 + end + + class RecordCreate12 < BinData::Record + endian :big + + int8 :operation, :value => Protocol7::Operations::RECORD_CREATE + int32 :session + int32 :datasegment_id, :value => -1 + int16 :cluster_id + protocol_string :record_content + int8 :record_type, :value => Protocol7::RecordTypes::DOCUMENT + int8 :mode, :value => Protocol7::SyncModes::SYNC + end + + end + + def self.command(socket, session, command, options = {}) + options[:query_class_name].tap do |qcn| + if qcn.is_a?(Symbol) + qcn = case qcn + when :query then 'q' + when :command then 'c' + end + end + + if qcn.nil? || qcn == 'com.orientechnologies.orient.core.sql.query.OSQLSynchQuery' + qcn = 'q' + end + + options[:query_class_name] = qcn + end + + super socket, session, command, options + end + + def self.db_create(socket, session, database, options = {}) + if options.is_a?(String) + options = { :storage_type => options } + end + + options = { + :database_type => 'document' + }.merge(options) + + super + end + + def self.read_clusters(socket) + clusters = [] + + num_clusters = read_short(socket) + (num_clusters).times do |x| + cluster = + { + :name => read_string(socket), + :id => read_short(socket), + :type => read_string(socket), + :data_segment => read_short(socket) + } + clusters << cluster + + end + + clusters + end + + def self.read_record_load(socket) + result = nil + + status = read_byte(socket) + + while (status != PayloadStatuses::NO_RECORDS) + case status + when PayloadStatuses::RESULTSET + record = record || read_record(socket) + case record[:record_type] + when 'd'.ord + result = result || record + result[:document] = deserializer.deserialize(record[:bytes])[:document] + else + raise "Unsupported record type: #{record[:record_type]}" + end + else + raise "Unsupported payload status: #{status}" + end + status = read_byte(socket) + end + + result + end + + def self.read_db_open(socket) + session = read_integer(socket) + clusters = read_clusters(socket) + { :session => session, + :clusters => clusters, + :cluster_config => read_string(socket) } + end + + def self.record_create(socket, session, cluster_id, record) + command = Commands::RecordCreate12.new :session => session, + :cluster_id => cluster_id, + :record_content => serializer.serialize(record) + command.write(socket) + + read_response(socket) + + { :session => read_integer(socket), + :message_content => read_record_create(socket).merge({ :cluster_id => cluster_id }) } + end + + def self.db_open(socket, database, options = {}) + command = Commands::DbOpen.new :protocol_version => self.version, + :database_name => database, + :database_type => options[:database_type] || 'document', + :user_name => options[:user], + :user_password => options[:password] + command.write(socket) + + read_response(socket) + + { :session => read_integer(socket), + :message_content => read_db_open(socket) } + end + + def self.config_get(socket, session, config_name) + config = Commands::ConfigGet.new :session => session, + :config_name => config_name + + config.write(socket) + + response = read_response(socket) + { :session => read_integer(socket), + :value => read_string(socket) } + + end + + def self.record_load(socket, session, rid, options = {}) + command = Commands::RecordLoad12.new :session => session, + :cluster_id => rid.cluster_id, + :cluster_position => rid.cluster_position + # :ignore_cache => options[:ignore_cache] === true ? 1 : 0 + + command.write(socket) + + read_response(socket) + + { :session => read_integer(socket), + :message_content => read_record_load(socket) } + end + + def self.read_record_create(socket) + { :cluster_position => read_long(socket), + :record_version => read_integer(socket) } + end + + private + + def self.make_db_create_command(*args) + session = args.shift + database = args.shift + options = args.shift + + Commands::DbCreate.new :session => session, + :database => database, + :database_type => options[:database_type].to_s, + :storage_type => options[:storage_type] + end + + end + end +end \ No newline at end of file diff --git a/lib/orient_db_client/protocols/protocol7.rb b/lib/orient_db_client/protocols/protocol7.rb index 47a6016..7c96fe6 100644 --- a/lib/orient_db_client/protocols/protocol7.rb +++ b/lib/orient_db_client/protocols/protocol7.rb @@ -34,6 +34,9 @@ module Operations RECORD_DELETE = 33 RECORD_LOAD = 30 RECORD_UPDATE = 32 + CONFIG_GET = 70 + CONFIG_SET = 71 + CONFIG_LIST = 72 end module RecordTypes @@ -398,6 +401,7 @@ def self.datacluster_remove(socket, session, cluster_id) end def self.db_close(socket, session = NEW_SESSION) + return true if socket.closed? command = Commands::DbClose.new :session => session command.write(socket) @@ -463,6 +467,8 @@ def self.db_open(socket, database, options = {}) { :session => read_integer(socket), :message_content => read_db_open(socket) } end + + def self.db_reload(socket, session) command = Commands::DbReload.new :session => session @@ -483,6 +489,8 @@ def self.db_size(socket, session) { :session => read_integer(socket), :message_content => read_db_size(socket) } end + + def self.record_create(socket, session, cluster_id, record) command = Commands::RecordCreate.new :session => session, @@ -578,12 +586,17 @@ def self.read_count(socket) def self.read_clusters(socket) clusters = [] - read_short(socket).times do - clusters << { + num_clusters = read_short(socket) + (num_clusters).times do |x| + cluster = + { :name => read_string(socket), :id => read_short(socket), - :type => read_string(socket) + :type => read_string(socket), + :other => read_short(socket) } + clusters << cluster + end clusters @@ -616,6 +629,8 @@ def self.read_command(socket) collection = read_record_collection(socket) result.concat collection break + when PayloadStatuses::SERIALIZED + result.push(status) else raise "Unsupported payload status: #{status}" end @@ -650,8 +665,10 @@ def self.read_db_exist(socket) end def self.read_db_open(socket) - { :session => read_integer(socket), - :clusters => read_clusters(socket), + session = read_integer(socket) + clusters = read_clusters(socket) + { :session => session, + :clusters => clusters, :cluster_config => read_string(socket) } end @@ -765,4 +782,4 @@ def self.read_string(socket) end end end -end \ No newline at end of file +end diff --git a/lib/orient_db_client/protocols/protocol9.rb b/lib/orient_db_client/protocols/protocol9.rb deleted file mode 100644 index eb0eee9..0000000 --- a/lib/orient_db_client/protocols/protocol9.rb +++ /dev/null @@ -1,125 +0,0 @@ -require 'orient_db_client/network_message' -require 'orient_db_client/version' - -require 'bindata' - -module OrientDbClient - module Protocols - class Protocol9 < Protocol7 - VERSION = 9 - - module Commands - class DbCreate9 < BinData::Record - endian :big - - int8 :operation, :value => Protocol7::Operations::DB_CREATE - int32 :session - - protocol_string :database - protocol_string :database_type - protocol_string :storage_type - end - - class DbOpen9 < BinData::Record - endian :big - - int8 :operation, :value => Protocol7::Operations::DB_OPEN - int32 :session, :value => Protocol7::NEW_SESSION - - protocol_string :driver_name, :value => Protocol7::DRIVER_NAME - protocol_string :driver_version, :value => Protocol7::DRIVER_VERSION - int16 :protocol_version - protocol_string :client_id - protocol_string :database_name - protocol_string :database_type - protocol_string :user_name - protocol_string :user_password - end - - class RecordLoad9 < BinData::Record - endian :big - - int8 :operation, :value => Protocol7::Operations::RECORD_LOAD - int32 :session - - int16 :cluster_id - int64 :cluster_position - protocol_string :fetch_plan - int8 :ignore_cache, :initial_value => 0 - end - end - - def self.command(socket, session, command, options = {}) - options[:query_class_name].tap do |qcn| - if qcn.is_a?(Symbol) - qcn = case qcn - when :query then 'q' - when :command then 'c' - end - end - - if qcn.nil? || qcn == 'com.orientechnologies.orient.core.sql.query.OSQLSynchQuery' - qcn = 'q' - end - - options[:query_class_name] = qcn - end - - super socket, session, command, options - end - - def self.db_create(socket, session, database, options = {}) - if options.is_a?(String) - options = { :storage_type => options } - end - - options = { - :database_type => 'document' - }.merge(options) - - super - end - - def self.db_open(socket, database, options = {}) - command = Commands::DbOpen9.new :protocol_version => self.version, - :database_name => database, - :database_type => options[:database_type] || 'document', - :user_name => options[:user], - :user_password => options[:password] - command.write(socket) - - read_response(socket) - - { :session => read_integer(socket), - :message_content => read_db_open(socket) } - end - - def self.record_load(socket, session, rid, options = {}) - command = Commands::RecordLoad9.new :session => session, - :cluster_id => rid.cluster_id, - :cluster_position => rid.cluster_position, - :ignore_cache => options[:ignore_cache] === true ? 1 : 0 - command.write(socket) - - read_response(socket) - - { :session => read_integer(socket), - :message_content => read_record_load(socket) } - end - - private - - def self.make_db_create_command(*args) - session = args.shift - database = args.shift - options = args.shift - - Commands::DbCreate9.new :session => session, - :database => database, - :database_type => options[:database_type].to_s, - :storage_type => options[:storage_type] - end - - end - end -end \ No newline at end of file diff --git a/lib/orient_db_client/server_session.rb b/lib/orient_db_client/server_session.rb index da162a8..08d033d 100644 --- a/lib/orient_db_client/server_session.rb +++ b/lib/orient_db_client/server_session.rb @@ -13,6 +13,10 @@ def create_memory_database(database, options = {}) @connection.create_database(@id, database, options) end + + def config_get(config_name) + @connection.config_get(@id, config_name) + end def database_exists?(database) @connection.database_exists?(@id, database) diff --git a/lib/orient_db_client/version.rb b/lib/orient_db_client/version.rb index 6ab1397..b67516b 100644 --- a/lib/orient_db_client/version.rb +++ b/lib/orient_db_client/version.rb @@ -1,3 +1,3 @@ module OrientDbClient - VERSION = "0.0.6" + VERSION = "0.0.9" end diff --git a/test/integration/connection_test.rb b/test/integration/connection_test.rb index 85dcf45..9bfb336 100644 --- a/test/integration/connection_test.rb +++ b/test/integration/connection_test.rb @@ -15,4 +15,5 @@ def teardown def test_establishing_a_connection assert_instance_of OrientDbClient::Connection, @connection end + end diff --git a/test/integration/database_session_9_test.rb b/test/integration/database_session_12_test.rb similarity index 63% rename from test/integration/database_session_9_test.rb rename to test/integration/database_session_12_test.rb index 87b7070..48c8899 100644 --- a/test/integration/database_session_9_test.rb +++ b/test/integration/database_session_12_test.rb @@ -54,6 +54,55 @@ def test_query end end end + + def test_multi_create12 + cluster = "Test123" + + ensure_cluster_exists(@session, cluster) + @session.reload + + cluster_id = @session.get_cluster(cluster)[:id] + + record = { :this => "sucks" } + + rid = @session.create_record(cluster_id, record) + rec = @session.load_record(rid) + + + end + + def test_create_class + @connection.command(@session.id, "Create class testclass") + @connection.command(@session.id, "drop class testclass") + end + + def test_create_and_delete_record12 + + cluster = "OTest" + + ensure_cluster_exists(@session, cluster) + @session.reload + + cluster_id = @session.get_cluster(cluster)[:id] + + record = { :key1 => "value1" } + + rid = @session.create_record(cluster_id, record) + created_record = @session.load_record(rid) + + assert_equal cluster_id, rid.cluster_id + assert_equal 0, rid.cluster_position + + refute_nil created_record + refute_nil created_record[:document]['key1'] + + assert_equal record[:key1], created_record[:document]['key1'] + + assert @session.delete_record(rid, created_record[:record_version]) + assert_nil @session.load_record(rid) + + ensure_cluster_does_not_exist(@session, cluster) + end def test_load_record result = @session.load_record("#4:0") @@ -72,7 +121,7 @@ def test_load_record assert roles.is_a?(Array), "expected Array, but got #{roles.class}" assert roles[0].is_a?(OrientDbClient::Rid) - assert_equal 3, roles[0].cluster_id + assert_equal 4, roles[0].cluster_id assert_equal 0, roles[0].cluster_position end end diff --git a/test/integration/database_session_test.rb b/test/integration/database_session_test.rb index aa59a92..d04e897 100644 --- a/test/integration/database_session_test.rb +++ b/test/integration/database_session_test.rb @@ -1,5 +1,5 @@ require File.join File.dirname(__FILE__), '..', 'test_helper' - + class TestDatabaseSession < MiniTest::Unit::TestCase include ServerConfig include ConnectionHelper @@ -12,6 +12,7 @@ def setup :user => @options["user"], :password => @options["password"] }) + end def teardown @@ -59,7 +60,7 @@ def test_query result[0].tap do |record| assert_equal 0, record[:format] - assert_equal 4, record[:cluster_id] + assert_equal 5, record[:cluster_id] assert_equal 0, record[:cluster_position] record[:document].tap do |doc| @@ -70,7 +71,7 @@ def test_query assert roles.is_a?(Array), "expected Array, but got #{roles.class}" assert roles[0].is_a?(OrientDbClient::Rid) - assert_equal 3, roles[0].cluster_id + assert_equal 4, roles[0].cluster_id assert_equal 0, roles[0].cluster_position end end @@ -90,7 +91,7 @@ def test_create_cluster new_cluster = @session.create_physical_cluster(cluster) - assert_equal 6, new_cluster + assert new_cluster assert @session.cluster_exists?(cluster) @@ -100,6 +101,7 @@ def test_create_cluster end def test_create_and_delete_record + cluster = "OTest" ensure_cluster_exists(@session, cluster) @@ -110,7 +112,6 @@ def test_create_and_delete_record rid = @session.create_record(cluster_id, record) created_record = @session.load_record(rid) - assert_equal cluster_id, rid.cluster_id assert_equal 0, rid.cluster_position @@ -186,15 +187,9 @@ def test_load_record record[:document].tap do |doc| assert_equal 'admin', doc['name'] - assert_equal 'ACTIVE', doc['status'] - - doc['roles'].tap do |roles| - assert roles.is_a?(Array), "expected Array, but got #{roles.class}" - - assert roles[0].is_a?(OrientDbClient::Rid) - assert_equal 3, roles[0].cluster_id - assert_equal 0, roles[0].cluster_position - end + assert_equal 1, doc['mode'] + assert doc['rules'].is_a?(Hash), "expected Hash, but got #{doc['rules'].class}" + end end diff --git a/test/integration/server_session_test.rb b/test/integration/server_session_test.rb index 11ffd6d..ceba257 100644 --- a/test/integration/server_session_test.rb +++ b/test/integration/server_session_test.rb @@ -21,6 +21,11 @@ def test_database_exists_command assert @session.database_exists?(@options["database"]) refute @session.database_exists?("InvalidDatabase") end + + def test_config_get + retval = @session.config_get("network.retry") + assert retval[:value] + end def test_create_and_delete_local_database_commands database = "test_create_local_database" diff --git a/test/support/connection_helper.rb b/test/support/connection_helper.rb index c25e0f2..fc9bbb5 100644 --- a/test/support/connection_helper.rb +++ b/test/support/connection_helper.rb @@ -1,6 +1,6 @@ module ConnectionHelper def connect_to_orientdb(options) - OrientDbClient.connect(options["host"], { + OrientDbClient.connect(options["host"], { port: options["port"] }) end diff --git a/test/support/databases.yml b/test/support/databases.yml index 4e295e9..b43c2a7 100644 --- a/test/support/databases.yml +++ b/test/support/databases.yml @@ -2,7 +2,7 @@ test: host: localhost port: 2424 server_user: root - server_password: 83CACE21A23DB46F93BFD58A3CE48C8D29926C6EF424D7DA9BD725AE070CCDC0 + server_password: orient123 database: temp user: admin password: admin diff --git a/test/unit/connection_test.rb b/test/unit/connection_test.rb index 77f6046..a1f30da 100644 --- a/test/unit/connection_test.rb +++ b/test/unit/connection_test.rb @@ -81,4 +81,4 @@ def test_opening_a_database assert_instance_of OrientDbClient::DatabaseSession, session assert_equal @session, session.id end -end \ No newline at end of file +end