require 'neo4j/property/class_methods' module Neo4j module Property # Returns a hash of all properties # It also include the id of the node with the key _neo_id # def props ret = {"_neo_id" => neo_id} iter = getPropertyKeys.iterator while (iter.hasNext) do key = iter.next ret[key] = get_property(key) end ret end # Returns the unique id of this node. # Ids are garbage collected over time so they are only guaranteed to be unique during a specific time span: # if the node is deleted, it's likely that a new node at some point will get the old id. Note: # this makes node ids brittle as public APIs. def neo_id getId end # Returns a hash of properties with keys not starting with _ # That means that the neo_id will not be included in the returned hash. # def attributes attr = props ret = {} attr.each_pair { |k, v| ret[k] = wrapper.respond_to?(k) ? wrapper.send(k) : v unless k.to_s[0] == ?_ } ret end # Checks if the given key exist as a property. def property?(key) has_property?(key.to_s) end # Updates this node/relationship's properties by using the provided struct/hash. # If the option {:strict => true} is given, any properties present on # the node but not present in the hash will be removed from the node. # # ==== Parameters # struct_or_hash:: the key and value to be set, should respond to each_pair # options:: further options defining the context of the update, should be a Hash # # ==== Returns # self # def update(struct_or_hash, options={}) strict = options[:strict] keys_to_delete = props.keys - %w(_neo_id _classname) if strict struct_or_hash.each_pair do |key, value| next if %w(_neo_id _classname).include? key.to_s # do not allow special properties to be mass assigned keys_to_delete.delete(key) if strict setter_meth = "#{key}=".to_sym if @_wrapper && @_wrapper.respond_to?(setter_meth) @_wrapper.send(setter_meth, value) else self[key] = value end end keys_to_delete.each { |key| delete_property(key) } if strict self end # Returns the value of the given key or nil if the property does not exist. def [](key) return unless property?(key) val = get_property(key.to_s) val.class.superclass == ArrayJavaProxy ? val.to_a : val end # Sets the property of this node. # Property keys are always strings. Valid property value types are the primitives(String, Fixnum, Float, FalseClass, TrueClass) or array of those primitives. # # ==== Gotchas # * Values in the array must be of the same type. # * You can *not* delete or add one item in the array (e.g. person.phones.delete('123')) but instead you must create a new array instead. # def []=(key, value) k = key.to_s if value.nil? remove_property(k) elsif (Array === value) case value[0] when NilClass set_property(k, [].to_java(:string)) when String set_property(k, value.to_java(:string)) when Float set_property(k, value.to_java(:double)) when FalseClass, TrueClass set_property(k, value.to_java(:boolean)) when Fixnum set_property(k, value.to_java(:long)) when Boolean set_property(k, value.to_java(:boolean)) else raise "Not allowed to store array with value #{value[0]} type #{value[0].class}" end else set_property(k, value) end end end end