require 'geoff/children_dsl' require 'geoff/dsl_exception_handling' class NodeDsl include DslExceptionHandling def initialize(options, &block) @node_name = options[:node_name] || 'root' @klass_name = options[:klass_name] || 'ROOT' @container = options[:container] || Container.new @rel_type = options[:rel_type] @target = options[:target] @properties = {} @children_dsls = [] @rendered = false eval_with_exceptions(&block) if block_given? end def to_geoff geoff_lines.join "\n" end def geoff_lines #we need this to prevent rendering same node which is rendered already return [] if @rendered @rendered = true lines = [self_to_geoff] lines << all_rule_to_geoff if use_neo4j_wrapper? lines += @children_dsls.map(&:geoff_lines) lines end def b @container end def all_rule_to_geoff "(#{@klass_name})-[:all]->(#{node_name})" end def self_to_geoff "(#{node_name}) #{properties.to_json}" end #refactor out wrapper specific stuff later def use_neo4j_wrapper? true end def properties if use_neo4j_wrapper? { '_classname' => @klass_name }.merge @properties else @properties end end # e.g. #sandwich "BLT", type: :on_menu do # filling 'bacon' # filling 'lettuce' # filling 'tomato' #end def method_missing m, *args, &blk if args.empty? @properties[m] else return super unless @write_mode val = if args.first.is_a? Proc @target.instance_exec &args.first else args.first end @properties[m] = val end end def to_s to_geoff end def clone c = self.class.new( node_name: @node_name, klass_name: @klass_name, container: @container, rel_type: @rel_type, target: @target ) # sort it out, instance_variable_set is probably not the best way to clone object c.instance_variable_set('@properties', @properties) children_dsls = @children_dsls.map &:clone children_dsls.each {|children_dsl| children_dsl.parent_node_dsl = c} c.instance_variable_set('@children_dsls', children_dsls) c end def node_name [@node_name, object_id].compact.join '_' end private def incoming type=nil, options={}, &block options.merge!(direction: :incoming) children type, options, &block end def outgoing type=nil, options={}, &block options.merge!(direction: :outgoing) children type, options, &block end def children type=nil, options={}, &block options.merge!({ parent_node_dsl: self, type: type, container: @container, target: @target }) options.merge!(direction: :outgoing) unless options.has_key? :direction @children_dsls << ChildrenDsl.new(options, &block) end end