lib/redgraph/graph/edge_methods.rb in redgraph-0.1.3 vs lib/redgraph/graph/edge_methods.rb in redgraph-0.1.4

- old
+ new

@@ -1,20 +1,23 @@ +# frozen_string_literal: true + module Redgraph class Graph module EdgeMethods # Adds an edge. If successul it returns the created object, otherwise false # def add_edge(edge) - result = _query("MATCH (src), (dest) - WHERE ID(src) = #{edge.src.id} AND ID(dest) = #{edge.dest.id} - CREATE (src)-[e:`#{edge.type}` #{quote_hash(edge.properties)}]->(dest) RETURN ID(e)") - return false if result.stats[:relationships_created] != 1 - id = result.resultset.first["ID(e)"] - edge.id = id - edge + merge_or_add_edge(edge, :create) end + # Merges (creates an edge unless one with the same type and properties exists) an edge. + # If successul it returns the object, otherwise false + # + def merge_edge(edge) + merge_or_add_edge(edge, :merge) + end + # Finds edges. Options: # # - type # - src # - dest @@ -22,12 +25,10 @@ # - order # - limit # - skip # def edges(type: nil, src: nil, dest: nil, properties: nil, order: nil, limit: nil, skip: nil) - _type = ":`#{type}`" if type - _props = quote_hash(properties) if properties _order = if order raise MissingAliasPrefixError unless order.include?("edge.") "ORDER BY #{order}" end _limit = "LIMIT #{limit}" if limit @@ -39,11 +40,13 @@ ("ID(dest) = #{dest.id}" if dest) ].compact.join(" AND ") "WHERE #{clauses}" end - cmd = "MATCH (src)-[edge#{_type} #{_props}]->(dest) #{_where} + edge = Edge.new(type: type, src: src, dest: dest, properties: properties) + + cmd = "MATCH #{edge.to_query_string} #{_where} RETURN src, edge, dest #{_order} #{_skip} #{_limit}" result = _query(cmd) result.resultset.map do |item| src = node_from_resultset_item(item["src"]) @@ -55,24 +58,48 @@ edge end end + # Counts edges. Options: + # + # - type: filter by type + # - properties: filter by properties + # + def count_edges(type: nil, properties: nil) + edge = Edge.new(type: type, properties: properties) + + cmd = "MATCH #{edge.to_query_string} RETURN COUNT(edge)" + query(cmd).flatten[0] + end + + private def edge_from_resultset_item(item) (edge_id, type_id, _src_id, _dest_id, props) = item - attrs = {} + attrs = HashWithIndifferentAccess.new props.each do |(index, type, value)| attrs[get_property(index)] = value end Edge.new.tap do |edge| edge.id = edge_id edge.type = get_relationship_type(type_id) edge.properties = attrs end + end + + def merge_or_add_edge(edge, verb = :create) + verb = verb == :create ? "CREATE" : "MERGE" + result = _query("MATCH (src), (dest) + WHERE ID(src) = #{edge.src.id} AND ID(dest) = #{edge.dest.id} + #{verb} #{edge.to_query_string} RETURN ID(edge)") + return false if result.stats[:relationships_created] != 1 + id = result.resultset.first["ID(edge)"] + edge.id = id + edge end end end end