Skip to content

Commit

Permalink
Added support for type in custom queries and SQLiss select "nodes sel…
Browse files Browse the repository at this point in the history
…ect created_at as ti:time".
  • Loading branch information
gaspard committed Aug 30, 2012
1 parent 285d33d commit 5a72910
Show file tree
Hide file tree
Showing 10 changed files with 101 additions and 24 deletions.
1 change: 1 addition & 0 deletions History.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* Enabled "static" assets with symlink to skins in static bricks (/static/[brick]-[skin]/xxx.css => bricks/[brick]/skins/[skin]/static/xxx.css)
* No more strict scoping: "set" variables are rewritten if type matches.
* Added support for new in rubyless (Post.new, Post.new(:title => 'foo')).
* Added support for type in custom queries and SQLiss select "nodes select created_at as ti:time"

* Minor changes
* Fixed label traduction for param.
Expand Down
45 changes: 45 additions & 0 deletions app/models/node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ def self.author_proc
safe_property :title, :text, :summary

safe_attribute :created_at, :updated_at, :event_at, :log_at, :publish_from, :basepath, :inherit, :position
safe_attribute :idx_datetime1, :idx_datetime2, :idx_float1, :idx_float2, :idx_string1, :idx_string2, :idx_integer1, :idx_integer2


# safe_node_context defined in Enrollable
Expand Down Expand Up @@ -293,6 +294,50 @@ def v_#{attribute}=(value)
def v_number
version.number
end

Caster = ::ActiveRecord::ConnectionAdapters::Column

# Return class of cast value.
def self.cast_to_class(type)
case type
when :string then String
when :text then String
when :integer then Number
when :float then Number
when :decimal then Number
when :datetime then Time
when :timestamp then Time
when :time then Time
when :date then Time
when :binary then String
when :boolean then Boolean
else nil
end
end

# Read with cast to an appropriate instance. This is used along with
# custom select in QueryBuilder queries.
def rcast(key, type)
@rcast_cache ||= {}
@rcast_cache[key] ||= begin
value = @attributes[key]
return nil if value.nil?
case type
when :string then value
when :text then value
when :integer then value.to_i rescue value ? 1 : 0
when :float then value.to_f
when :decimal then Caster.value_to_decimal(value)
when :datetime then Caster.string_to_time(value)
when :timestamp then Caster.string_to_time(value)
when :time then Caster.string_to_time(value)
when :date then Caster.string_to_time(value)
when :binary then Caster.binary_to_string(value)
when :boolean then Caster.value_to_boolean(value)
else value
end
end
end

# This is an adaptation of Versions::Multi code to use our special v_ shortcut
# to access version attributes.
Expand Down
11 changes: 10 additions & 1 deletion app/models/virtual_class.rb
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,16 @@ def safe_method_type(signature, receiver = nil)

# In order to use types other then String, we use the overwritten property's
# type.
if type = safe_column_types[method]
if type_name = query.types[method]
klass = Node.cast_to_class(type_name)
if klass == String
return {:method => "attributes[#{method.inspect}]", :nil => true, :class => klass}
elsif klass
return {:method => "rcast(#{method.inspect}, #{type_name.inspect})", :nil => true, :class => klass}
else
return nil
end
elsif type = safe_column_types[method]
return type.merge(:method => "attributes[#{method.inspect}]", :nil => true)
elsif type = real_class.safe_method_type(signature)
return type.merge(:nil => true)
Expand Down
2 changes: 1 addition & 1 deletion config/gems.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ gem_plugin: # upload progress
simple_xlsx_writer: # spreadsheet
lib: 'simple_xlsx'

querybuilder: '= 1.1.2'
querybuilder: '= 1.1.3'
yamltest: '= 0.7.0'
rubyless: '= 0.8.6'
property: '= 2.3.2'
Expand Down
8 changes: 7 additions & 1 deletion lib/zena/use/query_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,13 @@ def process_idx_field(scope_field)
def process_field(field_name)
if fld = @query.attributes_alias[field_name]
# use custom query alias value defined in select clause: 'custom_a AS validation'
return processing_filter? ? "(#{fld})" : fld
if processing_filter?
# We need to use the full original clause, except when the clause contains group functions (MAX, MIN, etc).
# If the clause is too complex, we need to use something simpler or it will break (custom queries).
"(#{fld})"
else
fld
end
elsif processing_filter? && map_def = self.class.filter_fields[field_name]
# Special filter fields such as 'role', 'tag' or 'class'
if map_def.kind_of?(String)
Expand Down
5 changes: 5 additions & 0 deletions test/custom_queries/complex.host.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,12 @@ Node:
- courses.custom_a AS repeat_every
- form.last_date AS last_date
- form.last_date + INTERVAL courses.custom_a MONTH AS next_date
# Current hack to properly cast values to Time during read
- form.last_date + INTERVAL courses.custom_a MONTH AS idx_datetime1
- MAX(IF(assigned_pages.custom_a,assigned_pages.custom_a,5)) AS priority
types:
next_date: time
last_date: time
tables:
- nodes AS courses
# assigned to
Expand Down
16 changes: 0 additions & 16 deletions test/integration/zafu_compiler/basic.yml
Original file line number Diff line number Diff line change
Expand Up @@ -268,22 +268,6 @@ find_count:
src: "<r:nodes in='site' where='name like \"a%\"' find='count'/>"
res: "3"

link_page_next:
context:
pak: 2
src: "<r:nodes in='site' limit='3' order='zip' paginate='pak'><r:link page='previous'/> | <r:show var='pak'/> | <r:link page='next'/> || <r:each join=',' do='title'/></r:nodes>"
res: "<a href='/oo/projects-list/Clean-Water-project/page22.html?pak=1'>1</a> | 2 | <a href='/oo/projects-list/Clean-Water-project/page22.html?pak=3'>3</a> || tiger,lion,myLife"

