diff --git a/lib/neography.rb b/lib/neography.rb index dafef9e..ecefbea 100644 --- a/lib/neography.rb +++ b/lib/neography.rb @@ -37,8 +37,16 @@ def find_and_require_user_defined_code require 'neography/rest/node_relationships' require 'neography/rest/node_indexes' require 'neography/rest/node_auto_indexes' +require 'neography/rest/node_traversal' +require 'neography/rest/node_paths' require 'neography/rest/relationships' require 'neography/rest/relationship_properties' +require 'neography/rest/relationship_indexes' +require 'neography/rest/relationship_auto_indexes' +require 'neography/rest/cypher' +require 'neography/rest/gremlin' +require 'neography/rest/batch' +require 'neography/rest/clean' require 'neography/connection' require 'neography/rest' diff --git a/lib/neography/rest.rb b/lib/neography/rest.rb index ccbe828..db25be4 100644 --- a/lib/neography/rest.rb +++ b/lib/neography/rest.rb @@ -9,19 +9,28 @@ class Rest attr_reader :connection - def_delegators :@connection, :configuration, - :get, :post, :put, :delete + def_delegators :@connection, :configuration def initialize(options=ENV['NEO4J_URL'] || {}) @connection = Connection.new(options) - @nodes = Nodes.new(@connection) - @node_properties = NodeProperties.new(@connection) - @node_relationships = NodeRelationships.new(@connection) - @node_indexes = NodeIndexes.new(@connection) - @node_auto_indexes = NodeAutoIndexes.new(@connection) - @relationships = Relationships.new(@connection) - @relationship_properties = RelationshipProperties.new(@connection) + @nodes = Nodes.new(@connection) + @node_properties = NodeProperties.new(@connection) + @node_relationships = NodeRelationships.new(@connection) + @node_indexes = NodeIndexes.new(@connection) + @node_auto_indexes = NodeAutoIndexes.new(@connection) + @node_traversal = NodeTraversal.new(@connection) + @node_paths = NodePaths.new(@connection) + + @relationships = Relationships.new(@connection) + @relationship_properties = RelationshipProperties.new(@connection) + @relationship_indexes = RelationshipIndexes.new(@connection) + @relationship_auto_indexes = RelationshipAutoIndexes.new(@connection) + + @cypher = Cypher.new(@connection) + @gremlin = Gremlin.new(@connection) + @batch = Batch.new(@connection) + @clean = Clean.new(@connection) end def get_root @@ -40,13 +49,6 @@ def create_nodes_threaded(nodes) @nodes.create_multiple_threaded(nodes) end - # This is not yet implemented in the REST API - # - # def get_all_node - # puts "get all nodes" - # get("/nodes/") - # end - # nodes def get_node(id) @@ -57,13 +59,23 @@ def get_nodes(*nodes) @nodes.get_each(*nodes) end + # This is not yet implemented in the REST API + # + # def get_all_node + # puts "get all nodes" + # get("/nodes/") + # end + def delete_node(id) @nodes.delete(id) end def delete_node!(id) relationships = get_node_relationships(get_id(id)) - relationships.each { |r| delete_relationship(r["self"].split('/').last) } unless relationships.nil? + relationships.each do |relationship| + delete_relationship(relationship["self"].split('/').last) + end unless relationships.nil? + delete_node(id) end @@ -147,33 +159,32 @@ def create_node_auto_index(type = "exact", provider = "lucene") end def add_node_to_index(index, key, value, id) - @node_indexes.add_node(index, key, value, id) + @node_indexes.add(index, key, value, id) end alias_method :add_to_index, :add_node_to_index def create_unique_node(index, key, value, props={}) - @node_indexes.create_unique_node(index, key, value, props) + @node_indexes.create_unique(index, key, value, props) end def remove_node_from_index(*args) case args.size - when 4 then @node_indexes.remove_node_by_value(args[0], args[3], args[1], args[2]) - when 3 then @node_indexes.remove_node_by_key(args[0], args[2], args[1]) - when 2 then @node_indexes.remove_node(args[0], args[1]) + when 4 then @node_indexes.remove_by_value(args[0], args[3], args[1], args[2]) + when 3 then @node_indexes.remove_by_key(args[0], args[2], args[1]) + when 2 then @node_indexes.remove(args[0], args[1]) end end alias_method :remove_from_index, :remove_node_from_index - def get_node_index(index, key, value) - @node_indexes.get_node(index, key, value) + @node_indexes.get(index, key, value) end alias_method :get_index, :get_node_index def find_node_index(*args) case args.size - when 3 then index = @node_indexes.find_node_by_value(args[0], args[1], args[2]) - when 2 then index = @node_indexes.find_node_by_query(args[0], args[1]) + when 3 then index = @node_indexes.find_by_value(args[0], args[1], args[2]) + when 2 then index = @node_indexes.find_by_query(args[0], args[1]) end return nil if index.empty? index @@ -214,294 +225,138 @@ def remove_node_auto_index_property(property) @node_auto_indexes.remove_property(property) end - # relationship indexes + # relationship indexes - def create_unique_relationship(index, key, value, type, from, to) - body = {:key=>key,:value=>value, :type => type } - body[:start] = self.configuration + "/node/#{get_id(from)}" - body[:end] = self.configuration + "/node/#{get_id(to)}" - options = { :body => body.to_json, :headers => {'Content-Type' => 'application/json'} } - post("/index/relationship/#{index}?unique", options) - end + def list_relationship_indexes + @relationship_indexes.list + end - def list_relationship_indexes - get("/index/relationship") - end + def create_relationship_index(name, type = "exact", provider = "lucene") + @relationship_indexes.create(name, type, provider) + end - def create_relationship_index(name, type = "exact", provider = "lucene") - options = { :body => ({:name => name, :config => {:type => type, :provider => provider}}).to_json, :headers => {'Content-Type' => 'application/json'} } - post("/index/relationship", options) - end + def create_relationship_auto_index(type = "exact", provider = "lucene") + @relationship_indexes.create_auto(type, provider) + end - def create_relationship_auto_index(type = "exact", provider = "lucene") - create_relationship_index("relationship_auto_index", type, provider) - end + def create_unique_relationship(index, key, value, type, from, to) + @relationship_indexes.create_unique(index, key, value, type, from, to) + end - def add_relationship_to_index(index, key, value, id) - options = { :body => ({:uri => self.configuration + "/relationship/#{get_id(id)}", :key => key, :value => value}).to_json, :headers => {'Content-Type' => 'application/json'} } - post("/index/relationship/#{index}", options) - end + def add_relationship_to_index(index, key, value, id) + @relationship_indexes.add(index, key, value, id) + end - def remove_relationship_from_index(*args) - case args.size - when 4 then delete("/index/relationship/#{args[0]}/#{args[1]}/#{args[2]}/#{get_id(args[3])}") - when 3 then delete("/index/relationship/#{args[0]}/#{args[1]}/#{get_id(args[2])}") - when 2 then delete("/index/relationship/#{args[0]}/#{get_id(args[1])}") - end + def remove_relationship_from_index(*args) + case args.size + when 4 then @relationship_indexes.remove_by_value(args[0], get_id(args[3]), args[1], args[2]) + when 3 then @relationship_indexes.remove_by_key(args[0], get_id(args[2]), args[1]) + when 2 then @relationship_indexes.remove(args[0], get_id(args[1])) end + end - def get_relationship_index(index, key, value) - index = get("/index/relationship/#{index}/#{key}/#{value}") || Array.new - return nil if index.empty? - index - end + def get_relationship_index(index, key, value) + @relationship_indexes.get(index, key, value) + end - def find_relationship_index(*args) - case args.size - when 3 then index = get("/index/relationship/#{args[0]}/#{args[1]}?query=#{args[2]}") || Array.new - when 2 then index = get("/index/relationship/#{args[0]}?query=#{args[1]}") || Array.new - end - return nil if index.empty? - index + def find_relationship_index(*args) + case args.size + when 3 then index = @relationship_indexes.find_by_key_query(args[0], args[1], args[2]) + when 2 then index = @relationship_indexes.find_by_query(args[0], args[1]) end + return nil if index.empty? + index + end - # relationship auto indexes - - def get_relationship_auto_index(key, value) - index = get("/index/auto/relationship/#{key}/#{value}") || Array.new - return nil if index.empty? - index - end + # relationship auto indexes - def find_relationship_auto_index(*args) - case args.size - when 2 then index = get("/index/auto/relationship/#{args[0]}/#{args[1]}") || Array.new - when 1 then index = get("/index/auto/relationship/?query=#{args[0]}") || Array.new - end - return nil if index.empty? - index - end - - def get_relationship_auto_index_status - get("/index/auto/relationship/status") - end + def get_relationship_auto_index(key, value) + @relationship_auto_indexes.get(key, value) + end - def set_relationship_auto_index_status(change_to = true) - options = { :body => change_to.to_json, :headers => {'Content-Type' => 'application/json'} } - put("/index/auto/relationship/status", options) + def find_relationship_auto_index(*args) + case args.size + when 2 then index = @relationship_auto_indexes.find(args[0], args[1]) + when 1 then index = @relationship_auto_indexes.query(args[0]) end + return nil if index.empty? + index + end - def get_relationship_auto_index_properties - get("/index/auto/relationship/properties") - end + def get_relationship_auto_index_status + @relationship_auto_indexes.status + end - def add_relationship_auto_index_property(property) - options = { :body => property, :headers => {'Content-Type' => 'application/json'} } - post("/index/auto/relationship/properties", options) - end + def set_relationship_auto_index_status(change_to = true) + @relationship_auto_indexes.status = change_to + end - def remove_relationship_auto_index_property(property) - delete("/index/auto/relationship/properties/#{property}") - end + def get_relationship_auto_index_properties + @relationship_auto_indexes.properties + end - # traversal + def add_relationship_auto_index_property(property) + @relationship_auto_indexes.add_property(property) + end - def traverse(id, return_type, description) - options = { :body => {"order" => get_order(description["order"]), - "uniqueness" => get_uniqueness(description["uniqueness"]), - "relationships" => description["relationships"], - "prune_evaluator" => description["prune evaluator"], - "return_filter" => description["return filter"], - "max_depth" => get_depth(description["depth"]), }.to_json, :headers => {'Content-Type' => 'application/json'} } - traversal = post("/node/#{get_id(id)}/traverse/#{get_type(return_type)}", options) || Array.new - end + def remove_relationship_auto_index_property(property) + @relationship_auto_indexes.remove_property(property) + end - # paths + # traversal - def get_path(from, to, relationships, depth=1, algorithm="shortestPath") - options = { :body => {"to" => self.configuration + "/node/#{get_id(to)}", "relationships" => relationships, "max_depth" => depth, "algorithm" => get_algorithm(algorithm) }.to_json, :headers => {'Content-Type' => 'application/json'} } - path = post("/node/#{get_id(from)}/path", options) || Hash.new - end + def traverse(id, return_type, description) + @node_traversal.traverse(id, return_type, description) + end - def get_paths(from, to, relationships, depth=1, algorithm="allPaths") - options = { :body => {"to" => self.configuration + "/node/#{get_id(to)}", "relationships" => relationships, "max_depth" => depth, "algorithm" => get_algorithm(algorithm) }.to_json, :headers => {'Content-Type' => 'application/json'} } - paths = post("/node/#{get_id(from)}/paths", options) || Array.new - end - - def get_shortest_weighted_path(from, to, relationships, weight_attr='weight', depth=1, algorithm="dijkstra") - options = { :body => {"to" => self.configuration + "/node/#{get_id(to)}", "relationships" => relationships, "cost_property" => weight_attr, "max_depth" => depth, "algorithm" => get_algorithm(algorithm) }.to_json, :headers => {'Content-Type' => 'application/json'} } - paths = post("/node/#{get_id(from)}/paths", options) || Hash.new - end + # paths - # query + def get_path(from, to, relationships, depth = 1, algorithm = "shortestPath") + @node_paths.get(from, to, relationships, depth, algorithm) + end - def execute_query(query, params = {}) - options = { :body => {:query => query, :params => params}.to_json, :headers => {'Content-Type' => 'application/json', 'Accept' => 'application/json;stream=true'} } - result = post(@connection.cypher_path, options) - end + def get_paths(from, to, relationships, depth = 1, algorithm = "allPaths") + @node_paths.get_all(from, to, relationships, depth, algorithm) + end - # script - - def execute_script(script, params = {}) - options = { :body => {:script => script, :params => params}.to_json , :headers => {'Content-Type' => 'application/json'} } - result = post(@connection.gremlin_path, options) - result == "null" ? nil : result - end + def get_shortest_weighted_path(from, to, relationships, weight_attr = "weight", depth = 1, algorithm = "dijkstra") + @node_paths.shortest_weighted(from, to, relationships, weight_attr, depth, algorithm) + end - # batch + # cypher query - def batch(*args) - batch = [] - Array(args).each_with_index do |c,i| - batch << {:id => i}.merge(get_batch(c)) - end - options = { :body => batch.to_json, :headers => {'Content-Type' => 'application/json', 'Accept' => 'application/json;stream=true'} } - post("/batch", options) - end - - def batch_not_streaming(*args) - batch = [] - Array(args).each_with_index do |c,i| - batch << {:id => i}.merge(get_batch(c)) - end - options = { :body => batch.to_json, :headers => {'Content-Type' => 'application/json'} } - post("/batch", options) - end - - def get_batch(args) - case args[0] - when :get_node - {:method => "GET", :to => "/node/#{get_id(args[1])}"} - when :create_node - {:method => "POST", :to => "/node/", :body => args[1]} - when :create_unique_node - {:method => "POST", :to => "/index/node/#{args[1]}?unique", :body => {:key => args[2], :value => args[3], :properties => args[4]}} - when :set_node_property - {:method => "PUT", :to => "/node/#{get_id(args[1])}/properties/#{args[2].keys.first}", :body => args[2].values.first} - when :reset_node_properties - {:method => "PUT", :to => "/node/#{get_id(args[1])}/properties", :body => args[2]} - when :get_relationship - {:method => "GET", :to => "/relationship/#{get_id(args[1])}"} - when :create_relationship - {:method => "POST", :to => (args[2].is_a?(String) && args[2].start_with?("{") ? "" : "/node/") + "#{get_id(args[2])}/relationships", :body => {:to => (args[3].is_a?(String) && args[3].start_with?("{") ? "" : "/node/") + "#{get_id(args[3])}", :type => args[1], :data => args[4] } } - when :create_unique_relationship - {:method => "POST", :to => "/index/relationship/#{args[1]}?unique", :body => {:key => args[2], :value => args[3], :type => args[4], :start => (args[5].is_a?(String) && args[5].start_with?("{") ? "" : "/node/") + "#{get_id(args[5])}", :end=> (args[6].is_a?(String) && args[6].start_with?("{") ? "" : "/node/") + "#{get_id(args[6])}"} } - when :delete_relationship - {:method => "DELETE", :to => "/relationship/#{get_id(args[1])}"} - when :set_relationship_property - {:method => "PUT", :to => "/relationship/#{get_id(args[1])}/properties/#{args[2].keys.first}", :body => args[2].values.first} - when :reset_relationship_properties - {:method => "PUT", :to => (args[1].is_a?(String) && args[1].start_with?("{") ? "" : "/relationship/") + "#{get_id(args[1])}/properties", :body => args[2]} - when :add_node_to_index - {:method => "POST", :to => "/index/node/#{args[1]}", :body => {:uri => (args[4].is_a?(String) && args[4].start_with?("{") ? "" : "/node/") + "#{get_id(args[4])}", :key => args[2], :value => args[3] } } - when :add_relationship_to_index - {:method => "POST", :to => "/index/relationship/#{args[1]}", :body => {:uri => (args[4].is_a?(String) && args[4].start_with?("{") ? "" : "/relationship/") + "#{get_id(args[4])}", :key => args[2], :value => args[3] } } - when :get_node_index - {:method => "GET", :to => "/index/node/#{args[1]}/#{args[2]}/#{args[3]}"} - when :get_relationship_index - {:method => "GET", :to => "/index/relationship/#{args[1]}/#{args[2]}/#{args[3]}"} - when :get_node_relationships - {:method => "GET", :to => "/node/#{get_id(args[1])}/relationships/#{args[2] || 'all'}"} - when :execute_script - {:method => "POST", :to => @connection.gremlin_path, :body => {:script => args[1], :params => args[2]}} - when :execute_query - if args[2] - {:method => "POST", :to => @connection.cypher_path, :body => {:query => args[1], :params => args[2]}} - else - {:method => "POST", :to => @connection.cypher_path, :body => {:query => args[1]}} - end - when :remove_node_from_index - case args.size - when 5 then {:method => "DELETE", :to => "/index/node/#{args[1]}/#{args[2]}/#{args[3]}/#{get_id(args[4])}" } - when 4 then {:method => "DELETE", :to => "/index/node/#{args[1]}/#{args[2]}/#{get_id(args[3])}" } - when 3 then {:method => "DELETE", :to => "/index/node/#{args[1]}/#{get_id(args[2])}" } - end - when :remove_relationship_from_index - case args.size - when 5 then {:method => "DELETE", :to => "/index/relationship/#{args[1]}/#{args[2]}/#{args[3]}/#{get_id(args[4])}" } - when 4 then {:method => "DELETE", :to => "/index/relationship/#{args[1]}/#{args[2]}/#{get_id(args[3])}" } - when 3 then {:method => "DELETE", :to => "/index/relationship/#{args[1]}/#{get_id(args[2])}" } - end - when :delete_node - {:method => "DELETE", :to => "/node/#{get_id(args[1])}"} - else - raise "Unknown option #{args[0]}" - end - end + def execute_query(query, params = {}) + @cypher.query(query, params) + end - # delete - - # For testing (use a separate neo4j instance) - # call this before each test or spec - def clean_database(sanity_check = "not_really") - if sanity_check == "yes_i_really_want_to_clean_the_database" - delete("/cleandb/secret-key") - true - else - false - end - end + # gremlin script + def execute_script(script, params = {}) + @gremlin.execute(script, params) + end - def get_algorithm(algorithm) - case algorithm - when :shortest, "shortest", :shortestPath, "shortestPath", :short, "short" - "shortestPath" - when :allSimplePaths, "allSimplePaths", :simple, "simple" - "allSimplePaths" - when :dijkstra, "dijkstra" - "dijkstra" - else - "allPaths" - end - end + # batch - def get_order(order) - case order - when :breadth, "breadth", "breadth first", "breadthFirst", :wide, "wide" - "breadth first" - else - "depth first" - end - end + def batch(*args) + @batch.execute(*args) + end - def get_type(type) - case type - when :relationship, "relationship", :relationships, "relationships" - "relationship" - when :path, "path", :paths, "paths" - "path" - when :fullpath, "fullpath", :fullpaths, "fullpaths" - "fullpath" - else - "node" - end - end + def batch_not_streaming(*args) + @batch.not_streaming(*args) + end - def get_uniqueness(uniqueness) - case uniqueness - when :nodeglobal, "node global", "nodeglobal", "node_global" - "node global" - when :nodepath, "node path", "nodepath", "node_path" - "node path" - when :noderecent, "node recent", "noderecent", "node_recent" - "node recent" - when :relationshipglobal, "relationship global", "relationshipglobal", "relationship_global" - "relationship global" - when :relationshippath, "relationship path", "relationshippath", "relationship_path" - "relationship path" - when :relationshiprecent, "relationship recent", "relationshiprecent", "relationship_recent" - "relationship recent" - else - "none" - end - end + # clean database - def get_depth(depth) - return nil if depth.nil? - return 1 if depth.to_i == 0 - depth.to_i + # For testing (use a separate neo4j instance) + # call this before each test or spec + def clean_database(sanity_check = "not_really") + if sanity_check == "yes_i_really_want_to_clean_the_database" + @clean.execute + true + else + false end + end end end diff --git a/lib/neography/rest/batch.rb b/lib/neography/rest/batch.rb new file mode 100644 index 0000000..6aec6c9 --- /dev/null +++ b/lib/neography/rest/batch.rb @@ -0,0 +1,99 @@ +module Neography + class Rest + class Batch + include Neography::Rest::Paths + include Neography::Rest::Helpers + + add_path :batch_path, "/batch" + + def initialize(connection) + @connection = connection + end + + def execute(*args) + batch({'Accept' => 'application/json;stream=true'}, *args) + end + + def not_streaming(*args) + batch({}, *args) + end + + private + + def batch(accept_header, *args) + batch = [] + Array(args).each_with_index do |c,i| + batch << {:id => i }.merge(get_batch(c)) + end + options = { + :body => batch.to_json, + :headers => json_content_type.merge(accept_header) + } + + @connection.post(batch_path, options) + end + + def get_batch(args) + case args[0] + when :get_node + {:method => "GET", :to => "/node/#{get_id(args[1])}"} + when :create_node + {:method => "POST", :to => "/node/", :body => args[1]} + when :create_unique_node + {:method => "POST", :to => "/index/node/#{args[1]}?unique", :body => {:key => args[2], :value => args[3], :properties => args[4]}} + when :set_node_property + {:method => "PUT", :to => "/node/#{get_id(args[1])}/properties/#{args[2].keys.first}", :body => args[2].values.first} + when :reset_node_properties + {:method => "PUT", :to => "/node/#{get_id(args[1])}/properties", :body => args[2]} + when :get_relationship + {:method => "GET", :to => "/relationship/#{get_id(args[1])}"} + when :create_relationship + {:method => "POST", :to => (args[2].is_a?(String) && args[2].start_with?("{") ? "" : "/node/") + "#{get_id(args[2])}/relationships", :body => {:to => (args[3].is_a?(String) && args[3].start_with?("{") ? "" : "/node/") + "#{get_id(args[3])}", :type => args[1], :data => args[4] } } + when :create_unique_relationship + {:method => "POST", :to => "/index/relationship/#{args[1]}?unique", :body => {:key => args[2], :value => args[3], :type => args[4], :start => (args[5].is_a?(String) && args[5].start_with?("{") ? "" : "/node/") + "#{get_id(args[5])}", :end=> (args[6].is_a?(String) && args[6].start_with?("{") ? "" : "/node/") + "#{get_id(args[6])}"} } + when :delete_relationship + {:method => "DELETE", :to => "/relationship/#{get_id(args[1])}"} + when :set_relationship_property + {:method => "PUT", :to => "/relationship/#{get_id(args[1])}/properties/#{args[2].keys.first}", :body => args[2].values.first} + when :reset_relationship_properties + {:method => "PUT", :to => (args[1].is_a?(String) && args[1].start_with?("{") ? "" : "/relationship/") + "#{get_id(args[1])}/properties", :body => args[2]} + when :add_node_to_index + {:method => "POST", :to => "/index/node/#{args[1]}", :body => {:uri => (args[4].is_a?(String) && args[4].start_with?("{") ? "" : "/node/") + "#{get_id(args[4])}", :key => args[2], :value => args[3] } } + when :add_relationship_to_index + {:method => "POST", :to => "/index/relationship/#{args[1]}", :body => {:uri => (args[4].is_a?(String) && args[4].start_with?("{") ? "" : "/relationship/") + "#{get_id(args[4])}", :key => args[2], :value => args[3] } } + when :get_node_index + {:method => "GET", :to => "/index/node/#{args[1]}/#{args[2]}/#{args[3]}"} + when :get_relationship_index + {:method => "GET", :to => "/index/relationship/#{args[1]}/#{args[2]}/#{args[3]}"} + when :get_node_relationships + {:method => "GET", :to => "/node/#{get_id(args[1])}/relationships/#{args[2] || 'all'}"} + when :execute_script + {:method => "POST", :to => @connection.gremlin_path, :body => {:script => args[1], :params => args[2]}} + when :execute_query + if args[2] + {:method => "POST", :to => @connection.cypher_path, :body => {:query => args[1], :params => args[2]}} + else + {:method => "POST", :to => @connection.cypher_path, :body => {:query => args[1]}} + end + when :remove_node_from_index + case args.size + when 5 then {:method => "DELETE", :to => "/index/node/#{args[1]}/#{args[2]}/#{args[3]}/#{get_id(args[4])}" } + when 4 then {:method => "DELETE", :to => "/index/node/#{args[1]}/#{args[2]}/#{get_id(args[3])}" } + when 3 then {:method => "DELETE", :to => "/index/node/#{args[1]}/#{get_id(args[2])}" } + end + when :remove_relationship_from_index + case args.size + when 5 then {:method => "DELETE", :to => "/index/relationship/#{args[1]}/#{args[2]}/#{args[3]}/#{get_id(args[4])}" } + when 4 then {:method => "DELETE", :to => "/index/relationship/#{args[1]}/#{args[2]}/#{get_id(args[3])}" } + when 3 then {:method => "DELETE", :to => "/index/relationship/#{args[1]}/#{get_id(args[2])}" } + end + when :delete_node + {:method => "DELETE", :to => "/node/#{get_id(args[1])}"} + else + raise "Unknown option #{args[0]}" + end + end + + end + end +end diff --git a/lib/neography/rest/clean.rb b/lib/neography/rest/clean.rb new file mode 100644 index 0000000..ca16fc3 --- /dev/null +++ b/lib/neography/rest/clean.rb @@ -0,0 +1,20 @@ +module Neography + class Rest + class Clean + include Neography::Rest::Paths + include Neography::Rest::Helpers + + add_path :clean, "/cleandb/secret-key" + + def initialize(connection) + @connection = connection + end + + + def execute + @connection.delete(clean) + end + + end + end +end diff --git a/lib/neography/rest/cypher.rb b/lib/neography/rest/cypher.rb new file mode 100644 index 0000000..c959295 --- /dev/null +++ b/lib/neography/rest/cypher.rb @@ -0,0 +1,24 @@ +module Neography + class Rest + class Cypher + include Neography::Rest::Helpers + + def initialize(connection) + @connection = connection + end + + def query(query, parameters) + options = { + :body => { + :query => query, + :params => parameters + }.to_json, + :headers => json_content_type.merge({'Accept' => 'application/json;stream=true'}) + } + + @connection.post(@connection.cypher_path, options) + end + + end + end +end diff --git a/lib/neography/rest/gremlin.rb b/lib/neography/rest/gremlin.rb new file mode 100644 index 0000000..d109123 --- /dev/null +++ b/lib/neography/rest/gremlin.rb @@ -0,0 +1,24 @@ +module Neography + class Rest + class Gremlin + include Neography::Rest::Helpers + + def initialize(connection) + @connection = connection + end + + def execute(script, parameters) + options = { + :body => { + :script => script, + :params => parameters, + }.to_json, + :headers => json_content_type + } + result = @connection.post(@connection.gremlin_path, options) + result == "null" ? nil : result + end + + end + end +end diff --git a/lib/neography/rest/node_indexes.rb b/lib/neography/rest/node_indexes.rb index 0ce4d82..83ff40d 100644 --- a/lib/neography/rest/node_indexes.rb +++ b/lib/neography/rest/node_indexes.rb @@ -42,7 +42,7 @@ def create_auto(type, provider) create("node_auto_index", type, provider) end - def create_unique_node(index, key, value, props) + def create_unique(index, key, value, props) options = { :body => ( { :properties => props, @@ -55,7 +55,7 @@ def create_unique_node(index, key, value, props) @connection.post(unique(:index => index), options) end - def add_node(index, key, value, id) + def add(index, key, value, id) options = { :body => ( { :uri => @connection.configuration + "/node/#{get_id(id)}", @@ -68,30 +68,30 @@ def add_node(index, key, value, id) @connection.post(base(:index => index), options) end - def get_node(index, key, value) + def get(index, key, value) index = @connection.get(key_value(:index => index, :key => key, :value => value)) || Array.new return nil if index.empty? index end # TODO FIX BUG %20 - def find_node_by_value(index, key, value) + def find_by_value(index, key, value) @connection.get(key_value2(:index => index, :key => key, :value => value)) || Array.new end - def find_node_by_query(index, query) + def find_by_query(index, query) @connection.get(query(:index => index, :query => query)) || Array.new end - def remove_node(index, id) + def remove(index, id) @connection.delete(node(:index => index, :id => get_id(id))) end - def remove_node_by_key(index, id, key) + def remove_by_key(index, id, key) @connection.delete(key(:index => index, :id => get_id(id), :key => key)) end - def remove_node_by_value(index, id, key, value) + def remove_by_value(index, id, key, value) @connection.delete(value(:index => index, :id => get_id(id), :key => key, :value => value)) end diff --git a/lib/neography/rest/node_paths.rb b/lib/neography/rest/node_paths.rb new file mode 100644 index 0000000..9f2dee5 --- /dev/null +++ b/lib/neography/rest/node_paths.rb @@ -0,0 +1,68 @@ +module Neography + class Rest + class NodePaths + include Neography::Rest::Paths + include Neography::Rest::Helpers + + add_path :base, "/node/:id/path" + add_path :all, "/node/:id/paths" + + def initialize(connection) + @connection = connection + end + + def get(from, to, relationships, depth, algorithm) + options = { :body => { + "to" => @connection.configuration + "/node/#{get_id(to)}", + "relationships" => relationships, + "max_depth" => depth, + "algorithm" => get_algorithm(algorithm) + }.to_json, + :headers => json_content_type + } + @connection.post(base(:id => get_id(from)), options) || Hash.new + end + + def get_all(from, to, relationships, depth, algorithm) + options = { :body => { + "to" => @connection.configuration + "/node/#{get_id(to)}", + "relationships" => relationships, + "max_depth" => depth, + "algorithm" => get_algorithm(algorithm) + }.to_json, + :headers => json_content_type + } + @connection.post(all(:id => get_id(from)), options) || Array.new + end + + def shortest_weighted(from, to, relationships, weight_attribute, depth, algorithm) + options = { :body => { + "to" => @connection.configuration + "/node/#{get_id(to)}", + "relationships" => relationships, + "cost_property" => weight_attribute, + "max_depth" => depth, + "algorithm" => get_algorithm(algorithm) + }.to_json, + :headers => json_content_type + } + @connection.post(all(:id => get_id(from)), options) || Hash.new + end + + private + + def get_algorithm(algorithm) + case algorithm + when :shortest, "shortest", :shortestPath, "shortestPath", :short, "short" + "shortestPath" + when :allSimplePaths, "allSimplePaths", :simple, "simple" + "allSimplePaths" + when :dijkstra, "dijkstra" + "dijkstra" + else + "allPaths" + end + end + + end + end +end diff --git a/lib/neography/rest/node_traversal.rb b/lib/neography/rest/node_traversal.rb new file mode 100644 index 0000000..fe3c542 --- /dev/null +++ b/lib/neography/rest/node_traversal.rb @@ -0,0 +1,81 @@ +module Neography + class Rest + class NodeTraversal + include Neography::Rest::Paths + include Neography::Rest::Helpers + + add_path :traversal, "/node/:id/traverse/:type" + + def initialize(connection) + @connection = connection + end + + def traverse(id, return_type, description) + options = { :body => { + "order" => get_order(description["order"]), + "uniqueness" => get_uniqueness(description["uniqueness"]), + "relationships" => description["relationships"], + "prune_evaluator" => description["prune evaluator"], + "return_filter" => description["return filter"], + "max_depth" => get_depth(description["depth"]) + }.to_json, + :headers => json_content_type + } + + type = get_type(return_type) + + @connection.post(traversal(:id => get_id(id), :type => type), options) || Array.new + end + + private + + def get_order(order) + case order + when :breadth, "breadth", "breadth first", "breadthFirst", :wide, "wide" + "breadth first" + else + "depth first" + end + end + + def get_uniqueness(uniqueness) + case uniqueness + when :nodeglobal, "node global", "nodeglobal", "node_global" + "node global" + when :nodepath, "node path", "nodepath", "node_path" + "node path" + when :noderecent, "node recent", "noderecent", "node_recent" + "node recent" + when :relationshipglobal, "relationship global", "relationshipglobal", "relationship_global" + "relationship global" + when :relationshippath, "relationship path", "relationshippath", "relationship_path" + "relationship path" + when :relationshiprecent, "relationship recent", "relationshiprecent", "relationship_recent" + "relationship recent" + else + "none" + end + end + + def get_depth(depth) + return nil if depth.nil? + return 1 if depth.to_i == 0 + depth.to_i + end + + def get_type(type) + case type + when :relationship, "relationship", :relationships, "relationships" + "relationship" + when :path, "path", :paths, "paths" + "path" + when :fullpath, "fullpath", :fullpaths, "fullpaths" + "fullpath" + else + "node" + end + end + + end + end +end diff --git a/lib/neography/rest/relationship_auto_indexes.rb b/lib/neography/rest/relationship_auto_indexes.rb new file mode 100644 index 0000000..c4d55c2 --- /dev/null +++ b/lib/neography/rest/relationship_auto_indexes.rb @@ -0,0 +1,61 @@ +module Neography + class Rest + class RelationshipAutoIndexes + include Neography::Rest::Paths + include Neography::Rest::Helpers + + add_path :key_value, "/index/auto/relationship/:key/:value" + add_path :query_index, "/index/auto/relationship/?query=:query" + add_path :index_status, "/index/auto/relationship/status" + add_path :index_properties, "/index/auto/relationship/properties" + add_path :index_property, "/index/auto/relationship/properties/:property" + + def initialize(connection) + @connection = connection + end + + def get(key, value) + index = @connection.get(key_value(:key => key, :value => value)) || Array.new + return nil if index.empty? + index + end + + def find(key, value) + @connection.get(key_value(:key => key, :value => value)) || Array.new + end + + def query(query_expression) + @connection.get(query_index(:query => query_expression)) || Array.new + end + + def status + @connection.get(index_status) + end + + def status=(value) + options = { + :body => value.to_json, + :headers => json_content_type + } + @connection.put(index_status, options) + end + + def properties + @connection.get(index_properties) + end + + def add_property(property) + options = { + :body => property, + :headers => json_content_type + } + @connection.post(index_properties, options) + end + + def remove_property(property) + @connection.delete(index_property(:property => property)) + end + + end + end +end diff --git a/lib/neography/rest/relationship_indexes.rb b/lib/neography/rest/relationship_indexes.rb new file mode 100644 index 0000000..58bd798 --- /dev/null +++ b/lib/neography/rest/relationship_indexes.rb @@ -0,0 +1,101 @@ +module Neography + class Rest + class RelationshipIndexes + include Neography::Rest::Paths + include Neography::Rest::Helpers + + add_path :all, "/index/relationship" + add_path :base, "/index/relationship/:index" + add_path :unique, "/index/relationship/:index?unique" + + add_path :relationship, "/index/relationship/:index/:id" + add_path :key, "/index/relationship/:index/:key/:id" + add_path :value, "/index/relationship/:index/:key/:value/:id" + add_path :key_value, "/index/relationship/:index/:key/:value" + + add_path :key_query, "/index/relationship/:index/:key?query=:query" + add_path :query, "/index/relationship/:index?query=:query" + + def initialize(connection) + @connection = connection + end + + def list + @connection.get(all) + end + + def create(name, type, provider) + options = { + :body => ( + { :name => name, + :config => { + :type => type, + :provider => provider + } + } + ).to_json, + :headers => json_content_type + } + @connection.post(all, options) + end + + def create_auto(type, provider) + create("relationship_auto_index", type, provider) + end + + def create_unique(index, key, value, type, from, to) + body = { + :key => key, + :value => value, + :type => type, + :start => @connection.configuration + "/node/#{get_id(from)}", + :end => @connection.configuration + "/node/#{get_id(to)}" + } + options = { :body => body.to_json, :headers => json_content_type } + + @connection.post(unique(:index => index), options) + end + + def add(index, key, value, id) + options = { + :body => ( + { :uri => @connection.configuration + "/relationship/#{get_id(id)}", + :key => key, + :value => value + } + ).to_json, + :headers => json_content_type + } + + @connection.post(base(:index => index), options) + end + + def get(index, key, value) + index = @connection.get(key_value(:index => index, :key => key, :value => value)) || Array.new + return nil if index.empty? + index + end + + def find_by_key_query(index, key, query) + @connection.get(key_query(:index => index, :key => key, :query => query)) || Array.new + end + + def find_by_query(index, query) + @connection.get(query(:index => index, :query => query)) || Array.new + end + + def remove(index, id) + @connection.delete(relationship(:index => index, :id => get_id(id))) + end + + def remove_by_key(index, id, key) + @connection.delete(key(:index => index, :id => get_id(id), :key => key)) + end + + def remove_by_value(index, id, key, value) + @connection.delete(value(:index => index, :id => get_id(id), :key => key, :value => value)) + end + + end + end +end