class OrientdbClient::Node

Attributes

database[R]
debug[W]

Public Class Methods

new(host:, port:, http_client:, client:) click to toggle source
# File lib/orientdb_client.rb, line 143
def initialize(host:, port:, http_client:, client:)
  @host = host
  @port = port
  @http_client = http_client
  @client = client
  @connected = false
  @database = nil
  @debug = false
end

Public Instance Methods

alter_property(class_name, property_name, field, value) click to toggle source
# File lib/orientdb_client.rb, line 212
def alter_property(class_name, property_name, field, value)
  command("ALTER PROPERTY #{class_name}.#{property_name} #{field} #{value}")
end
command(sql) click to toggle source
# File lib/orientdb_client.rb, line 227
def command(sql)
  r = request(:post, "command/#{@database}/sql/#{CGI::escape(sql)}")
  parse_response(r)
end
connect(database) click to toggle source
# File lib/orientdb_client.rb, line 153
def connect(database)
  request(:get, "connect/#{database}")
  @connected = true
  @database = database
  true
end
connected?() click to toggle source
# File lib/orientdb_client.rb, line 247
def connected?
  @connected == true
end
create_class(name, options) click to toggle source
# File lib/orientdb_client.rb, line 193
def create_class(name, options)
  sql = "CREATE CLASS #{name}"
  sql << " EXTENDS #{options[:extends]}" if options.key?(:extends)
  sql << " CLUSTER #{options[:cluster]}" if options.key?(:cluster)
  sql << ' ABSTRACT' if options.key?(:abstract)
  command(sql)
end
create_database(name, storage, type, options) click to toggle source
# File lib/orientdb_client.rb, line 166
def create_database(name, storage, type, options)
  r = request(:post, "database/#{name}/#{storage}/#{type}", options)
  parse_response(r)
end
create_property(class_name, property_name, type, options) click to toggle source
# File lib/orientdb_client.rb, line 205
def create_property(class_name, property_name, type, options)
  command("CREATE PROPERTY #{class_name}.#{property_name} #{type}")
  options.each do |k, v|
    alter_property(class_name, property_name, k, v)
  end
end
delete_database(name, options) click to toggle source
# File lib/orientdb_client.rb, line 171
def delete_database(name, options)
  r = request(:delete, "database/#{name}", options)
  parse_response(r)
end
disconnect() click to toggle source
# File lib/orientdb_client.rb, line 160
def disconnect
  request(:get, 'disconnect') rescue UnauthorizedError
  @connected = false
  true
end
drop_class(name) click to toggle source
# File lib/orientdb_client.rb, line 201
def drop_class(name)
  command("DROP CLASS #{name}")
end
get_class(name) click to toggle source
# File lib/orientdb_client.rb, line 232
def get_class(name)
  r = request(:get, "class/#{@database}/#{name}")
  parse_response(r)
rescue IllegalArgumentException
  raise NotFoundError
end
get_database(name, options) click to toggle source
# File lib/orientdb_client.rb, line 176
def get_database(name, options)
  r = request(:get, "database/#{name}", options)
  r = parse_response(r)
rescue UnauthorizedError => e
  # Attempt to get not-found db, when connected, will return 401 error.
  if connected?
    raise NotFoundError.new("Database #{name} not found, or you are not authorized to access it.", 401)
  else
    raise e
  end
end
has_class?(name) click to toggle source
# File lib/orientdb_client.rb, line 239
def has_class?(name)
  if get_class(name)
    return true
  end
rescue NotFoundError
  return false
end
list_databases() click to toggle source
# File lib/orientdb_client.rb, line 188
def list_databases
  r = request(:get, 'listDatabases')
  parse_response(r)['databases']
end
query(sql, options) click to toggle source
# File lib/orientdb_client.rb, line 216
def query(sql, options)
  parse_response(query_unparsed(sql, options))['result']
end
query_unparsed(sql, options) click to toggle source
# File lib/orientdb_client.rb, line 220
def query_unparsed(sql, options)
  limit = limit_string(options)
  request(:get, "query/#{@database}/sql/#{CGI::escape(sql)}#{limit}")
rescue NegativeArraySizeException
  raise NotFoundError
end

Private Instance Methods

build_url(path) click to toggle source
# File lib/orientdb_client.rb, line 268
def build_url(path)
  "http://#{@host}:#{@port}/#{path}"
end
error_handling_fallback(code, body, e = nil) click to toggle source
# File lib/orientdb_client.rb, line 378
def error_handling_fallback(code, body, e = nil)
  if (body.match(/Database.*already exists/))
    raise ConflictError.new('Database already exists', code, body)
  elsif (body.match(/NegativeArraySizeException/))
    raise NegativeArraySizeException.new(e.message, code, body)
  else
    raise ServerError.new("Unparseable Orientdb server error", code, body)
  end
end
extract_odb_error_from_json(response) click to toggle source
# File lib/orientdb_client.rb, line 366
def extract_odb_error_from_json(response)
  body = response.body
  json = Oj.load(body)
  # odb > 2.1 (?) errors are in JSON format
  matches = json['errors'].first['content'].match(/\A([^:]+):?\s?(.*)/m)
  [matches[1], matches[2]]
rescue => e
  code = response.response_code
  body = response.body
  error_handling_fallback(code, body, e)
