lib/arcade/api/operations.rb in arcadedb-0.3.3 vs lib/arcade/api/operations.rb in arcadedb-0.4

- old
+ new

@@ -1,7 +1,8 @@ module Arcade module Api + extend Primitives =begin This is a simple admin interface $ Arcade::Api.databases # returns an Array of known databases $ Arcade::Api.create_database <a string> # returns true if succesfull @@ -20,48 +21,57 @@ :limit => a number , :serializer: one of :graph, :record } =end + # ------------------------------ Service methods ------------------------------------------------- # + # ------------------------------ ------------------------------------------------- # + # ------------------------------ databases ------------------------------------------------- # + # returns an array of databases present on the database-server # def self.databases get_data 'databases' end + # ------------------------------ create database ------------------------------------------------- # + # creates a database if not present # def self.create_database name - unless databases.include?( name.to_s ) - payload = { "command" => "create database #{name}" }.to_json - post_data "server", { body: payload }.merge( auth ).merge( json ) - end - rescue QueryError => e + return if databases.include?( name.to_s ) + payload = { "command" => "create database #{name}" } + post_data "server", payload + rescue HTTPX::HTTPError => e logger.fatal "Create database #{name} through \"POST create/#{name}\" failed" logger.fatal e raise end + # ------------------------------ drop database ------------------------------------------------- # + # deletes the given database # def self.drop_database name - if databases.include?( name.to_s ) - payload = { "command" => "drop database #{name}" }.to_json - post_data "server", { body: payload }.merge( auth ).merge( json ) - end + return unless databases.include?( name.to_s ) + payload = {"command" => "drop database #{name}" } + post_data "server", payload + rescue HTTPX::HTTPError => e + logger.fatal "Drop database #{name} through \"POST drop database/#{name}\" failed" + raise end # ------------------------------ create document ------------------------------------------------- # - # adds a document to the database + # adds a document to the specified database table # # specify database-fields as hash-type parameters # # i.e Arcade::Api.create_document 'devel', 'documents', name: 'herta meyer', age: 56, sex: 'f' # # returns the rid of the inserted dataset - # + # def self.create_document database, type, **attributes - payload = { "@type" => type }.merge( attributes ).to_json + payload = { "@type" => type }.merge( attributes ) logger.debug "C: #{payload}" options = if session.nil? - { body: payload }.merge( auth ).merge( json ) + payload else - { body: payload }.merge( auth ).merge( json ).merge( headers: { "arcadedb-session-id" => session }) + payload.merge headers: { "arcadedb-session-id" => session } end post_data "document/#{database}", options end # ------------------------------ execute ------------------------------------------------- # @@ -69,36 +79,26 @@ # # the query is provided as block # # returns an Array of results (if propriate) # i.e - # Arcade::Api.execcute( "devel" ) { 'select from test ' } + # Arcade::Api.execute( "devel" ) { 'select from test ' } # =y [{"@rid"=>"#57:0", "@type"=>"test", "name"=>"Hugo"}, {"@rid"=>"#60:0", "@type"=>"test", "name"=>"Hubert"}] # - def self.execute database, query=nil + def self.execute database, query=nil, session_id= nil pl = query.nil? ? provide_payload(yield) : provide_payload(query) - options = { body: pl }.merge( auth ).merge( json ) - unless session.nil? - options = options.merge( headers: { "arcadedb-session-id" => session }) + if session_id.nil? && session.nil? + post_data "command/#{database}" , pl + else + post_transaction "command/#{database}" , pl, session_id || session end - post_data "command/#{database}" , options - rescue Arcade::QueryError => e -# puts e.methods - #puts e.exception - # puts e.full_message - if e.message =~ /retry/ - retry - else - raise e.message - end end # ------------------------------ query ------------------------------------------------- # # same for idempotent queries def self.query database, query - options = { body: provide_payload(query) }.merge( auth ).merge( json ) - post_data "query/#{database}" , options + post_data "query/#{database}" , provide_payload(query) end # ------------------------------ get_record ------------------------------------------------- # # fetches a record by providing database and rid # and returns the result as hash @@ -112,11 +112,11 @@ rid = rid.join(':') rid = rid[1..-1] if rid[0]=="#" if rid.rid? get_data "document/#{database}/#{rid}" else - raise Arcade::Error "Get requires a rid input" + raise Error "Get requires a rid input" end end # ------------------------------ property ------------------------------------------------- # # Adds properties to the type @@ -134,14 +134,15 @@ def self.property database, type, **args begin_transaction database success = args.map do | name, format | r= execute(database) {" create property #{type.to_s}.#{name.to_s} #{format.to_s} " } &.first + puts "R: #{r.inspect}" if r.nil? false else - r.keys == [ :propertyName, :typeName, :operation ] && r[:operation] == 'create property' + r[:operation] == 'create property' end end.uniq if success == [true] commit database true @@ -153,49 +154,24 @@ end # ------------------------------ index ------------------------------------------------- # def self.index database, type, name , *properties properties = properties.map( &:to_s ) - unique_requested = "unique" if properties.delete("unique") + unique_requested = "unique" if properties.delete("unique") unique_requested = "notunique" if properties.delete("notunique" ) automatic = true if properties << name if properties.empty? - # puts " create index #{type.to_s}[#{name.to_s}] on #{type} ( #{properties.join(',')} ) #{unique_requested}" + # puts " create index #{type.to_s}[#{name.to_s}] on #{type} ( #{properties.join(',')} ) #{unique_requested}" # VV 22.10: providing an index-name raises an Error ( Encountered " "(" "( "" at line 1, column 44. Was expecting one of: <EOF> <SCHEMA> ... <NULL_STRATEGY> ... ";" ... "," ... )) ) # named indices droped for now - success = execute(database) {" create index on #{type} ( #{properties.join(',')} ) #{unique_requested}" } &.first + success = execute(database) {" create index IF NOT EXISTS on #{type} (#{properties.join(', ')}) #{unique_requested}" } &.first # puts "success: #{success}" - success && success.keys == [ :totalIndexed, :name, :operation ] && success[:operation] == 'create index' + success[:operation] == 'create index' end - # ------------------------------ transaction ------------------------------------------------- # - # - def self.begin_transaction database - result = Typhoeus.post Arcade::Config.base_uri + "begin/#{database}", auth - @session_id = result.headers["arcadedb-session-id"] - - # returns the session-id - end - - - # ------------------------------ commit ------------------------------------------------- # - def self.commit database - options = auth.merge( headers: { "arcadedb-session-id" => session }) - post_data "commit/#{database}", options - @session_id = nil - end - - # ------------------------------ rollback ------------------------------------------------- # - def self.rollback database, publish_error=true - options = auth.merge( headers: { "arcadedb-session-id" => session }) - post_data "rollback/#{database}", options - @session_id = nil - raise Arcade::RollbackError "A Transaction has been rolled back" if publish_error - end - private def self.logger Database.logger end @@ -233,74 +209,49 @@ when :language if [:sql, :cypher, :gremlin, :neo4j ].include? value.to_sym [ :language, value.to_sym ] end end # case - end .to_h ).to_json # map + end .to_h ) # map end - def self.get_data command, options = auth - result = Typhoeus.get Arcade::Config.base_uri + command, options - analyse_result(result, command) - end - def self.post_data command, options = auth - # puts "Post DATA #{command} #{options}" # debug - i = 0; a="" - loop do - result = Typhoeus.post Arcade::Config.base_uri + command, options - # Code: 503 – Service Unavailable - if result.response_code.to_i == 503 # retry two times - i += 1 - raise Arcade::QueryError, JSON.parse( result.response_body, symbolize_names: true )[:result] if i > 3 - sleep 0.1 - else - a= analyse_result(result, command ) - break - end - end - a - end - - # returns the json-response + # returns the json-response ## retiered def self.analyse_result r, command if r.success? - return nil if r.response_code == 204 # no content + return nil if r.status == 204 # no content result = JSON.parse( r.response_body, symbolize_names: true )[:result] if result == [{}] [] else result end elsif r.timed_out? - raise Arcade::Error "Timeout Error", caller + raise Error "Timeout Error", caller [] elsif r.response_code > 0 logger.error "Execution Failure – Code: #{ r.response_code } – #{r.status_message} " error_message = JSON.parse( r.response_body, symbolize_names: true ) logger.error "ErrorMessage: #{ error_message[:detail]} " if error_message[:detail] =~ /Duplicated key/ - raise Arcade::IndexError, error_message[:detail] + raise IndexError, error_message[:detail] else # available fields: :detail, :exception, error puts error_message[:detail] #raise error_message[:detail], caller end end end def self.auth @a ||= { httpauth: :basic, - username: Arcade::Config.admin[:user], - password: Arcade::Config.admin[:pass] } + username: Config.admin[:user], + password: Config.admin[:pass] } end - def self.json - { headers: { "Content-Type" => "application/json"} } - end # not tested def self.delete_data command - result = Typhoeus.delete Arcade::Config.base_uri + command, auth + result = HTTPX.delete Config.base_uri + command, auth analyse_result(result, command) end end end