Changeset 1111

Show
Ignore:
Timestamp:
2008-07-19 00:17:02 (6 months ago)
Author:
gaspard
Message:

Started to make changes to enable queries across multiple tables (comments/data/nodes). Added [start_node] to keep track of opening node when using ajax.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/app/helpers/application_helper.rb

    r1106 r1111  
    55module ApplicationHelper 
    66  include Zena::Acts::Secure 
    7    
    87   
    98  def dom_id(node) 
     
    721720    else 
    722721      sprintf("%i octets", size) 
     722    end 
     723  end 
     724   
     725  # main node before ajax stuff (the one in browser url) 
     726  def start_node 
     727    @start_node ||= if params[:s] 
     728      secure!(Node) { Node.find_by_zip(params[:s]) } 
     729    else 
     730      @node 
    723731    end 
    724732  end 
  • trunk/lib/node_query.rb

    r1103 r1111  
    252252    end 
    253253     
     254    def class_from_table(table_name) 
     255      case table_name 
     256      when 'nodes' 
     257        Node 
     258      when 'versions' 
     259        Version 
     260      when 'comments' 
     261        Comment 
     262      when 'data_entries' 
     263        DataEntry 
     264      else 
     265        # ? error 
     266        Object 
     267      end 
     268    end 
     269     
    254270    def parse_custom_query_argument(key, value) 
    255271      return nil unless value 
     
    325341        end 
    326342        query = NodeQuery.new(pseudo_sql, opts.merge(:custom_query_group => visitor.site.host)) 
    327         [query.to_sql, query.errors, !query.uses_node_name
     343        [query.to_sql, query.errors, query.uses_node_name, query.result_class
    328344      end 
    329345    end 
  • trunk/lib/parser/lib/rules/zena.rb

    r1107 r1111  
    489489      end 
    490490       
    491       out "<%= form_remote_tag(:url => zafu_node_path(#{node_id}), :method => :get, :html => {:id => \"#{dom_id}_f\"}) %><div class='hidden'><input type='hidden' name='t_url' value='#{block.template_url}'/><input type='hidden' name='dom_id' value='#{block.erb_dom_id}'/></div><div class='wrapper'>" 
     491      out "<%= form_remote_tag(:url => zafu_node_path(#{node_id}), :method => :get, :html => {:id => \"#{dom_id}_f\"}) %><div class='hidden'><input type='hidden' name='t_url' value='#{block.template_url}'/><input type='hidden' name='dom_id' value='#{block.erb_dom_id}'/>#{start_node_input}</div><div class='wrapper'>" 
    492492      if @blocks == [] 
    493493        out "<input type='text' name='#{@params[:key] || 'f'}' value='<%= params[#{(@params[:key] || 'f').to_sym.inspect}] %>'/>" 
     
    10411041      else 
    10421042        # relation 
    1043         list_finder = build_finder_for(:all, values) 
     1043        list_finder, klass = build_finder_for(:all, values) 
     1044        return parser_error("invalid class (#{klass})") unless klass.ancestors.include?(Node) 
    10441045      end 
    10451046      out "<% if (#{list_var} = #{list_finder}) && (#{list_var}_relation = #{node}.relation_proxy(#{role.inspect})) -%>" 
     
    15361537    def r_icon 
    15371538      if !@params[:in] && !@params[:where] && !@params[:from] && !@params[:find] 
    1538         do_var(build_finder_for(:first, 'icon', :or => 'image'), :node_class => Image) 
     1539        finder, klass = build_finder_for(:first, 'icon', @params.merge(:or => 'image')) 
     1540        return parser_error("invalid class (#{klass})") unless klass.ancestors.include?(Node) 
     1541        do_var(finder, :node_class => klass) 
    15391542      else 
    15401543        r_unknown 
     
    16501653      if @params[:href] 
    16511654        unless lnode = find_stored(Node, @params[:href]) 
    1652           opts << ", :href=>#{build_finder_for(:first, @params[:href])}" 
     1655          finder, klass = build_finder_for(:first, @params[:href]) 
     1656          return parser_error("invalid class (#{klass})") unless klass.ancestors.include?(Node) 
     1657          opts << ", :href=>#{finder}" 
    16531658        end 
    16541659      end 
     
    16791684       
    16801685      if sharp_in = @params[:in] 
    1681         opts << ", :sharp_in=>#{build_finder_for(:first, sharp_in, {})}" 
     1686        finder, klass = build_finder_for(:first, sharp_in, {}) 
     1687        return parser_error("invalid class (#{klass})") unless klass.ancestors.include?(Node) 
     1688        opts << ", :sharp_in=>#{finder}" 
    16821689      end 
    16831690       
     
    17231730      return unless node_kind_of?(Node) 
    17241731      if @params[:src] 
    1725         img = build_finder_for(:first, @params[:src]) 
     1732        finder, klass = build_finder_for(:first, @params[:src]) 
     1733        return parser_error("invalid class (#{klass})") unless klass.ancestors.include?(Node) 
     1734        img = finder 
    17261735      else 
    17271736        img = node 
     
    17341743      res += ")" 
    17351744      if @params[:link] 
    1736         link = build_finder_for(:first, @params[:link]) 
     1745        link, klass = build_finder_for(:first, @params[:link]) 
     1746        return parser_error("invalid class (#{klass})") unless klass.ancestors.include?(Node) 
    17371747        res  = "node_link(:node=>#{link}, :text=>#{res})" 
    17381748      end 
     
    17771787          return parser_error("invalid type (should be 'month' or 'week')") 
    17781788        end 
    1779  
     1789         
     1790        finder, klass = build_finder_for(:all, finder, @params, [@date_scope]) 
     1791        return parser_error("invalid class (#{klass})") unless klass.ancestors.include?(Node) 
    17801792        res = <<-END_TXT 
    17811793<h3 class='title'> 
     
    17871799  <tr class='head'><%= cal_day_names(#{size.inspect}) %></tr> 
    17881800<% start_date, end_date = cal_start_end(#{current_date}, #{type.inspect}) -%> 
    1789 <% cal_weeks(#{ref_date.to_sym.inspect}, #{build_finder_for(:all, finder, @params, [@date_scope])}, start_date, end_date) do |week, cal_#{list_var}| -%> 
     1801<% cal_weeks(#{ref_date.to_sym.inspect}, #{finder}, start_date, end_date) do |week, cal_#{list_var}| -%> 
    17901802  <tr class='body'> 
    17911803<% week.step(week+6,1) do |day_#{list_var}|; #{list_var} = cal_#{list_var}[day_#{list_var}.strftime('%Y-%m-%d')] -%> 
     
    18451857      # DRY ! (build_finder_for, block) 
    18461858      method = @params[:method] 
    1847       if (context = node_class.zafu_known_contexts[method]) && !@params[:in] && !@params[:where] && !@params[:from
    1848         node_class = context[:node_class
    1849          
     1859      context = node_class.zafu_known_contexts[method
     1860      if context && @params.keys == [:method
     1861        klass = context[:node_class] 
    18501862        # hack to store last 'Node' context until we fix node(Node) stuff: 
    18511863        previous_node = node_kind_of?(Node) ? node : @context[:previous_node] 
    1852         if node_class.kind_of?(Array) 
     1864        if klass.kind_of?(Array) 
    18531865          # plural 
    1854           do_list( "#{node}.#{method}", context.merge(:node_class => node_class[0], :previous_node => previous_node) ) 
     1866          do_list( "#{node}.#{method}", context.merge(:node_class => klass[0], :previous_node => previous_node) ) 
    18551867        else 
    18561868          # singular 
     
    18601872        count   = ['first','all'].include?(@params[:find]) ? @params[:find].to_sym : nil 
    18611873        count ||= Node.plural_relation?(method) ? :all : :first 
     1874        finder, klass = build_finder_for(count, method, @params) 
    18621875        if count == :all 
    18631876          # plural 
    1864           do_list( build_finder_for(count, method, @params)
     1877          do_list( finder, :node_class => klass
    18651878        # elsif count == :count 
    18661879        #   "<%= #{build_finder_for(count, method, @params)} %>" 
    18671880        else 
    18681881          # singular 
    1869           do_var(  build_finder_for(count, method, @params)
     1882          do_var(  finder, :node_class => klass
    18701883        end 
    18711884      else 
     
    18991912    # Create an sql query to open a new context (passes its arguments to HasRelations#build_find) 
    19001913    def build_finder_for(count, rel, params=@params, raw_filters = []) 
    1901       if (context = node_class.zafu_known_contexts[rel]) && !params[:in] && !params[:where] && !params[:from] && raw_filters == [] 
    1902         node_class = context[:node_class] 
    1903          
    1904         if node_class.kind_of?(Array) && count == :all && node_class[0].ancestors.include?(Node) 
    1905           return "#{node}.#{rel}" 
    1906         elsif node_class.ancestors.include?(Node) 
    1907           return count == :all ? "[#{node}.#{rel}]" : "#{node}.#{rel}" 
    1908         else 
    1909           # not a Node 
    1910           'nil' 
     1914      if (context = node_class.zafu_known_contexts[rel]) && !params[:in] && !params[:where] && !params[:from] && !params[:order] && raw_filters == [] 
     1915        klass = context[:node_class] 
     1916         
     1917        if klass.kind_of?(Array) && count == :all 
     1918          return ["#{node}.#{rel}", klass[0]] 
     1919        else 
     1920          return [(count == :all ? "[#{node}.#{rel}]" : "#{node}.#{rel}"), klass] 
    19111921        end 
    19121922      end 
     
    19151925      if (count == :first) 
    19161926        if rel == 'self' 
    1917           return node 
     1927          return [node, self.node_class] 
    19181928        elsif rel == 'main' 
    1919           return "@node" 
     1929          return ["@node", Node] 
    19201930        elsif rel == 'root' 
    1921           return "(secure(Node) { Node.find(#{current_site[:root_id]})})" 
     1931          return ["(secure(Node) { Node.find(#{current_site[:root_id]})})", Node] 
    19221932        elsif rel == 'visitor' 
    1923           return "visitor.contact" 
     1933          return ["visitor.contact", Node] 
    19241934        elsif rel =~ /^\d+$/ 
    1925           return "(secure(Node) { Node.find_by_zip(#{rel.inspect})})" 
     1935          return ["(secure(Node) { Node.find_by_zip(#{rel.inspect})})", Node] 
    19261936        elsif node_name = find_stored(Node, rel) 
    1927           return node_name 
     1937          return [node_name, Node] 
    19281938        elsif rel[0..0] == '/' 
    19291939          rel = rel[1..-1] 
    1930           return "(secure(Node) { Node.find_by_path(#{rel.inspect})})" 
     1940          return ["(secure(Node) { Node.find_by_path(#{rel.inspect})})", Node] 
    19311941        end 
    19321942      end 
     
    19501960       
    19511961      # make sure we do not use a new record in a find query: 
    1952       sql_query, query_errors, can_ignore_source = Node.build_find(count, pseudo_sql, :node_name => node_name, :raw_filters => raw_filters, :ref_date => "\#{#{current_date}}") 
     1962      sql_query, query_errors, uses_node_name, klass = Node.build_find(count, pseudo_sql, :node_name => node_name, :raw_filters => raw_filters, :ref_date => "\#{#{current_date}}") 
    19531963       
    19541964      unless sql_query 
    19551965        # is 'out' here a good idea ? 
    19561966        out parser_error(query_errors.join(' '), pseudo_sql.join(', ')) 
    1957         return "nil" 
    1958       end 
    1959        
    1960       res = "#{node_name}.do_find(#{count.inspect}, \"#{sql_query}\", #{can_ignore_source})" 
     1967        return ['nil', NilClass] 
     1968      end 
     1969       
     1970      res = "#{node_name}.do_find(#{count.inspect}, \"#{sql_query}\", #{!uses_node_name})" 
    19611971      if params[:else] 
    1962         if else_query = build_finder_for(count, params[:else], {}) 
    1963           "(#{res} || #{else_query})" 
    1964         end 
    1965       else 
    1966         res  
     1972        else_query, else_klass = build_finder_for(count, params[:else], {}) 
     1973        if else_query && (else_klass == klass || klass.ancestors.include?(else_klass) || else_klass.ancestors.include?(klass)) 
     1974          ["(#{res} || #{else_query})", klass] 
     1975        else 
     1976          [res, klass] 
     1977        end 
     1978      else 
     1979        [res, klass] 
    19671980      end 
    19681981    end 
     
    21532166    end 
    21542167     
    2155     def params_to_erb(params
    2156       res = "" 
     2168    def params_to_erb(params, initial_comma = true
     2169      res = initial_comma ? [""] : [] 
    21572170      params.each do |k,v| 
    2158         res << ", #{k.inspect}=>#{v.inspect}" 
    2159       end 
    2160       res 
     2171        res << "#{k.inspect}=>#{v.inspect}" 
     2172      end 
     2173      res.join(', ') 
    21612174    end 
    21622175     
     
    22632276    def context_name 
    22642277      return (@context[:name] || 'list') if @context 
    2265       @name || @params[:id] || parent.context_name 
     2278      @name || @params[:id] || parent ? parent.context_name : 'root' 
    22662279    end 
    22672280     
     
    22692282      return @context if @context 
    22702283      # not rendered yet, find first parent with context 
    2271       @context = parent.context 
     2284      @context = parent ? parent.context : {} 
    22722285    end 
    22732286     
     
    27112724      url_params << "link_id=\#{#{node}.link_id}" if @context[:need_link_id] && node_kind_of?(Node) 
    27122725      url_params << "node[v_status]=#{Zena::Status[:pub]}" if @params[:publish] 
     2726      url_params << start_node_input(false) 
    27132727       
    27142728      res = '' 
     
    28362850        else 
    28372851          # relation 
    2838           nodes = build_finder_for(:all, nodes) 
     2852          nodes, klass = build_finder_for(:all, nodes) 
     2853          return parser_error("invalid class (#{klass})") unless klass.ancestors.include?(Node) 
    28392854        end   
    28402855        set_attr  = @params[:attr] || 'id' 
     
    29072922     
    29082923    def find_stored(klass, key) 
    2909       @context["#{klass}_#{key}"] 
     2924      if "#{klass}_#{key}" == "Node_start_node" 
     2925        # main node before ajax stuff (the one in browser url) 
     2926        "start_node" 
     2927      else 
     2928        @context["#{klass}_#{key}"] 
     2929      end 
    29102930    end 
    29112931     
     
    29722992      end 
    29732993      return false 
     2994    end 
     2995     
     2996    def start_node_input(erb = true) 
     2997      if erb 
     2998        "<input type='hidden' name='s' value='<%= params[:s] || @node[:zip] %>'/>" 
     2999      else 
     3000        "&s=\#{params[:s] || @node[:zip]}" 
     3001      end 
    29743002    end 
    29753003     
  • trunk/lib/query_builder/lib/query_builder.rb

    r1096 r1111  
    152152  end 
    153153   
     154  def result_class 
     155    class_from_table(current_table) 
     156  end 
     157   
    154158  protected 
     159     
     160    def current_table 
     161      @current_table || main_table 
     162    end 
    155163     
    156164    def main_table 
     
    495503     
    496504    # ******** Overwrite these ********** 
     505    def class_from_table(table_name) 
     506      Object 
     507    end 
     508     
    497509    def parse_custom_query_argument(key, value) 
    498510      return nil unless value 
  • trunk/test/functional/nodes_controller_test.rb

    r1109 r1111  
    3636    art = opening.find(:first, 'set_tag') 
    3737    assert_equal 5, art.l_status 
    38     post 'update', :id => art[:zip], :node => {:l_status => 54321}, :link_id => links_id(:opening_in_art) 
     38    put 'update', :id => art[:zip], :node => {:l_status => 54321}, :link_id => links_id(:opening_in_art) 
    3939    art = assigns(:node) 
    4040    assert_equal 54321, art.l_status 
  • trunk/test/helpers/node_query/relations.yml

    r1074 r1111  
    2929projects_in_site: 
    3030  sql: "SELECT nodes.* FROM nodes WHERE nodes.kpath LIKE 'NPP%' AND (#{@node.secure_scope('nodes')}) ORDER BY nodes.position ASC, nodes.name ASC" 
     31 
     32#comments_order: 
     33#  src: "comments order by date desc" 
     34#  sql: "Comment: x" 
  • trunk/test/helpers/node_query_test.rb

    r1103 r1111  
    1717    login context[:visitor].to_sym 
    1818     
    19     sql, errors = Node.build_find(:all,@@test_strings[file][test]['src'] || test.gsub('_',' '), context) 
     19    sql, errors, uses_node_name, node_class = Node.build_find(:all,@@test_strings[file][test]['src'] || test.gsub('_',' '), context) 
    2020    if test_err = @@test_strings[file][test]['err'] 
    2121      assert_yaml_test test_err, errors.join(", ") 
     
    3636          res = @node.do_find(:all, sql) 
    3737          res = res ? res.map {|r| r[:name]}.join(', ') : '' 
     38          res = "#{node_class}: #{res}" if node_class != Node 
    3839          assert_yaml_test test_res, res 
    3940        else 
     
    5657    login(:tiger) 
    5758    assert var1_new = secure!(Node) { Node.get_class("Post").new } 
    58     assert_nil var1_new.do_find(:all, eval("\"#{Node.build_find(:all, 'posts in site', :node_name => 'self')}\"")) 
     59    sql, errors = Node.build_find(:all, 'posts in site', :node_name => 'self') 
     60    assert_nil var1_new.do_find(:all, eval("\"#{sql}\"")) 
    5961  end 
    6062   
  • trunk/test/helpers/zena_parser/basic.yml

    r1107 r1111  
    932932  res: "<ul> <li><b>I agree</b> </li> <li><b>I think this is bad</b> <ul> <li><b>Why ?</b> </li></ul> </li> <li><b>OK for me</b> </li> </ul>" 
    933933 
     934#comments_with_params: 
     935#  src: "<r:comments order='date desc'><r:each join=', ' do='[title]'/></r:comments>" 
     936#  tem: "." 
     937 
    934938comments_shown_if_empty_but_can_comment: 
    935939  src: "<r:comments><r:each do='[title]'/><r:add/></r:comments>"