Skip to content

Commit

Permalink
Merge cb10870 into a00d124
Browse files Browse the repository at this point in the history
  • Loading branch information
cheerfulstoic committed Sep 21, 2014
2 parents a00d124 + cb10870 commit aa02908
Show file tree
Hide file tree
Showing 17 changed files with 115 additions and 42 deletions.
2 changes: 2 additions & 0 deletions lib/neo4j/active_node.rb
Expand Up @@ -67,6 +67,8 @@ def self.inherit_id_property(other)
end

Neo4j::Session.on_session_available do |_|
id_property :uuid, auto: :uuid

name = Neo4j::Config[:id_property]
type = Neo4j::Config[:id_property_type]
value = Neo4j::Config[:id_property_type_value]
Expand Down
41 changes: 35 additions & 6 deletions lib/neo4j/active_node/id_property.rb
Expand Up @@ -51,18 +51,24 @@ def validate_conf(conf)
end

def define_property_method(clazz, name)
clear_methods(clazz, name)

clazz.module_eval(%Q{
def id
persisted? ? #{name} : nil
end
property :#{name}
validates_uniqueness_of :#{name}
property :#{name}
}, __FILE__, __LINE__)

end


def define_uuid_method(clazz, name)
clear_methods(clazz, name)

clazz.module_eval(%Q{
default_property :#{name} do
::SecureRandom.uuid
Expand All @@ -77,6 +83,8 @@ def #{name}
end

def define_custom_method(clazz, name, on)
clear_methods(clazz, name)

clazz.module_eval(%Q{
default_property :#{name} do |instance|
raise "Specifying custom id_property #{name} on none existing method #{on}" unless instance.respond_to?(:#{on})
Expand All @@ -91,17 +99,36 @@ def #{name}
}, __FILE__, __LINE__)
end

def clear_methods(clazz, name)
if clazz.method_defined?(name)
clazz.module_eval(%Q{
undef_method :#{name}
}, __FILE__, __LINE__)
end

if clazz.attribute_names.include?(name.to_s)
clazz.module_eval(%Q{
undef_property :#{name}
}, __FILE__, __LINE__)
end
end

extend self
end


module ClassMethods

def find_by_id(key)
Neo4j::Node.load(key.to_i)
self.where(id_property_name => key).first
end

def id_property(name, conf = {})
begin
drop_constraint(id_property_name, type: :unique) if has_id_property?
rescue Neo4j::Server::CypherResponse::ResponseError
end

@id_property_info = {name: name, type: conf}
TypeMethods.define_id_methods(self, name, conf)
constraint name, type: :unique
Expand All @@ -112,18 +139,20 @@ def id_property(name, conf = {})
end

def has_id_property?
!id_property_info.empty?
id_property_info && !id_property_info.empty?
end

def id_property_info
@id_property_info ||= {}
end

def primary_key
id_property_info[:name] || :id
def id_property_name
id_property_info[:name]
end

alias_method :primary_key, :id_property_name

end
end

end
end
9 changes: 8 additions & 1 deletion lib/neo4j/active_node/labels.rb
Expand Up @@ -129,12 +129,19 @@ def index(property, conf = {})
# Person.constraint :name, type: :unique
#
def constraint(property, constraints, session = Neo4j::Session.current)
Neo4j::Session.on_session_available do |_|
Neo4j::Session.on_session_available do |session|
label = Neo4j::Label.create(mapped_label_name)
label.create_constraint(property, constraints, session)
end
end

def drop_constraint(property, constraint, session = Neo4j::Session.current)
Neo4j::Session.on_session_available do |session|
label = Neo4j::Label.create(mapped_label_name)
label.drop_constraint(property, constraint, session)
end
end

def index?(index_def)
mapped_label.indexes[:property_keys].include?([index_def])
end
Expand Down
2 changes: 1 addition & 1 deletion lib/neo4j/active_node/orm_adapter.rb
Expand Up @@ -73,7 +73,7 @@ def hasherize_order(order)

def extract_id!(conditions)
if id = conditions.delete(:id)
conditions[:neo_id] = id.to_i
conditions[klass.id_property_name.to_sym] = id
end
end

Expand Down
3 changes: 2 additions & 1 deletion lib/neo4j/active_node/persistence.rb
Expand Up @@ -98,9 +98,10 @@ def create!(*args)
def load_entity(id)
Neo4j::Node.load(id)
end

end

private

end
end
end
4 changes: 2 additions & 2 deletions lib/neo4j/active_node/query/query_proxy_methods.rb
Expand Up @@ -37,7 +37,7 @@ def empty?(target=nil)
def include?(other, target=nil)
raise(InvalidParameterError, ':include? only accepts nodes') unless other.respond_to?(:neo_id)
query_with_target(target) do |target|
self.where("ID(#{target}) = {other_node_id}").params(other_node_id: other.neo_id).query.return("count(#{target}) AS count").first.count > 0
self.query.where(target => {@model.primary_key => other.id}).return("count(#{target}) AS count").first.count > 0
end
end

Expand Down Expand Up @@ -69,4 +69,4 @@ def exists_query_start(origin, condition, target)
end
end
end
end
end
8 changes: 4 additions & 4 deletions lib/neo4j/active_node/query_methods.rb
Expand Up @@ -12,12 +12,12 @@ def exists?(node_condition=nil)

# 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('ID(n)').pluck(:n).first
self.query_as(:n).limit(1).order(n: primary_key).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
self.query_as(:n).limit(1).order('ID(n) DESC').pluck(:n).first
self.query_as(:n).limit(1).order(n: {primary_key => :desc}).pluck(:n).first
end

# @return [Fixnum] number of nodes of this class
Expand All @@ -38,7 +38,7 @@ def empty?

def include?(other)
raise(InvalidParameterError, ':include? only accepts nodes') unless other.respond_to?(:neo_id)
self.query_as(:n).where("ID(n) = #{other.neo_id}").return("count(n) AS count").first.count > 0
self.query_as(:n).where(n: {primary_key => other.id}).return("count(n) AS count").first.count > 0
end

private
Expand All @@ -55,4 +55,4 @@ def exists_query_start(node_condition)
end
end
end
end
end
10 changes: 10 additions & 0 deletions lib/neo4j/shared/property.rb
Expand Up @@ -153,6 +153,16 @@ def property(name, options={})
constraint_or_index(name, options)
end

def undef_property(name)
raise ArgumentError, "Argument `#{name}` not an attribute" if not attribute_names.include?(name.to_s)

attribute_methods(name).each do |method|
undef_method(method)
end

undef_constraint_or_index(name)
end

def default_property(name, &block)
default_properties[name] = block
end
Expand Down
6 changes: 3 additions & 3 deletions spec/e2e/active_model_spec.rb
Expand Up @@ -233,7 +233,7 @@ class Company
before do
Neo4j::Config[:cache_class_names] = true
@cached = CacheTest.create
@unwrapped = Neo4j::Node._load(@cached.id)
@unwrapped = Neo4j::Node._load(@cached.neo_id)
end

it 'responds true to :cached_class?' do
Expand All @@ -253,7 +253,7 @@ class Company
before do
Neo4j::Config[:cache_class_names] = false
@uncached = CacheTest.create
@unwrapped = Neo4j::Node._load(@uncached.id)
@unwrapped = Neo4j::Node._load(@uncached.neo_id)
end

before { Neo4j::Config[:cache_class_names] = false }
Expand Down Expand Up @@ -830,4 +830,4 @@ class RelClass
expect(reflection.rel_class_name).to eq rel_clazz.name
end
end
end
end
8 changes: 5 additions & 3 deletions spec/e2e/id_property_spec.rb
Expand Up @@ -42,10 +42,11 @@
end

it 'uses the neo_id as id after save' do
SecureRandom.stub(:uuid) { 'secure123' }
node = clazz.new
expect(node.id).to eq(nil)
node.save!
expect(node.id).to eq(node.neo_id)
expect(node.id).to eq('secure123')
end

it 'can find by id uses the neo_id' do
Expand All @@ -55,11 +56,11 @@
end

it 'returns :id as primary_key' do
expect(clazz.primary_key).to eq :id
expect(clazz.primary_key).to eq :uuid
end

it 'responds false to has_id_property' do
expect(clazz.has_id_property?).to be_falsey
expect(clazz.has_id_property?).to be_truthy
end

describe 'when having a configuration' do
Expand Down Expand Up @@ -295,6 +296,7 @@ class Car < Vehicle; end

Fruit = UniqueClass.create do
include Neo4j::ActiveNode

id_property :my_id
end

Expand Down
10 changes: 5 additions & 5 deletions spec/e2e/label_spec.rb
Expand Up @@ -124,12 +124,12 @@
end

it 'creates an index' do
expect(clazz.mapped_label.indexes).to eq(:property_keys => [[:name]])
expect(clazz.mapped_label.indexes).to eq(:property_keys => [[:name], [:uuid]])
end

it 'does not create index on other classes' do
expect(clazz.mapped_label.indexes).to eq(:property_keys => [[:name]])
expect(other_class.mapped_label.indexes).to eq(:property_keys => [])
expect(clazz.mapped_label.indexes).to eq(:property_keys => [[:name], [:uuid]])
expect(other_class.mapped_label.indexes).to eq(:property_keys => [[:uuid]])
end

describe 'when inherited' do
Expand All @@ -141,8 +141,8 @@ class Foo1
class Foo2 < Foo1

end
expect(Foo1.mapped_label.indexes).to eq(:property_keys => [[:name]])
expect(Foo2.mapped_label.indexes).to eq(:property_keys => [[:name]])
expect(Foo1.mapped_label.indexes).to eq(:property_keys => [[:name], [:uuid]])
expect(Foo2.mapped_label.indexes).to eq(:property_keys => [[:name], [:uuid]])
end

end
Expand Down
11 changes: 9 additions & 2 deletions spec/e2e/transaction_spec.rb
Expand Up @@ -12,18 +12,25 @@

#:nocov:
it 'returns hash values inside but outside it has the node value after commit' do
i = 0
SecureRandom.stub(:uuid) do
i += 1
"secure1234_#{i}"
end

if Neo4j::Session.current.db_type == :server_db
clazz
tx = Neo4j::Transaction.new
a = clazz.create name: 'a'
b = clazz.create name: 'b'
a.thing = b
expect(a.thing).to eq("name"=>"b", "_classname"=>clazz.to_s)
expect(a.thing).to eq("name"=>"b", "_classname"=>clazz.to_s, "uuid" => "secure1234_2")
tx.close
expect(a.thing).to eq(b)
end

if Neo4j::Session.current.db_type == :embedded_db
clazz
tx = Neo4j::Transaction.new
a = clazz.create name: 'a'
b = clazz.create name: 'b'
Expand All @@ -36,4 +43,4 @@
end
#:nocov:
end
end
end
6 changes: 3 additions & 3 deletions spec/integration/label_spec.rb
Expand Up @@ -172,19 +172,19 @@ class EmptyTestClass
end

@jasmine = FirstLastTestClass.create(name: 'jasmine')
FirstLastTestClass.create
@middle = FirstLastTestClass.create
@lauren = FirstLastTestClass.create(name: 'lauren')
end

describe 'first' do
it 'returns the first object created... sort of, see docs' do
expect(FirstLastTestClass.first).to eq @jasmine
expect(FirstLastTestClass.first).to eq [@jasmine, @middle, @lauren].sort_by(&:uuid).first
end
end

describe 'last' do
it 'returns the last object created... sort of, see docs' do
expect(FirstLastTestClass.last).to eq @lauren
expect(FirstLastTestClass.last).to eq [@jasmine, @middle, @lauren].sort_by(&:uuid).last
end

it 'returns nil when there are no results' do
Expand Down

0 comments on commit aa02908

Please sign in to comment.