end
extract_odb_error_from_text(response) click to toggle source
# File lib/orientdb_client.rb, line 388
def extract_odb_error_from_text(response)
  body = response.body
  matches = body.match(/\A([^:]+):\s(.*)$/)
  [matches[1], matches[2]]
rescue => e
  if (response.body.match(/Database.*already exists/))
    raise ConflictError.new('Database already exists', response.response_code, response.body)
  elsif (response.body.match(/NegativeArraySizeException/))
    raise NegativeArraySizeException.new(e.message, response.response_code, response.body)
  else
    raise OrientdbError.new("Could not parse Orientdb server error", response.response_code, response.body)
  end
end
handle_response(response) click to toggle source
# File lib/orientdb_client.rb, line 272
def handle_response(response)
  return response if @debug
  case response.response_code
  when 0
    raise ConnectionError.new("No server at #{@host}:#{@port}", 0, nil)
  when 200, 201, 204
    return response
  when 400
    translate_error(response)
  when 401
    raise UnauthorizedError.new('Unauthorized', response.response_code, response.body)
  when 404
    raise NotFoundError.new('Not found', response.response_code, response.body)
  when 409
    translate_error(response)
  when 500
    translate_error(response)
  else
    raise ServerError.new("Unexpected HTTP status code: #{response.response_code}", response.response_code, response.body)
  end
end
limit_string(options) click to toggle source
# File lib/orientdb_client.rb, line 299
def limit_string(options)
  options[:limit] ? "/#{options[:limit]}" : ''
end
parse_response(response) click to toggle source
# File lib/orientdb_client.rb, line 294
def parse_response(response)
  return nil if response.body.empty?
  @debug ? response : Oj.load(response.body)
end
request(method, path, options = {}) click to toggle source
# File lib/orientdb_client.rb, line 253
def request(method, path, options = {})
  url = build_url(path)
  request_instrumentation_hash = {method: method, url: url, options: options}
  raw_response = @client.instrument('request.orientdb_client', request_instrumentation_hash) do |payload|
    response = @http_client.request(method, url, options)
    payload[:response_code] = response.response_code
    response
  end
  response_instrumentation_hash = request_instrumentation_hash.merge(response_code: raw_response.response_code)
  processed_response = @client.instrument('process_response.orientdb_client', response_instrumentation_hash) do |payload|
    handle_response(raw_response)
  end
  processed_response
end
translate_error(response) click to toggle source
# File lib/orientdb_client.rb, line 303
def translate_error(response)
  odb_error_class, odb_error_message = if response.content_type.start_with?('application/json')
     extract_odb_error_from_json(response)
  else
    extract_odb_error_from_text(response)
  end
  code = response.response_code
  body = response.body
  case odb_error_class
  when /OCommandSQLParsingException/, "Error parsing query", "Error on parsing command"
    raise ParsingError.new("#{odb_error_class}: #{odb_error_message}", code, body)
  when /OQueryParsingException/
    raise ClientError.new("#{odb_error_class}: #{odb_error_message}", code, body)
  when /OCommandExecutorNotFoundException/
    raise ClientError.new("#{odb_error_class}: #{odb_error_message}", code, body)
  when /IllegalArgumentException/
    raise IllegalArgumentException.new("#{odb_error_class}: #{odb_error_message}", code, body)
  when /OConfigurationException/
    raise ClientError.new("#{odb_error_class}: #{odb_error_message}", code, body)
  when /OCommandExecutionException/
    raise CommandExecutionException.new("#{odb_error_class}: #{odb_error_message}", code, body)
  when /OSchemaException|OIndexException/
    raise ClientError.new("#{odb_error_class}: #{odb_error_message}", code, body)
  when /OConcurrentModification/
    raise MVCCError.new("#{odb_error_class}: #{odb_error_message}", code, body)
  when /IllegalStateException/
    raise ServerError.new("#{odb_error_class}: #{odb_error_message}", code, body)
  when /ORecordDuplicate/
    raise DuplicateRecordError.new("#{odb_error_class}: #{odb_error_message}", code, body)
  when /ODistributedException/
    if odb_error_message.match(/ORecordDuplicate/)
      raise DistributedDuplicateRecordError.new("#{odb_error_class}: #{odb_error_message}", code, body)
    else
      raise DistributedException.new("#{odb_error_class}: #{odb_error_message}", code, body)
    end
  when /OTransactionException/
    if odb_error_message.match(/ORecordDuplicate/)
      raise DistributedDuplicateRecordError.new("#{odb_error_class}: #{odb_error_message}", code, body)
    elsif odb_error_message.match(/distributed/)
      raise DistributedTransactionException.new("#{odb_error_class}: #{odb_error_message}", code, body)
    else
      raise TransactionException.new("#{odb_error_class}: #{odb_error_message}", code, body)
    end
  when /ODatabaseException/
    if odb_error_message.match(/already exists/)
      klass = ConflictError
      message = 'Database already exists'
    else
      klass = ServerError
      message = "#{odb_error_class}: #{odb_error_message}"
    end
    raise klass.new(message, code, body)
  when /ODistributedRecordLockedException/
    raise DistributedRecordLockedException.new("#{odb_error_class}: #{odb_error_message}", code, body)
  when /OSerializationException/
    raise SerializationException.new("#{odb_error_class}: #{odb_error_message}", code, body)
  when /NegativeArraySizeException/
    raise NegativeArraySizeException.new("#{odb_error_class}: #{odb_error_message}", code, body)
  else
    error_handling_fallback(code, body)
  end
end