lib/grumlin/repository.rb in grumlin-0.17.0 vs lib/grumlin/repository.rb in grumlin-0.18.0
- old
+ new
@@ -8,21 +8,91 @@
single: :next,
traversal: :nil
}.freeze
module InstanceMethods
+ include Grumlin::Expressions
+
def __
TraversalStart.new(self.class.shortcuts)
end
def g
TraversalStart.new(self.class.shortcuts)
end
+
+ def drop_vertex(id)
+ g.V(id).drop.iterate
+ end
+
+ def drop_edge(id = nil, from: nil, to: nil, label: nil) # rubocop:disable Metrics/AbcSize
+ raise ArgumentError, "either id or from:, to: and label: must be passed" if [id, from, to, label].all?(&:nil?)
+ return g.E(id).drop.iterate unless id.nil?
+
+ raise ArgumentError, "from:, to: and label: must be passed" if [from, to, label].any?(&:nil?)
+
+ g.V(from).outE(label).where(__.inV.hasId(to)).limit(1).drop.iterate
+ end
+
+ def add_vertex(label, id = nil, **properties)
+ id ||= properties[T.id]
+ properties = except(properties, T.id)
+
+ t = g.addV(label)
+ t = t.props(T.id => id) unless id.nil?
+ t.props(**properties).next
+ end
+
+ def add_edge(label, id = nil, from:, to:, **properties)
+ id ||= properties[T.id]
+ properties = except(properties, T.label)
+ properties[T.id] = id
+
+ g.addE(label).from(__.V(from)).to(__.V(to)).props(**properties).next
+ end
+
+ def upsert_vertex(label, id, create_properties: {}, update_properties: {}) # rubocop:disable Metrics/AbcSize
+ create_properties = except(create_properties, T.id, T.label)
+ update_properties = except(update_properties, T.id, T.label)
+ g.V(id)
+ .fold
+ .coalesce(
+ __.unfold,
+ __.addV(label).props(**create_properties.merge(T.id => id))
+ ).props(**update_properties)
+ .next
+ end
+
+ # Only from and to are used to find the existing edge, if one wants to assign an id to a created edge,
+ # it must be passed as T.id in via create_properties.
+ def upsert_edge(label, from:, to:, create_properties: {}, update_properties: {}) # rubocop:disable Metrics/AbcSize
+ create_properties = except(create_properties, T.label)
+ update_properties = except(update_properties, T.id, T.label)
+
+ g.V(from)
+ .outE(label).where(__.inV.hasId(to))
+ .fold
+ .coalesce(
+ __.unfold,
+ __.addE(label).from(__.V(from)).to(__.V(to)).props(**create_properties)
+ ).props(**update_properties).next
+ end
+
+ private
+
+ # A polyfill for Hash#except for ruby 2.x environments without ActiveSupport
+ # TODO: delete and use native Hash#except when after ruby 2.7 is deprecated.
+ def except(hash, *keys)
+ return hash.except(*keys) if hash.respond_to?(:except)
+
+ hash.each_with_object({}) do |(k, v), res|
+ res[k] = v unless keys.include?(k)
+ end
+ end
end
def self.extended(base)
base.extend(Grumlin::Shortcuts)
- base.include(Grumlin::Expressions)
base.include(InstanceMethods)
base.shortcuts_from(Grumlin::Shortcuts::Properties)
end