Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A suggestion on NodeMixin interface #20

Merged
merged 1 commit into from
Apr 27, 2011
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 19 additions & 15 deletions lib/neo4j/index/indexer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ def to_s
# Example:
# class Person
# include Neo4j::NodeMixin
# property :weight, :type => Float
# index :weight
# property :height, :weight, :type => Float
# index :height, :weight
# end
#
# Supported values for <tt>:type</tt> is <tt>String</tt>, <tt>Float</tt>, <tt>Date</tt>, <tt>DateTime</tt> and <tt>Fixnum</tt>
Expand All @@ -78,19 +78,23 @@ def to_s
# * See Neo4j::Index::LuceneQuery
# * See #find
#
def index(field, conf = {})
if conf[:via]
rel_dsl = @indexer_for._decl_rels[conf[:via]]
raise "No relationship defined for '#{conf[:via]}'. Check class '#{@indexer_for}': index :#{field}, via=>:#{conf[:via]} <-- error. Define it with a has_one or has_n" unless rel_dsl
raise "Only incoming relationship are possible to define index on. Check class '#{@indexer_for}': index :#{field}, via=>:#{conf[:via]}" unless rel_dsl.incoming?
via_indexer = rel_dsl.target_class._indexer

field = field.to_s
@via_relationships[field] = rel_dsl
conf.delete :via # avoid endless recursion
via_indexer.index(field, conf)
else
@field_types[field.to_s] = conf[:type] || :exact
def index(*args)
conf = args.last.kind_of?(Hash) ? args.pop : {}
conf_no_via = conf.reject { |k,v| k == :via } # avoid endless recursion

args.uniq.each do | field |
if conf[:via]
rel_dsl = @indexer_for._decl_rels[conf[:via]]
raise "No relationship defined for '#{conf[:via]}'. Check class '#{@indexer_for}': index :#{field}, via=>:#{conf[:via]} <-- error. Define it with a has_one or has_n" unless rel_dsl
raise "Only incoming relationship are possible to define index on. Check class '#{@indexer_for}': index :#{field}, via=>:#{conf[:via]}" unless rel_dsl.incoming?
via_indexer = rel_dsl.target_class._indexer

field = field.to_s
@via_relationships[field] = rel_dsl
via_indexer.index(field, conf_no_via)
else
@field_types[field.to_s] = conf[:type] || :exact
end
end
end

Expand Down
16 changes: 6 additions & 10 deletions lib/neo4j/property/class_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,14 @@ module ClassMethods
# :to_java in the Neo4j::TypeConverters module.
#
def property(*props)
if props.size == 2 and props[1].kind_of?(Hash)
props[1].each_pair do |key, value|
pname = props[0].to_sym
_decl_props[pname] ||= {}
_decl_props[pname][key] = value
end
props = props[0..0]
end
options = props.last.kind_of?(Hash) ? props.pop : {}

props.each do |prop|
props.uniq.each do |prop|
pname = prop.to_sym
_decl_props[pname] ||= {}
options.each do |key, value|
_decl_props[pname][key] = value
end

define_method(pname) do
Neo4j::TypeConverters.to_ruby(self.class, pname, self[pname])
Expand Down Expand Up @@ -80,4 +76,4 @@ def property?(prop_name)
end
end
end
end
end
20 changes: 14 additions & 6 deletions spec/node_mixin/node_mixin_find_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,21 @@
before(:all) do
@clazz = create_node_mixin do
property :year, :type => Fixnum
property :month, :day, :type => Fixnum
index :year
index :month, :day
def to_s
"Year #{year}"
end
end
end

before(:each) do
@x49 = @clazz.new(:year => 49)
@x50 = @clazz.new(:year => 50)
@x51 = @clazz.new(:year => 51)
@x52 = @clazz.new(:year => 52)
@x53 = @clazz.new(:year => 53)
@x49 = @clazz.new(:year => 49, :month => 1, :day => 11)
@x50 = @clazz.new(:year => 50, :month => 2, :day => 12)
@x51 = @clazz.new(:year => 51, :month => 3, :day => 13)
@x52 = @clazz.new(:year => 52, :month => 4, :day => 14)
@x53 = @clazz.new(:year => 53, :month => 5, :day => 15)
new_tx
end

Expand All @@ -35,12 +37,18 @@ def to_s
res.should include(@x50,@x51,@x52)
end

it "find(:year => 50..52) returns all integer between 50 and 51" do
it "find(:year => 50...52) returns all integer between 50 and 51" do
res = [*@clazz.find(:year=> 50...52)]
res.should include(@x50,@x51)
res.should_not include(@x49,@x52,@x53)
end

it "find(:month=> 2..5, :day => 11...14) finds nodes matching both conditions" do
res = [*@clazz.find(:month=> 2..5, :day => 11...14)]
res.should include(@x50,@x51)
res.should_not include(@x49,@x52,@x53)
end

end


Expand Down
9 changes: 7 additions & 2 deletions spec/node_mixin/node_mixin_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,19 @@
end

@employee_class = create_node_mixin_subclass(person_class) do
property :employee_id
property :employee_id, :ssn
property :weight, :height, :type => Float
has_n :contracts
end
end

it "#new creates node and set properties with given hash" do
empl = @employee_class.new(:name => 'andreas', :employee_id => 123)
empl = @employee_class.new(:name => 'andreas', :employee_id => 123, :ssn => 1000, :height => '6.3')

empl[:name].should == 'andreas'
empl.ssn == 1000
empl.height.class.should == Float
empl.height.should == 6.3
end

it "#has_n can use baseclass definition" do
Expand Down