lib/neo4j/active_node/labels.rb in neo4j-3.0.0.alpha.8 vs lib/neo4j/active_node/labels.rb in neo4j-3.0.0.alpha.9
- old
+ new
@@ -57,69 +57,97 @@
end
end
end
module ClassMethods
-
# Find all nodes/objects of this class
def all
self.query_as(:n).pluck(:n)
end
+ # Returns the first node of this class, sorted by ID. Note that this may not be the first node created since Neo4j recycles IDs.
def first
- self.query_as(:n).limit(1).order('n.neo_id').pluck(:n).first
+ self.query_as(:n).limit(1).order('ID(n)').pluck(:n).first
end
+ # Returns the last node of this class, sorted by ID. Note that this may not be the first node created since Neo4j recycles IDs.
def last
- count = self.count
- final_count = count == 0 ? 0 : count - 1
- self.query_as(:n).order('n.neo_id').skip(final_count).limit(1).pluck(:n).first
+ self.query_as(:n).order('ID(n) DESC').limit(1).pluck(:n).first
end
# @return [Fixnum] number of nodes of this class
def count
self.query_as(:n).return("count(n) AS count").first.count
end
# Returns the object with the specified neo4j id.
- # @param [String,Fixnum] neo_id of node to find
+ # @param [String,Fixnum] id of node to find
def find(id)
- raise "Unknown argument #{id.class} in find method" if not [String, Fixnum].include?(id.class)
-
- Neo4j::Node.load(id.to_i)
+ raise "Unknown argument #{id.class} in find method (expected String or Fixnum)" if not [String, Fixnum].include?(id.class)
+ find_by_id(id)
end
# Finds the first record matching the specified conditions. There is no implied ordering so if order matters, you should specify it yourself.
- # @param [Hash] hash of arguments to find
+ # @param [Hash] args of arguments to find
def find_by(*args)
self.query_as(:n).where(n: eval(args.join)).limit(1).pluck(:n).first
end
# Like find_by, except that if no record is found, raises a RecordNotFound error.
def find_by!(*args)
a = eval(args.join)
find_by(args) or raise RecordNotFound, "#{self.query_as(:n).where(n: a).limit(1).to_cypher} returned no results"
end
- # Destroy all nodes an connected relationships
+ # Destroy all nodes and connected relationships
def destroy_all
self.neo4j_session._query("MATCH (n:`#{mapped_label_name}`)-[r]-() DELETE n,r")
self.neo4j_session._query("MATCH (n:`#{mapped_label_name}`) DELETE n")
end
# Creates a Neo4j index on given property
+ #
+ # This can also be done on the property directly, see Neo4j::ActiveNode::Property::ClassMethods#property.
+ #
# @param [Symbol] property the property we want a Neo4j index on
- def index(property)
- if self.neo4j_session
- _index(property)
- else
- Neo4j::Session.add_listener do |event, _|
- _index(property) if event == :session_available
- end
+ # @param [Hash] conf optional property configuration
+ #
+ # @example
+ # class Person
+ # include Neo4j::ActiveNode
+ # property :name
+ # index :name
+ # end
+ #
+ # @example with constraint
+ # class Person
+ # include Neo4j::ActiveNode
+ # property :name
+ #
+ # # below is same as: index :name, index: :exact, constraint: {type: :unique}
+ # index :name, constraint: {type: :unique}
+ # end
+ def index(property, conf = {})
+ Neo4j::Session.on_session_available do |_|
+ _index(property, conf)
end
+ @_indexed_properties ||= []
+ @_indexed_properties.push property unless @_indexed_properties.include? property
end
+ # Creates a neo4j constraint on this class for given property
+ #
+ # @example
+ # Person.constraint :name, type: :unique
+ #
+ def constraint(property, constraints, session = Neo4j::Session.current)
+ Neo4j::Session.on_session_available do |_|
+ label = Neo4j::Label.create(mapped_label_name)
+ label.create_constraint(property, constraints, session)
+ end
+ end
+
def index?(index_def)
mapped_label.indexes[:property_keys].include?(index_def)
end
# @return [Array{Symbol}] all the labels that this class has
@@ -130,29 +158,38 @@
# @return [Symbol] the label that this class has which corresponds to a Ruby class
def mapped_label_name
@_label_name || self.to_s.to_sym
end
- def indexed_labels
+ # @return [Neo4j::Label] the label for this class
+ def mapped_label
+ Neo4j::Label.create(mapped_label_name)
+ end
+ def indexed_properties
+ @_indexed_properties
end
+
protected
- def _index(property)
+ def _index(property, conf)
mapped_labels.each do |label|
# make sure the property is not indexed twice
existing = label.indexes[:property_keys]
- label.create_index(property) unless existing.flatten.include?(property)
+
+ # In neo4j constraint automatically creates an index
+ if conf[:constraint]
+ constraint(property, conf[:constraint])
+ else
+ label.create_index(property) unless existing.flatten.include?(property)
+ end
+
end
end
def mapped_labels
mapped_label_names.map{|label_name| Neo4j::Label.create(label_name)}
- end
-
- def mapped_label
- Neo4j::Label.create(mapped_label_name)
end
def set_mapped_label_name(name)
@_label_name = name.to_sym
end