Module: Zena::Use::QueryBuilder::ZafuMethods

Includes:
RubyLess
Defined in:
lib/zena/use/query_builder.rb

Overview

  1. try Zafu

<r:images in='site'>
  1. r_unknown

try RubyLess.translate(node, xxxxxx) <-- pass context
  1. helper (view) tries to resolve safe_method_type as RubyLess or PseudoSQL

Defined Under Namespace

Classes: DynamicQuery

Constant Summary collapse

QB_KEYS =
[:find, :from, :else, :in, :where, :or, :limit, :order]

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



158
159
160
# File 'lib/zena/use/query_builder.rb', line 158

def self.included(base)
  base.process_unknown :querybuilder_eval
end

Instance Method Details

#get_find_type(signature) ⇒ Object



144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/zena/use/query_builder.rb', line 144

def get_find_type(signature)
  if signature == ['find', Number]
    {:method => :find_node_by_zip, :class => VirtualClass['Node'], :nil => true, :accept_nil => true}
  elsif signature == ['find', String]
    # TODO: support dynamic strings ?
    {:method => 'nil', :pre_processor => :get_type_for_find,  :class => NilClass}
  elsif signature == ['count', String]
    # TODO: support dynamic strings ?
    {:method => '0',   :pre_processor => :get_type_for_count, :class => Number  }
  else
    nil
  end
end

#get_type_for_count(string) ⇒ Object

Pre-processing of the ‘count(“…”)’ method.



247
248
249
250
# File 'lib/zena/use/query_builder.rb', line 247

def get_type_for_count(string)
  finder = build_finder(:count, string, {})
  TypedString.new(finder.delete(:method), finder)
end

#get_type_for_find(string) ⇒ Object

Pre-processing of the ‘find(“…”)’ method.



238
239
240
241
242
243
244
# File 'lib/zena/use/query_builder.rb', line 238

def get_type_for_find(string)
  finder = build_finder(get_count(string, {}), string, {})
  TypedString.new(finder.delete(:method), finder)
rescue ::QueryBuilder::Error => err
  out parser_error(err.message)
  nil
end

#node_context_vars(finder) ⇒ Object

This method is called when we enter a new node context



281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
# File 'lib/zena/use/query_builder.rb', line 281

def node_context_vars(finder)
  sub_context = super
  query = finder[:query]
  if query && ((pagination_key = query.pagination_key) || child['count'])
    node_count = get_var_name('paginate', 'nodes', sub_context)
    set_context_var('set_var', 'count', RubyLess::TypedString.new(node_count, Number))

    res = "#{node_count} = Node.do_find(:count, #{query.to_s(:count)})"
    if pagination_key
      # Full pagination needed
      set_context_var('paginate', 'key', pagination_key, sub_context)

      page_count = get_var_name('paginate', 'count', sub_context)
      curr_page  = get_var_name('paginate', 'current', sub_context)

      # Give access to the page number through the pagination key.
      set_context_var('set_var', pagination_key, RubyLess::TypedString.new(curr_page, Number))
      # Give access to page_count and count
      # FIXME: DOC
      set_context_var('set_var', 'page_count', RubyLess::TypedString.new(page_count, Number))

      res << "; #{page_count} = (#{node_count} / #{query.page_size.to_f}).ceil; #{curr_page} = [1,params[:#{pagination_key}].to_i].max"
    end

    out "<% #{res} %>"

  elsif finder[:method].kind_of?(RubyLess::TypedString)
    # Hash passed with :zafu => {} is inserted into context
    sub_context.merge!(finder[:method].opts[:zafu] || {})
  end

  sub_context[:has_link_id] = query && query.select_keys.include?('link_id')

  sub_context
end

#querybuilder_eval(method = @method) ⇒ Object

Resolve unknown methods by trying to build a pseudo-sql query with QueryBuilder.



253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
# File 'lib/zena/use/query_builder.rb', line 253

def querybuilder_eval(method = @method)
  if method =~ /^\d+$/
    finder = {:method => "find_node_by_zip(#{method})", :class => VirtualClass['Node'], :nil => true}
  else
    count  = get_count(method, @params)
    finder = build_finder(count, method, @params)
  end

  if count == :count && @blocks.empty?
    out "<%= #{finder[:method]} %>"
  else
    expand_with_finder(finder)
  end
rescue ::QueryBuilder::Error => err
  parser_continue(err.message)
end

#r_queryObject

Open a list context with a query comming from the url params. Default param name is “qb”



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/zena/use/query_builder.rb', line 186

def r_query
  return parser_error("Missing 'default' query") unless default_psql = @params[:default]

  count = get_count(default_psql, {:find => @params[:find]})
  begin
    default = build_finder(count, default_psql, {})
    default_query = default[:query]
  rescue ::QueryBuilder::Error => err
    return parser_error(err.message)
  end
  
  if count == :all
    klass = [default_query.main_class]
    type = :find
    res_nil = true
  elsif count == :first
    klass = default_query.main_class
    type = :find
    res_nil = true
  else
    klass = Number
    type = :count
    res_nil = false
  end
  
  can_be_nil = true
  if sql = @params[:eval]
    sql = RubyLess.translate(self, sql)
    unless sql.klass <= String
      return parser_error("Invalid compilation result for #{sql.inspect} (#{sql.klass})")
    end
    can_be_nil = sql.opts[:nil]
  elsif sql = @params[:select]
    sql = RubyLess.translate_string(self, sql)
    can_be_nil = sql.opts[:nil]
  else
    sql = "params[:qb]"
  end

  if can_be_nil
    sql = "#{sql} || #{default_psql.inspect}"
  end

  query = DynamicQuery.new(default_query, single_node, sql, count)
  if @blocks.empty? && type == :count
    out "<%= #{query.to_s} %>"
  else
    expand_with_finder(:method => query.to_s, :class => klass, :nil => res_nil, :query => query)
  end
end

#show_errorsObject

Select the most pertinent error between RubyLess processing errors and QueryBuilder errors.



271
272
273
274
275
276
277
278
# File 'lib/zena/use/query_builder.rb', line 271

def show_errors
  if @method =~ / in | where | from / || (QB_KEYS & @params.keys != [])
    # probably a query
    @errors.detect {|e| e =~ /Syntax/} || @errors.last
  else
    @errors.first
  end
end