From 485415330b1e30a4810868aa89ee4f27ad764000 Mon Sep 17 00:00:00 2001 From: Junegunn Choi Date: Tue, 26 Apr 2011 16:24:38 +0900 Subject: [PATCH] property and index class methods modified to take arbitrary number of symbols optionally followed by options hash --- lib/neo4j/index/indexer.rb | 34 ++++++++++++++----------- lib/neo4j/property/class_methods.rb | 16 +++++------- spec/node_mixin/node_mixin_find_spec.rb | 20 ++++++++++----- spec/node_mixin/node_mixin_spec.rb | 9 +++++-- 4 files changed, 46 insertions(+), 33 deletions(-) diff --git a/lib/neo4j/index/indexer.rb b/lib/neo4j/index/indexer.rb index b1a8bdd16..17a40288e 100644 --- a/lib/neo4j/index/indexer.rb +++ b/lib/neo4j/index/indexer.rb @@ -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 :type is String, Float, Date, DateTime and Fixnum @@ -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 diff --git a/lib/neo4j/property/class_methods.rb b/lib/neo4j/property/class_methods.rb index d64dc5dc3..67711c4f0 100644 --- a/lib/neo4j/property/class_methods.rb +++ b/lib/neo4j/property/class_methods.rb @@ -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]) @@ -80,4 +76,4 @@ def property?(prop_name) end end end -end \ No newline at end of file +end diff --git a/spec/node_mixin/node_mixin_find_spec.rb b/spec/node_mixin/node_mixin_find_spec.rb index bb339540e..2b01d66a3 100644 --- a/spec/node_mixin/node_mixin_find_spec.rb +++ b/spec/node_mixin/node_mixin_find_spec.rb @@ -7,7 +7,9 @@ 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 @@ -15,11 +17,11 @@ def to_s 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 @@ -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 diff --git a/spec/node_mixin/node_mixin_spec.rb b/spec/node_mixin/node_mixin_spec.rb index 810c05519..7f6ed5a90 100644 --- a/spec/node_mixin/node_mixin_spec.rb +++ b/spec/node_mixin/node_mixin_spec.rb @@ -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