link_page_next_with_block:
src: "<r:nodes in='site' limit='3' order='zip' paginate='pak'><r:link page='next' do='t'>next</r:link></r:nodes>"
res: "<a href='/oo/projects-list/Clean-Water-project/page22.html?pak=2'>next</a>"

link_page_list:
context:
pak: 2
src: "<r:nodes in='site' limit='10' order='zip' paginate='pak' do='link' page='list' join=', '/>"
tem: "/set_pak_page != set_pak.*zen_path\(@node,:pak.*elsif true.*set_pak_page/"
res: "/<a href='.*page22.html\?pak=1'>1</a>, 2, .*pak=3'>3</a>.*pak=4'>4</a>.*pak=5'>5</a>/"

# TODO:
#link_page_list_single_page:
Expand Down
24 changes: 23 additions & 1 deletion test/integration/zafu_compiler/complex_ok.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,31 @@ it_should_compile_custom_select:
site: complex
ref_date: 2004-09-01
src: "<r:emp_form_dates do='each' join=', '><r:show attr='title'/>(<r:priority/>)[<r:last_date format='%Y-%m'/>]</r:emp_form_dates>"
tem: '/var2.attributes\["priority"\].*\[<%= format_date\(var2.attributes\["last_date"\], :format => "%Y-%m"\) %>\]/'
tem: '/var2.attributes\["priority"\].*\[<%= format_date\(var2.rcast\("last_date", :time\), :format => "%Y-%m"\) %>\]/'
res: 'how to use the winch(10)[], secure a site(10)[], dangerous transportations(10)[2004-03], engine maintenance(5)[], information transmission(5)[2002-05], fiber junction(5)[2003-03], problem formulation(5)[2006-03], how to use the radio(1)[]'

type_cast_to_time_using_existing_field:
context:
node_name: '@node'
node: roger
visitor: complex_admin
site: complex
ref_date: 2004-09-01
src: "<r:emp_form_dates where='idx_datetime1 is not null' do='each' join=', ' do='idx_datetime1' format='%d.%m.%Y %H:%M'/>"
tem: '/format_date\(var2.idx_datetime1/'
res: '15.03.2006 01:00, 05.05.2003 02:00, 03.03.2005 01:00'

type_cast_to_time_custom_field:
context:
node_name: '@node'
node: roger
visitor: complex_admin
site: complex
ref_date: 2004-09-01
src: "<r:emp_form_dates where='next_date is not null' do='each' join=', ' do='next_date' format='%d.%m.%Y %H:%M'/>"
tem: '/format_date\(var2.rcast\("next_date", :time/'
res: '15.03.2006 01:00, 05.05.2003 02:00, 03.03.2005 01:00'

it_should_group_by_custom_select:
context:
node_name: '@node'
Expand Down
5 changes: 5 additions & 0 deletions test/integration/zafu_compiler/query.yml
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,11 @@ simple_select:
tem: '/<%= var1.attributes\["ti"\] %>/'
res: "<div>crocodiles</div>"

select_with_type:
src: "<div do='nodes select created_at as ti:time' find='first' do='ti' format='%d.%m.%Y'/>"
tem: '/format_date\(var1.rcast\("ti", :time\)/'
res: "<div>11.04.2006</div>"

select_in_from:
src: "<div do='images select title as it from projects select title as pt in site' do='each' join=', '><r:pt/>: <r:it/></div>"
tem: '/<%= var2.attributes\["pt"\] %>: <%= var2.attributes\["it"\] %>/'
Expand Down
8 changes: 4 additions & 4 deletions zena.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Gem::Specification.new do |s|

s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["Gaspard Bucher"]
s.date = %q{2012-08-24}
s.date = %q{2012-08-30}
s.default_executable = %q{zena}
s.description = %q{zena is a Ruby on Rails CMS (content managment system) with a focus on usability, ease of customization and web 2.0 goodness (application like behaviour).}
s.email = %q{gaspard@teti.ch}
Expand Down Expand Up @@ -2491,7 +2491,7 @@ Gem::Specification.new do |s|
s.add_runtime_dependency(%q<differ>, ["= 0.1.2"])
s.add_runtime_dependency(%q<RedCloth>, ["= 3.0.4"])
s.add_runtime_dependency(%q<open4>, [">= 0"])
s.add_runtime_dependency(%q<querybuilder>, ["= 1.1.2"])
s.add_runtime_dependency(%q<querybuilder>, ["= 1.1.3"])
else
s.add_dependency(%q<ruby-recaptcha>, ["= 1.0.3"])
s.add_dependency(%q<tzinfo>, [">= 0"])
Expand All @@ -2517,7 +2517,7 @@ Gem::Specification.new do |s|
s.add_dependency(%q<differ>, ["= 0.1.2"])
s.add_dependency(%q<RedCloth>, ["= 3.0.4"])
s.add_dependency(%q<open4>, [">= 0"])
s.add_dependency(%q<querybuilder>, ["= 1.1.2"])
s.add_dependency(%q<querybuilder>, ["= 1.1.3"])
end
else
s.add_dependency(%q<ruby-recaptcha>, ["= 1.0.3"])
Expand All @@ -2544,7 +2544,7 @@ Gem::Specification.new do |s|
s.add_dependency(%q<differ>, ["= 0.1.2"])
s.add_dependency(%q<RedCloth>, ["= 3.0.4"])
s.add_dependency(%q<open4>, [">= 0"])
s.add_dependency(%q<querybuilder>, ["= 1.1.2"])
s.add_dependency(%q<querybuilder>, ["= 1.1.3"])
end
end

0 comments on commit 5a72910

Please sign in to comment.