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

- old
+ new

@@ -1,18 +1,23 @@ +# frozen_string_literal: true + module Redgraph class Graph module NodeMethods # Adds a node. If successul it returns the created object, otherwise false # def add_node(node) - result = _query("CREATE (n:`#{node.label}` #{quote_hash(node.properties)}) RETURN ID(n)") - return false if result.stats[:nodes_created] != 1 - id = result.resultset.first["ID(n)"] - node.id = id - node + merge_or_add_node(node, :create) end + # Merges (creates a node unless one with the same label and properties exists). If successul + # it returns the object, otherwise false + # + def merge_node(node) + merge_or_add_node(node, :merge) + end + def find_node_by_id(id) result = _query("MATCH (node) WHERE ID(node) = #{id} RETURN node") return nil if result.resultset.empty? (node_id, labels, properties) = result.resultset.first["node"] attrs = {} @@ -34,20 +39,21 @@ # - limit: number of items # - skip: items offset (useful for pagination) # def nodes(label: nil, properties: nil, order: nil, limit: nil, skip: nil) _label = ":`#{label}`" if label - _props = quote_hash(properties) if properties _order = if order raise MissingAliasPrefixError unless order.include?("node.") "ORDER BY #{order}" end _limit = "LIMIT #{limit}" if limit _skip = "SKIP #{skip}" if skip - cmd = "MATCH (node#{_label} #{_props}) RETURN node #{_order} #{_skip} #{_limit}" + node = Node.new(label: label, properties: properties) + cmd = "MATCH #{node.to_query_string} RETURN node #{_order} #{_skip} #{_limit}" + result = _query(cmd) result.resultset.map do |item| node_from_resultset_item(item["node"]) end @@ -57,30 +63,40 @@ # # - label: filter by label # - properties: filter by properties # def count_nodes(label: nil, properties: nil) - _label = ":`#{label}`" if label - _props = quote_hash(properties) if properties + node = Node.new(label: label, properties: properties) - cmd = "MATCH (node#{_label} #{_props}) RETURN COUNT(node)" + cmd = "MATCH #{node.to_query_string} RETURN COUNT(node)" query(cmd).flatten[0] end private # Builds a Node object from the raw data # def node_from_resultset_item(item) (node_id, labels, props) = item - attrs = {} + attrs = HashWithIndifferentAccess.new props.each do |(index, type, value)| attrs[get_property(index)] = value end Node.new(label: get_label(labels.first), properties: attrs).tap do |node| node.id = node_id end end + + def merge_or_add_node(node, verb = :create) + verb = verb == :create ? "CREATE" : "MERGE" + result = _query("#{verb} #{node.to_query_string} RETURN ID(node)") + # Should we treat this case differently? + # return false if result.stats[:nodes_created] != 1 + id = result.resultset.first["ID(node)"] + node.id = id + node + end + end end end