update to v1.3 - reportable - Fork of reportable required by WarVox, from hdm/reportable.
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
---
(DIR) commit 1b697477d79a5e17e869b4acc1f6be4330226037
(DIR) parent 80083c77564a3a852216fa1891136540ada6963b
(HTM) Author: Marco Otte-Witte <marco.otte-witte@simplabs.com>
Date: Tue, 5 May 2009 19:17:04 +0200
update to v1.3
Diffstat:
M HISTORY.rdoc | 6 ++++++
M README.rdoc | 29 +++++++++++++++++++++++++++++
M doc/classes/Simplabs/ReportsAsSpar… | 35 +++++++++++++------------------
M doc/classes/Simplabs/ReportsAsSpar… | 2 +-
M doc/classes/Simplabs/ReportsAsSpar… | 24 ++++++++++++------------
M doc/classes/Simplabs/ReportsAsSpar… | 68 ++++++++++++++++++++++++++++++-
M doc/created.rid | 2 +-
M doc/files/README_rdoc.html | 44 ++++++++++++++++++++++++++++++-
M doc/files/lib/simplabs/reports_as_… | 2 +-
M doc/files/lib/simplabs/reports_as_… | 2 +-
M doc/files/lib/simplabs/reports_as_… | 2 +-
M doc/files/lib/simplabs/reports_as_… | 2 +-
M doc/files/lib/simplabs/reports_as_… | 2 +-
M doc/fr_method_index.html | 5 +++--
M lib/simplabs/reports_as_sparkline.… | 5 -----
M lib/simplabs/reports_as_sparkline/… | 10 +++++-----
M lib/simplabs/reports_as_sparkline/… | 5 +++--
M lib/simplabs/reports_as_sparkline/… | 93 +++++++++++++++++++------------
M lib/simplabs/reports_as_sparkline/… | 28 +++++++++++++++++++---------
M spec/classes/report_cache_spec.rb | 93 +++++++++++++++++++------------
M spec/classes/report_spec.rb | 20 ++++++++++++++++++++
M spec/classes/reporting_period_spec… | 48 +++++++++++++++++++++++++++++++
M spec/db/schema.rb | 7 ++-----
23 files changed, 393 insertions(+), 141 deletions(-)
---
(DIR) diff --git a/HISTORY.rdoc b/HISTORY.rdoc
@@ -1,3 +1,9 @@
+=== v1.3
+
+* Fixed another bug where two report runs with different :end_date values would lead to invalid data
+* Entries in the report cache entry are no longer identified by the :limit the report was run with (YOU WILL HAVE TO RECREATE YOUR CACHE TABLE!)
+* rewrote the data retrieval and processing code, it's now much more compact and less complicated with fewer cache misses
+
=== v1.2
* FIXED: duplicate key error when using custom time zones (thanks to myronmarston (http://github.com/myronmarston))
(DIR) diff --git a/README.rdoc b/README.rdoc
@@ -43,6 +43,26 @@ When invoking the report, you can override some of the options you specified for
User.registrations_report(:conditions => ['last_name LIKE 'A%'])
User.activations_report(:grouping => :week, :limit => 5)
+=== The Report cache
+
+Unless you specify parameters that make it impossible to cache report results, all results will be cached. You can access the cache via the <tt>Simplabs::ReportsAsSparkline::ReportCache</tt> class.
+<b>Beware that when you modify data in the cache, report results may be incorrect or execurting reports may even fail completely!</b> To clear the cache for a specific report, use the <tt>Simplabs::ReportsAsSparkline::ReportCache.clear_for</tt>
+method.
+
+<b>Example</b>
+
+For a report defined as
+
+ class User < ActiveRecord::Base
+ reports_as_sparkline :registrations
+ end
+
+you can clear the cache with
+
+ Simplabs::ReportsAsSparkline::ReportCache.clear_for(User, :registrations)
+
+=== In your views
+
You can than render sparklines for these reports with sparkline_tag in your view:
<%= sparkline_tag(User.registrations_report) %>
@@ -91,6 +111,15 @@ If you are on PostgreSQL, you should add functional indices:
add_index :[table], :[date_column], :functional => "date_trunc('week', [date_column])"
add_index :[table], :[date_column], :functional => "date_trunc('year', [date_column])"
+You might also want to use fragment caching in your views since processing the data read from the db (either from the model's table or from the cache)
+aso takes some time.
+
+<b>Example</b>
+
+ <%- cache do -%>
+ <%= sparkline_tag(User.registrations_report) %>
+ <%- end -%>
+
== TODOs/ future plans
* support for Oracle and DB2 (and others?) missing
(DIR) diff --git a/doc/classes/Simplabs/ReportsAsSparkline/ClassMethods.html b/doc/classes/Simplabs/ReportsAsSparkline/ClassMethods.html
@@ -115,7 +115,7 @@
<p>
Generates a report on a model. That report can then be executed via the new
method <tt><name>_report</tt> (see documentation of <a
-href="Report.html#M000007">Simplabs::ReportsAsSparkline::Report#run</a>).
+href="Report.html#M000008">Simplabs::ReportsAsSparkline::Report#run</a>).
</p>
<h4>Parameters</h4>
<ul>
@@ -170,11 +170,6 @@ the <tt>:limit</tt> reporting periods until this date.
</ul>
<h4>Examples</h4>
<pre>
- class Game < ActiveRecord::Base
- reports_as_sparkline :games_per_day
- reports_as_sparkline :games_played_total, :cumulate => true
- end
-
class User < ActiveRecord::Base
reports_as_sparkline :registrations, :aggregation => :count
reports_as_sparkline :activations, :aggregation => :count, :date_column => :activated_at
@@ -186,20 +181,20 @@ the <tt>:limit</tt> reporting periods until this date.
onclick="toggleCode('M000002-source');return false;">[Source]</a></p>
<div class="method-source-code" id="M000002-source">
<pre>
- <span class="ruby-comment cmt"># File lib/simplabs/reports_as_sparkline.rb, line 41</span>
-41: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">reports_as_sparkline</span>(<span class="ruby-identifier">name</span>, <span class="ruby-identifier">options</span> = {})
-42: (<span class="ruby-keyword kw">class</span> <span class="ruby-operator"><<</span> <span class="ruby-keyword kw">self</span>; <span class="ruby-keyword kw">self</span>; <span class="ruby-keyword kw">end</span>).<span class="ruby-identifier">instance_eval</span> <span class="ruby-keyword kw">do</span>
-43: <span class="ruby-identifier">define_method</span> <span class="ruby-node">"#{name.to_s}_report"</span>.<span class="ruby-identifier">to_sym</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-operator">*</span><span class="ruby-identifier">args</span><span class="ruby-operator">|</span>
-44: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">options</span>.<span class="ruby-identifier">delete</span>(<span class="ruby-identifier">:cumulate</span>)
-45: <span class="ruby-identifier">report</span> = <span class="ruby-constant">Simplabs</span><span class="ruby-operator">::</span><span class="ruby-constant">ReportsAsSparkline</span><span class="ruby-operator">::</span><span class="ruby-constant">CumulatedReport</span>.<span class="ruby-identifier">new</span>(<span class="ruby-keyword kw">self</span>, <span class="ruby-identifier">name</span>, <span class="ruby-identifier">options</span>)
-46: <span class="ruby-keyword kw">else</span>
-47: <span class="ruby-identifier">report</span> = <span class="ruby-constant">Simplabs</span><span class="ruby-operator">::</span><span class="ruby-constant">ReportsAsSparkline</span><span class="ruby-operator">::</span><span class="ruby-constant">Report</span>.<span class="ruby-identifier">new</span>(<span class="ruby-keyword kw">self</span>, <span class="ruby-identifier">name</span>, <span class="ruby-identifier">options</span>)
-48: <span class="ruby-keyword kw">end</span>
-49: <span class="ruby-identifier">raise</span> <span class="ruby-constant">ArgumentError</span>.<span class="ruby-identifier">new</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">args</span>.<span class="ruby-identifier">length</span> <span class="ruby-operator">==</span> <span class="ruby-value">0</span> <span class="ruby-operator">||</span> (<span class="ruby-identifier">args</span>.<span class="ruby-identifier">length</span> <span class="ruby-operator">==</span> <span class="ruby-value">1</span> <span class="ruby-operator">&&</span> <span class="ruby-identifier">args</span>[<span class="ruby-value">0</span>].<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Hash</span>))
-50: <span class="ruby-identifier">report</span>.<span class="ruby-identifier">run</span>(<span class="ruby-identifier">args</span>.<span class="ruby-identifier">length</span> <span class="ruby-operator">==</span> <span class="ruby-value">0</span> <span class="ruby-operator">?</span> {} <span class="ruby-operator">:</span> <span class="ruby-identifier">args</span>[<span class="ruby-value">0</span>])
-51: <span class="ruby-keyword kw">end</span>
-52: <span class="ruby-keyword kw">end</span>
-53: <span class="ruby-keyword kw">end</span>
+ <span class="ruby-comment cmt"># File lib/simplabs/reports_as_sparkline.rb, line 36</span>
+36: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">reports_as_sparkline</span>(<span class="ruby-identifier">name</span>, <span class="ruby-identifier">options</span> = {})
+37: (<span class="ruby-keyword kw">class</span> <span class="ruby-operator"><<</span> <span class="ruby-keyword kw">self</span>; <span class="ruby-keyword kw">self</span>; <span class="ruby-keyword kw">end</span>).<span class="ruby-identifier">instance_eval</span> <span class="ruby-keyword kw">do</span>
+38: <span class="ruby-identifier">define_method</span> <span class="ruby-node">"#{name.to_s}_report"</span>.<span class="ruby-identifier">to_sym</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-operator">*</span><span class="ruby-identifier">args</span><span class="ruby-operator">|</span>
+39: <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">options</span>.<span class="ruby-identifier">delete</span>(<span class="ruby-identifier">:cumulate</span>)
+40: <span class="ruby-identifier">report</span> = <span class="ruby-constant">Simplabs</span><span class="ruby-operator">::</span><span class="ruby-constant">ReportsAsSparkline</span><span class="ruby-operator">::</span><span class="ruby-constant">CumulatedReport</span>.<span class="ruby-identifier">new</span>(<span class="ruby-keyword kw">self</span>, <span class="ruby-identifier">name</span>, <span class="ruby-identifier">options</span>)
+41: <span class="ruby-keyword kw">else</span>
+42: <span class="ruby-identifier">report</span> = <span class="ruby-constant">Simplabs</span><span class="ruby-operator">::</span><span class="ruby-constant">ReportsAsSparkline</span><span class="ruby-operator">::</span><span class="ruby-constant">Report</span>.<span class="ruby-identifier">new</span>(<span class="ruby-keyword kw">self</span>, <span class="ruby-identifier">name</span>, <span class="ruby-identifier">options</span>)
+43: <span class="ruby-keyword kw">end</span>
+44: <span class="ruby-identifier">raise</span> <span class="ruby-constant">ArgumentError</span>.<span class="ruby-identifier">new</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">args</span>.<span class="ruby-identifier">length</span> <span class="ruby-operator">==</span> <span class="ruby-value">0</span> <span class="ruby-operator">||</span> (<span class="ruby-identifier">args</span>.<span class="ruby-identifier">length</span> <span class="ruby-operator">==</span> <span class="ruby-value">1</span> <span class="ruby-operator">&&</span> <span class="ruby-identifier">args</span>[<span class="ruby-value">0</span>].<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Hash</span>))
+45: <span class="ruby-identifier">report</span>.<span class="ruby-identifier">run</span>(<span class="ruby-identifier">args</span>.<span class="ruby-identifier">length</span> <span class="ruby-operator">==</span> <span class="ruby-value">0</span> <span class="ruby-operator">?</span> {} <span class="ruby-operator">:</span> <span class="ruby-identifier">args</span>[<span class="ruby-value">0</span>])
+46: <span class="ruby-keyword kw">end</span>
+47: <span class="ruby-keyword kw">end</span>
+48: <span class="ruby-keyword kw">end</span>
</pre>
</div>
</div>
(DIR) diff --git a/doc/classes/Simplabs/ReportsAsSparkline/CumulatedReport.html b/doc/classes/Simplabs/ReportsAsSparkline/CumulatedReport.html
@@ -146,7 +146,7 @@ returns
<div class="method-description">
<p>
Runs the report (see <a
-href="Report.html#M000007">Simplabs::ReportsAsSparkline::Report#run</a>)
+href="Report.html#M000008">Simplabs::ReportsAsSparkline::Report#run</a>)
</p>
<p><a class="source-toggle" href="#"
onclick="toggleCode('M000003-source');return false;">[Source]</a></p>
(DIR) diff --git a/doc/classes/Simplabs/ReportsAsSparkline/Report.html b/doc/classes/Simplabs/ReportsAsSparkline/Report.html
@@ -93,8 +93,8 @@ and calculations
<h3 class="section-bar">Methods</h3>
<div class="name-list">
- <a href="#M000006">new</a>
- <a href="#M000007">run</a>
+ <a href="#M000007">new</a>
+ <a href="#M000008">run</a>
</div>
</div>
@@ -154,11 +154,11 @@ and calculations
<div id="methods">
<h3 class="section-bar">Public Class methods</h3>
- <div id="method-M000006" class="method-detail">
- <a name="M000006"></a>
+ <div id="method-M000007" class="method-detail">
+ <a name="M000007"></a>
<div class="method-heading">
- <a href="#M000006" class="method-signature">
+ <a href="#M000007" class="method-signature">
<span class="method-name">new</span><span class="method-args">(klass, name, options = {})</span>
</a>
</div>
@@ -221,8 +221,8 @@ the <tt>:limit</tt> reporting periods until this date.
</li>
</ul>
<p><a class="source-toggle" href="#"
- onclick="toggleCode('M000006-source');return false;">[Source]</a></p>
- <div class="method-source-code" id="M000006-source">
+ onclick="toggleCode('M000007-source');return false;">[Source]</a></p>
+ <div class="method-source-code" id="M000007-source">
<pre>
<span class="ruby-comment cmt"># File lib/simplabs/reports_as_sparkline/report.rb, line 24</span>
24: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">initialize</span>(<span class="ruby-identifier">klass</span>, <span class="ruby-identifier">name</span>, <span class="ruby-identifier">options</span> = {})
@@ -249,11 +249,11 @@ the <tt>:limit</tt> reporting periods until this date.
<h3 class="section-bar">Public Instance methods</h3>
- <div id="method-M000007" class="method-detail">
- <a name="M000007"></a>
+ <div id="method-M000008" class="method-detail">
+ <a name="M000008"></a>
<div class="method-heading">
- <a href="#M000007" class="method-signature">
+ <a href="#M000008" class="method-signature">
<span class="method-name">run</span><span class="method-args">(options = {})</span>
</a>
</div>
@@ -290,8 +290,8 @@ the <tt>:limit</tt> reporting periods until this date.
</li>
</ul>
<p><a class="source-toggle" href="#"
- onclick="toggleCode('M000007-source');return false;">[Source]</a></p>
- <div class="method-source-code" id="M000007-source">
+ onclick="toggleCode('M000008-source');return false;">[Source]</a></p>
+ <div class="method-source-code" id="M000008-source">
<pre>
<span class="ruby-comment cmt"># File lib/simplabs/reports_as_sparkline/report.rb, line 50</span>
50: <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">run</span>(<span class="ruby-identifier">options</span> = {})
(DIR) diff --git a/doc/classes/Simplabs/ReportsAsSparkline/ReportCache.html b/doc/classes/Simplabs/ReportsAsSparkline/ReportCache.html
@@ -85,8 +85,7 @@ The <a href="ReportCache.html">ReportCache</a> class is a regular
reporting periods (table name is <tt>reports_as_sparkline_cache</tt>) <a
href="ReportCache.html">ReportCache</a> instances are identified by the
combination of <tt>model_name</tt>, <tt>report_name</tt>,
-<tt>grouping</tt>, <tt>aggregation</tt>, <tt>reporting_period</tt>,
-<tt>run_limit</tt>
+<tt>grouping</tt>, <tt>aggregation</tt> and <tt>reporting_period</tt>
</p>
</div>
@@ -94,6 +93,13 @@ combination of <tt>model_name</tt>, <tt>report_name</tt>,
</div>
+ <div id="method-list">
+ <h3 class="section-bar">Methods</h3>
+
+ <div class="name-list">
+ <a href="#M000006">clear_for</a>
+ </div>
+ </div>
</div>
@@ -110,6 +116,64 @@ combination of <tt>model_name</tt>, <tt>report_name</tt>,
<!-- if method_list -->
+ <div id="methods">
+ <h3 class="section-bar">Public Class methods</h3>
+
+ <div id="method-M000006" class="method-detail">
+ <a name="M000006"></a>
+
+ <div class="method-heading">
+ <a href="#M000006" class="method-signature">
+ <span class="method-name">clear_for</span><span class="method-args">(klass, report)</span>
+ </a>
+ </div>
+
+ <div class="method-description">
+ <p>
+Clears the cache for the specified <tt>klass</tt> and <tt>report</tt>
+</p>
+<h3>Parameters</h3>
+<ul>
+<li><tt>klass</tt> - The model the report to clear the cache for works on
+
+</li>
+<li><tt>report</tt> - The name of the report to clear the cache for
+
+</li>
+</ul>
+<h3>Example</h3>
+<p>
+To clear the cache for a report defined as
+</p>
+<pre>
+ class User < ActiveRecord::Base
+ reports_as_sparkline :registrations
+ end
+</pre>
+<p>
+just do
+</p>
+<pre>
+ Simplabs::ReportsAsSparkline::ReportCache.clear_for(User, :registrations)
+</pre>
+ <p><a class="source-toggle" href="#"
+ onclick="toggleCode('M000006-source');return false;">[Source]</a></p>
+ <div class="method-source-code" id="M000006-source">
+<pre>
+ <span class="ruby-comment cmt"># File lib/simplabs/reports_as_sparkline/report_cache.rb, line 26</span>
+26: <span class="ruby-keyword kw">def</span> <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">clear_for</span>(<span class="ruby-identifier">klass</span>, <span class="ruby-identifier">report</span>)
+27: <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">delete_all</span>(<span class="ruby-identifier">:conditions</span> =<span class="ruby-operator">></span> {
+28: <span class="ruby-identifier">:model_name</span> =<span class="ruby-operator">></span> <span class="ruby-identifier">klass</span>.<span class="ruby-identifier">name</span>,
+29: <span class="ruby-identifier">:report_name</span> =<span class="ruby-operator">></span> <span class="ruby-identifier">report</span>.<span class="ruby-identifier">to_s</span>
+30: })
+31: <span class="ruby-keyword kw">end</span>
+</pre>
+ </div>
+ </div>
+ </div>
+
+
+ </div>
</div>
(DIR) diff --git a/doc/created.rid b/doc/created.rid
@@ -1 +1 @@
-Wed, 29 Apr 2009 19:32:38 +0200
+Tue, 05 May 2009 19:07:12 +0200
(DIR) diff --git a/doc/files/README_rdoc.html b/doc/files/README_rdoc.html
@@ -56,7 +56,7 @@
</tr>
<tr class="top-aligned-row">
<td><strong>Last Update:</strong></td>
- <td>Wed Apr 29 19:32:28 +0200 2009</td>
+ <td>Tue May 05 19:07:10 +0200 2009</td>
</tr>
</table>
</div>
@@ -177,6 +177,35 @@ the <tt>:limit</tt> reporting periods until this date.
User.registrations_report(:conditions => ['last_name LIKE 'A%'])
User.activations_report(:grouping => :week, :limit => 5)
</pre>
+<h3>The Report cache</h3>
+<p>
+Unless you specify parameters that make it impossible to cache report
+results, all results will be cached. You can access the cache via the
+<tt><a
+href="../classes/Simplabs/ReportsAsSparkline/ReportCache.html">Simplabs::ReportsAsSparkline::ReportCache</a></tt>
+class. <b>Beware that when you modify data in the cache, report results may
+be incorrect or execurting reports may even fail completely!</b> To clear
+the cache for a specific report, use the
+<tt>Simplabs::ReportsAsSparkline::ReportCache.clear_for</tt> method.
+</p>
+<p>
+<b>Example</b>
+</p>
+<p>
+For a report defined as
+</p>
+<pre>
+ class User < ActiveRecord::Base
+ reports_as_sparkline :registrations
+ end
+</pre>
+<p>
+you can clear the cache with
+</p>
+<pre>
+ Simplabs::ReportsAsSparkline::ReportCache.clear_for(User, :registrations)
+</pre>
+<h3>In your views</h3>
<p>
You can than render sparklines for these reports with sparkline_tag in your
view:
@@ -255,6 +284,19 @@ If you are on PostgreSQL, you should add functional indices:
add_index :[table], :[date_column], :functional => "date_trunc('week', [date_column])"
add_index :[table], :[date_column], :functional => "date_trunc('year', [date_column])"
</pre>
+<p>
+You might also want to use fragment caching in your views since processing
+the data read from the db (either from the model‘s table or from the
+cache) aso takes some time.
+</p>
+<p>
+<b>Example</b>
+</p>
+<pre>
+ <%- cache(:key => 'UserRegistrationsReport') do -%>
+ <%= sparkline_tag(User.registrations_report) %>
+ <%- end -%>
+</pre>
<h2>TODOs/ future plans</h2>
<ul>
<li>support for Oracle and DB2 (and others?) missing
(DIR) diff --git a/doc/files/lib/simplabs/reports_as_sparkline/grouping_rb.html b/doc/files/lib/simplabs/reports_as_sparkline/grouping_rb.html
@@ -56,7 +56,7 @@
</tr>
<tr class="top-aligned-row">
<td><strong>Last Update:</strong></td>
- <td>Wed Apr 29 19:18:36 +0200 2009</td>
+ <td>Tue May 05 18:20:50 +0200 2009</td>
</tr>
</table>
</div>
(DIR) diff --git a/doc/files/lib/simplabs/reports_as_sparkline/report_cache_rb.html b/doc/files/lib/simplabs/reports_as_sparkline/report_cache_rb.html
@@ -56,7 +56,7 @@
</tr>
<tr class="top-aligned-row">
<td><strong>Last Update:</strong></td>
- <td>Wed Apr 29 19:20:49 +0200 2009</td>
+ <td>Tue May 05 19:02:15 +0200 2009</td>
</tr>
</table>
</div>
(DIR) diff --git a/doc/files/lib/simplabs/reports_as_sparkline/report_rb.html b/doc/files/lib/simplabs/reports_as_sparkline/report_rb.html
@@ -56,7 +56,7 @@
</tr>
<tr class="top-aligned-row">
<td><strong>Last Update:</strong></td>
- <td>Wed Apr 29 19:26:39 +0200 2009</td>
+ <td>Tue May 05 15:51:11 +0200 2009</td>
</tr>
</table>
</div>
(DIR) diff --git a/doc/files/lib/simplabs/reports_as_sparkline/reporting_period_rb.html b/doc/files/lib/simplabs/reports_as_sparkline/reporting_period_rb.html
@@ -56,7 +56,7 @@
</tr>
<tr class="top-aligned-row">
<td><strong>Last Update:</strong></td>
- <td>Wed Apr 29 19:18:27 +0200 2009</td>
+ <td>Tue May 05 18:41:47 +0200 2009</td>
</tr>
</table>
</div>
(DIR) diff --git a/doc/files/lib/simplabs/reports_as_sparkline_rb.html b/doc/files/lib/simplabs/reports_as_sparkline_rb.html
@@ -56,7 +56,7 @@
</tr>
<tr class="top-aligned-row">
<td><strong>Last Update:</strong></td>
- <td>Wed Apr 29 19:29:22 +0200 2009</td>
+ <td>Tue May 05 19:02:42 +0200 2009</td>
</tr>
</table>
</div>
(DIR) diff --git a/doc/fr_method_index.html b/doc/fr_method_index.html
@@ -20,12 +20,13 @@
<div id="index">
<h1 class="section-bar">Methods</h1>
<div id="index-entries">
+ <a href="classes/Simplabs/ReportsAsSparkline/ReportCache.html#M000006">clear_for (Simplabs::ReportsAsSparkline::ReportCache)</a><br />
<a href="classes/Simplabs/ReportsAsSparkline/CumulatedReport.html#M000004">cumulate (Simplabs::ReportsAsSparkline::CumulatedReport)</a><br />
<a href="classes/Simplabs/ReportsAsSparkline/CumulatedReport.html#M000005">initial_cumulative_value (Simplabs::ReportsAsSparkline::CumulatedReport)</a><br />
- <a href="classes/Simplabs/ReportsAsSparkline/Report.html#M000006">new (Simplabs::ReportsAsSparkline::Report)</a><br />
+ <a href="classes/Simplabs/ReportsAsSparkline/Report.html#M000007">new (Simplabs::ReportsAsSparkline::Report)</a><br />
<a href="classes/Simplabs/ReportsAsSparkline/ClassMethods.html#M000002">reports_as_sparkline (Simplabs::ReportsAsSparkline::ClassMethods)</a><br />
<a href="classes/Simplabs/ReportsAsSparkline/CumulatedReport.html#M000003">run (Simplabs::ReportsAsSparkline::CumulatedReport)</a><br />
- <a href="classes/Simplabs/ReportsAsSparkline/Report.html#M000007">run (Simplabs::ReportsAsSparkline::Report)</a><br />
+ <a href="classes/Simplabs/ReportsAsSparkline/Report.html#M000008">run (Simplabs::ReportsAsSparkline::Report)</a><br />
<a href="classes/Simplabs/ReportsAsSparkline/SparklineTagHelper.html#M000001">sparkline_tag (Simplabs::ReportsAsSparkline::SparklineTagHelper)</a><br />
</div>
</div>
(DIR) diff --git a/lib/simplabs/reports_as_sparkline.rb b/lib/simplabs/reports_as_sparkline.rb
@@ -27,11 +27,6 @@ module Simplabs #:nodoc:
#
# ==== Examples
#
- # class Game < ActiveRecord::Base
- # reports_as_sparkline :games_per_day
- # reports_as_sparkline :games_played_total, :cumulate => true
- # end
- #
# class User < ActiveRecord::Base
# reports_as_sparkline :registrations, :aggregation => :count
# reports_as_sparkline :activations, :aggregation => :count, :date_column => :activated_at
(DIR) diff --git a/lib/simplabs/reports_as_sparkline/grouping.rb b/lib/simplabs/reports_as_sparkline/grouping.rb
@@ -14,7 +14,7 @@ module Simplabs #:nodoc:
end
def date_parts_from_db_string(db_string)
- return case ActiveRecord::Base.connection.adapter_name
+ case ActiveRecord::Base.connection.adapter_name
when /mysql/i
from_mysql_db_string(db_string)
when /sqlite/i
@@ -25,7 +25,7 @@ module Simplabs #:nodoc:
end
def to_sql(date_column) #:nodoc:
- return case ActiveRecord::Base.connection.adapter_name
+ case ActiveRecord::Base.connection.adapter_name
when /mysql/i
mysql_format(date_column)
when /sqlite/i
@@ -70,7 +70,7 @@ module Simplabs #:nodoc:
end
def mysql_format(date_column)
- return case @identifier
+ case @identifier
when :hour
"DATE_FORMAT(#{date_column}, '%Y/%m/%d/%H')"
when :day
@@ -83,7 +83,7 @@ module Simplabs #:nodoc:
end
def sqlite_format(date_column)
- return case @identifier
+ case @identifier
when :hour
"strftime('%Y/%m/%d/%H', #{date_column})"
when :day
@@ -96,7 +96,7 @@ module Simplabs #:nodoc:
end
def postgresql_format(date_column)
- return case @identifier
+ case @identifier
when :hour
"date_trunc('hour', #{date_column})"
when :day
(DIR) diff --git a/lib/simplabs/reports_as_sparkline/report.rb b/lib/simplabs/reports_as_sparkline/report.rb
@@ -70,8 +70,9 @@ module Simplabs #:nodoc:
@klass.send(@aggregation,
@value_column,
:conditions => conditions,
- :group => options[:grouping].to_sql(@date_column),
- :order => "#{options[:grouping].to_sql(@date_column)} ASC"
+ :group => options[:grouping].to_sql(@date_column),
+ :order => "#{options[:grouping].to_sql(@date_column)} ASC",
+ :limit => options[:limit]
)
end
(DIR) diff --git a/lib/simplabs/reports_as_sparkline/report_cache.rb b/lib/simplabs/reports_as_sparkline/report_cache.rb
@@ -3,32 +3,41 @@ module Simplabs #:nodoc:
module ReportsAsSparkline #:nodoc:
# The ReportCache class is a regular +ActiveRecord+ model and represents cached results for single reporting periods (table name is +reports_as_sparkline_cache+)
- # ReportCache instances are identified by the combination of +model_name+, +report_name+, +grouping+, +aggregation+, +reporting_period+, +run_limit+
+ # ReportCache instances are identified by the combination of +model_name+, +report_name+, +grouping+, +aggregation+ and +reporting_period+
class ReportCache < ActiveRecord::Base
set_table_name :reports_as_sparkline_cache
- # When reporting_period has a time zone conversion performed, we get duplicate key sql errors.
- # This occurs because find_cached_data will return a record set that is missing a record when we
- # have an end date. The SQL criteria reporting_period BETWEEN before_date AND end_date will not include
- # the last record that it should, because our end_date will not be time-zone converted (ex: 5/1/09 00:00:00) but
- # the reported_period in the database will be time-zone converted (ex: 5/1/00 07:00:00).
self.skip_time_zone_conversion_for_attributes = [:reporting_period]
+ # Clears the cache for the specified +klass+ and +report+
+ #
+ # === Parameters
+ # * <tt>klass</tt> - The model the report to clear the cache for works on
+ # * <tt>report</tt> - The name of the report to clear the cache for
+ #
+ # === Example
+ # To clear the cache for a report defined as
+ # class User < ActiveRecord::Base
+ # reports_as_sparkline :registrations
+ # end
+ # just do
+ # Simplabs::ReportsAsSparkline::ReportCache.clear_for(User, :registrations)
+ def self.clear_for(klass, report)
+ self.delete_all(:conditions => {
+ :model_name => klass.name,
+ :report_name => report.to_s
+ })
+ end
+
def self.process(report, options, cache = true, &block) #:nodoc:
raise ArgumentError.new('A block must be given') unless block_given?
self.transaction do
cached_data = []
- first_reporting_period = get_first_reporting_period(options)
- last_reporting_period = options[:end_date] ? ReportingPeriod.new(options[:grouping], options[:end_date]) : nil
-
if cache
- cached_data = find_cached_data(report, options, first_reporting_period, last_reporting_period)
- first_cached_reporting_period = cached_data.empty? ? nil : ReportingPeriod.new(options[:grouping], cached_data.first.reporting_period)
- last_cached_reporting_period = cached_data.empty? ? nil : ReportingPeriod.new(options[:grouping], cached_data.last.reporting_period)
+ cached_data = read_cached_data(report, options)
end
- new_data = read_new_data(first_reporting_period, last_reporting_period, last_cached_reporting_period, options, &block)
-
+ new_data = read_new_data(cached_data, options, &block)
prepare_result(new_data, cached_data, report, options, cache)
end
end
@@ -37,17 +46,22 @@ module Simplabs #:nodoc:
def self.prepare_result(new_data, cached_data, report, options, cache = true)
new_data = new_data.map { |data| [ReportingPeriod.from_db_string(options[:grouping], data[0]), data[1]] }
- result = cached_data.map { |cached| [cached.reporting_period, cached.value] }
- last_reporting_period = ReportingPeriod.new(options[:grouping])
- reporting_period = cached_data.empty? ? get_first_reporting_period(options) : ReportingPeriod.new(options[:grouping], cached_data.last.reporting_period).next
- while reporting_period < (options[:end_date] ? ReportingPeriod.new(options[:grouping], options[:end_date]).next : last_reporting_period)
- cached = build_cached_data(report, options[:grouping], options[:limit], reporting_period, find_value(new_data, reporting_period))
- cached.save! if cache
- result << [reporting_period.date_time, cached.value]
+ cached_data.map! { |cached| [ReportingPeriod.new(options[:grouping], cached.reporting_period), cached.value] }
+ current_reporting_period = ReportingPeriod.current(options[:grouping])
+ reporting_period = get_first_reporting_period(options)
+ result = []
+ while reporting_period < (options[:end_date] ? ReportingPeriod.new(options[:grouping], options[:end_date]).next : current_reporting_period)
+ if cached = cached_data.find { |cached| reporting_period == cached[0] }
+ result << cached
+ else
+ new_cached = build_cached_data(report, options[:grouping], reporting_period, find_value(new_data, reporting_period))
+ new_cached.save! if cache
+ result << [reporting_period.date_time, new_cached.value]
+ end
reporting_period = reporting_period.next
end
if options[:live_data]
- result << [last_reporting_period.date_time, find_value(new_data, last_reporting_period)]
+ result << [current_reporting_period.date_time, find_value(new_data, current_reporting_period)]
end
result
end
@@ -57,27 +71,27 @@ module Simplabs #:nodoc:
data ? data[1] : 0.0
end
- def self.build_cached_data(report, grouping, limit, reporting_period, value)
+ def self.build_cached_data(report, grouping, reporting_period, value)
self.new(
:model_name => report.klass.to_s,
:report_name => report.name.to_s,
:grouping => grouping.identifier.to_s,
:aggregation => report.aggregation.to_s,
:reporting_period => reporting_period.date_time,
- :value => value,
- :run_limit => limit
+ :value => value
)
end
- def self.find_cached_data(report, options, first_reporting_period, last_reporting_period)
+ def self.read_cached_data(report, options)
conditions = [
- 'model_name = ? AND report_name = ? AND grouping = ? AND aggregation = ? AND run_limit = ?',
+ 'model_name = ? AND report_name = ? AND grouping = ? AND aggregation = ?',
report.klass.to_s,
report.name.to_s,
options[:grouping].identifier.to_s,
- report.aggregation.to_s,
- options[:limit]
+ report.aggregation.to_s
]
+ first_reporting_period = get_first_reporting_period(options)
+ last_reporting_period = get_last_reporting_period(options)
if last_reporting_period
conditions.first << ' AND reporting_period BETWEEN ? AND ?'
conditions << first_reporting_period.date_time
@@ -88,17 +102,22 @@ module Simplabs #:nodoc:
end
self.all(
:conditions => conditions,
- :limit => options[:limit],
- :order => 'reporting_period ASC'
+ :limit => options[:limit],
+ :order => 'reporting_period ASC'
)
end
- def self.read_new_data(first_reporting_period, last_reporting_period, last_cached_reporting_period, options, &block)
- if !options[:live_data] && last_cached_reporting_period == ReportingPeriod.new(options[:grouping]).previous
+ def self.read_new_data(cached_data, options, &block)
+ if !options[:live_data] && cached_data.length == options[:limit]
[]
else
- end_date = options[:live_data] ? nil : (options[:end_date] ? last_reporting_period.last_date_time : nil)
- yield((last_cached_reporting_period.next rescue first_reporting_period).date_time, end_date)
+ first_reporting_period_to_read = if cached_data.length < options[:limit]
+ get_first_reporting_period(options)
+ else
+ ReportingPeriod.new(options[:grouping], cached_data.last.reporting_period).next
+ end
+ last_reporting_period_to_read = options[:end_date] ? ReportingPeriod.new(options[:grouping], options[:end_date]).last_date_time : nil
+ yield(first_reporting_period_to_read.date_time, last_reporting_period_to_read)
end
end
@@ -110,6 +129,10 @@ module Simplabs #:nodoc:
end
end
+ def self.get_last_reporting_period(options)
+ return ReportingPeriod.new(options[:grouping], options[:end_date]) if options[:end_date]
+ end
+
end
end
(DIR) diff --git a/lib/simplabs/reports_as_sparkline/reporting_period.rb b/lib/simplabs/reports_as_sparkline/reporting_period.rb
@@ -11,10 +11,18 @@ module Simplabs #:nodoc:
@date_time = parse_date_time(date_time || DateTime.now)
end
+ def offset(offset)
+ self.class.new(@grouping, @date_time + offset.send(@grouping.identifier))
+ end
+
def self.first(grouping, limit, end_date = nil)
self.new(grouping, end_date).offset(-limit)
end
+ def self.current(grouping)
+ self.new(grouping, Time.now)
+ end
+
def self.from_db_string(grouping, db_string)
parts = grouping.date_parts_from_db_string(db_string)
result = case grouping.identifier
@@ -38,22 +46,24 @@ module Simplabs #:nodoc:
self.offset(-1)
end
- def offset(offset)
- self.class.new(@grouping, @date_time + offset.send(@grouping.identifier))
- end
-
def ==(other)
- if other.class == Simplabs::ReportsAsSparkline::ReportingPeriod
- return @date_time.to_s == other.date_time.to_s && @grouping.identifier.to_s == other.grouping.identifier.to_s
+ if other.is_a?(Simplabs::ReportsAsSparkline::ReportingPeriod)
+ @date_time.to_s == other.date_time.to_s && @grouping.identifier.to_s == other.grouping.identifier.to_s
+ elsif other.is_a?(Time) || other.is_a?(DateTime)
+ @date_time == parse_date_time(other)
+ else
+ raise ArgumentError.new("Can only compare instances of #{self.class.name}")
end
- false
end
def <(other)
- if other.class == Simplabs::ReportsAsSparkline::ReportingPeriod
+ if other.is_a?(Simplabs::ReportsAsSparkline::ReportingPeriod)
return @date_time < other.date_time
+ elsif other.is_a?(Time) || other.is_a?(DateTime)
+ @date_time < parse_date_time(other)
+ else
+ raise ArgumentError.new("Can only compare instances of #{self.class.name}")
end
- raise ArgumentError.new("Can only compare instances of #{Simplabs::ReportsAsSparkline::ReportingPeriod.klass}")
end
def last_date_time
(DIR) diff --git a/spec/classes/report_cache_spec.rb b/spec/classes/report_cache_spec.rb
@@ -6,6 +6,19 @@ describe Simplabs::ReportsAsSparkline::ReportCache do
@report = Simplabs::ReportsAsSparkline::Report.new(User, :registrations, :limit => 10)
end
+ describe '.clear_for' do
+
+ it 'should delete all entries in the cache for the klass and report name' do
+ Simplabs::ReportsAsSparkline::ReportCache.should_receive(:delete_all).once.with(:conditions => {
+ :model_name => User.name,
+ :report_name => 'registrations'
+ })
+
+ Simplabs::ReportsAsSparkline::ReportCache.clear_for(User, :registrations)
+ end
+
+ end
+
describe '.process' do
before do
@@ -37,17 +50,31 @@ describe Simplabs::ReportsAsSparkline::ReportCache do
}.should raise_error(YieldMatchException)
end
- it 'should yield the reporting period after the last one in the cache if data was read from cache' do
+ it 'should yield the first reporting period if not all required data could be retrieved from the cache' do
reporting_period = Simplabs::ReportsAsSparkline::ReportingPeriod.new(
@report.options[:grouping],
Time.now - 3.send(@report.options[:grouping].identifier)
)
+ Simplabs::ReportsAsSparkline::ReportCache.stub!(:all).and_return([Simplabs::ReportsAsSparkline::ReportCache.new])
+
+ Simplabs::ReportsAsSparkline::ReportCache.process(@report, @options) do |begin_at, end_at|
+ begin_at.should == Simplabs::ReportsAsSparkline::ReportingPeriod.first(@report.options[:grouping], @report.options[:limit]).date_time
+ end_at.should == nil
+ []
+ end
+ end
+
+ it 'should yield the reporting period after the last one in the cache if all required data could be retrieved from the cache' do
+ reporting_period = Simplabs::ReportsAsSparkline::ReportingPeriod.new(
+ @report.options[:grouping],
+ Time.now - @report.options[:limit].send(@report.options[:grouping].identifier)
+ )
cached = Simplabs::ReportsAsSparkline::ReportCache.new
cached.stub!(:reporting_period).and_return(reporting_period.date_time)
- Simplabs::ReportsAsSparkline::ReportCache.stub!(:find).and_return([cached])
+ Simplabs::ReportsAsSparkline::ReportCache.stub!(:all).and_return(Array.new(@report.options[:limit] - 1, Simplabs::ReportsAsSparkline::ReportCache.new), cached)
Simplabs::ReportsAsSparkline::ReportCache.process(@report, @options) do |begin_at, end_at|
- begin_at.should == reporting_period.next.date_time
+ begin_at.should == reporting_period.date_time
end_at.should == nil
[]
end
@@ -57,75 +84,73 @@ describe Simplabs::ReportsAsSparkline::ReportCache do
describe 'with :live_data = false' do
- it 'should not yield to the block if data for the reporting period before the current one has been found in the cache' do
- cached = Simplabs::ReportsAsSparkline::ReportCache.new
- cached.stub!(:reporting_period).and_return(Simplabs::ReportsAsSparkline::ReportingPeriod.new(@report.options[:grouping]).previous)
- Simplabs::ReportsAsSparkline::ReportCache.stub!(:find).and_return([cached])
+ it 'should not yield if all required data could be retrieved from the cache' do
+ Simplabs::ReportsAsSparkline::ReportCache.stub!(:all).and_return(Array.new(@report.options[:limit], Simplabs::ReportsAsSparkline::ReportCache.new))
+
lambda {
Simplabs::ReportsAsSparkline::ReportCache.process(@report, @report.options) { raise YieldMatchException.new }
}.should_not raise_error(YieldMatchException)
end
- it 'should yield to the block if no data for the reporting period before the current one has been found in the cache' do
+ it 'should yield to the block if no data could be retrieved from the cache' do
+ Simplabs::ReportsAsSparkline::ReportCache.stub!(:all).and_return([])
+
lambda {
Simplabs::ReportsAsSparkline::ReportCache.process(@report, @report.options) { raise YieldMatchException.new }
}.should raise_error(YieldMatchException)
end
- it 'should yield the reporting period after the last one in the cache if data was read from cache' do
- reporting_period = Simplabs::ReportsAsSparkline::ReportingPeriod.new(
- @report.options[:grouping],
- Time.now - 3.send(@report.options[:grouping].identifier)
- )
- cached = Simplabs::ReportsAsSparkline::ReportCache.new
- cached.stub!(:reporting_period).and_return(reporting_period.date_time)
- Simplabs::ReportsAsSparkline::ReportCache.stub!(:find).and_return([cached])
+ describe 'with :end_date = <some date>' do
- Simplabs::ReportsAsSparkline::ReportCache.process(@report, @report.options) do |begin_at, end_at|
- begin_at.should == reporting_period.next.date_time
- end_at.should == nil
- []
+ before do
+ @options = @report.options.merge(:end_date => Time.now)
end
+
+ it 'should yield the last date and time of the reporting period for the specified end date' do
+ reporting_period = Simplabs::ReportsAsSparkline::ReportingPeriod.new(@report.options[:grouping], @options[:end_date])
+
+ Simplabs::ReportsAsSparkline::ReportCache.process(@report, @options) do |begin_at, end_at|
+ end_at.should == reporting_period.last_date_time
+ []
+ end
+ end
+
end
end
it 'should read existing data from the cache' do
- Simplabs::ReportsAsSparkline::ReportCache.should_receive(:find).once.with(
- :all,
+ Simplabs::ReportsAsSparkline::ReportCache.should_receive(:all).once.with(
:conditions => [
- 'model_name = ? AND report_name = ? AND grouping = ? AND aggregation = ? AND run_limit = ? AND reporting_period >= ?',
+ 'model_name = ? AND report_name = ? AND grouping = ? AND aggregation = ? AND reporting_period >= ?',
@report.klass.to_s,
@report.name.to_s,
@report.options[:grouping].identifier.to_s,
@report.aggregation.to_s,
- 10,
Simplabs::ReportsAsSparkline::ReportingPeriod.first(@report.options[:grouping], 10).date_time
],
:limit => 10,
:order => 'reporting_period ASC'
- )
+ ).and_return([])
Simplabs::ReportsAsSparkline::ReportCache.process(@report, @report.options) { [] }
end
it 'should utilize the end_date in the conditions' do
end_date = Time.now
- Simplabs::ReportsAsSparkline::ReportCache.should_receive(:find).once.with(
- :all,
+ Simplabs::ReportsAsSparkline::ReportCache.should_receive(:all).once.with(
:conditions => [
- 'model_name = ? AND report_name = ? AND grouping = ? AND aggregation = ? AND run_limit = ? AND reporting_period BETWEEN ? AND ?',
+ 'model_name = ? AND report_name = ? AND grouping = ? AND aggregation = ? AND reporting_period BETWEEN ? AND ?',
@report.klass.to_s,
@report.name.to_s,
@report.options[:grouping].identifier.to_s,
@report.aggregation.to_s,
- 10,
Simplabs::ReportsAsSparkline::ReportingPeriod.first(@report.options[:grouping], 9).date_time,
Simplabs::ReportsAsSparkline::ReportingPeriod.new(@report.options[:grouping], end_date).date_time
],
:limit => 10,
:order => 'reporting_period ASC'
- )
+ ).and_return([])
Simplabs::ReportsAsSparkline::ReportCache.process(@report, @report.options.merge(:end_date => end_date)) { [] }
end
@@ -135,17 +160,16 @@ describe Simplabs::ReportsAsSparkline::ReportCache do
Simplabs::ReportsAsSparkline::ReportCache.should_receive(:find).once.with(
:all,
:conditions => [
- 'model_name = ? AND report_name = ? AND grouping = ? AND aggregation = ? AND run_limit = ? AND reporting_period >= ?',
+ 'model_name = ? AND report_name = ? AND grouping = ? AND aggregation = ? AND reporting_period >= ?',
@report.klass.to_s,
@report.name.to_s,
grouping.identifier.to_s,
@report.aggregation.to_s,
- 10,
Simplabs::ReportsAsSparkline::ReportingPeriod.first(grouping, 10).date_time
],
:limit => 10,
:order => 'reporting_period ASC'
- )
+ ).and_return([])
Simplabs::ReportsAsSparkline::ReportCache.process(@report, { :limit => 10, :grouping => grouping }) { [] }
end
@@ -193,7 +217,6 @@ describe Simplabs::ReportsAsSparkline::ReportCache do
Simplabs::ReportsAsSparkline::ReportCache.should_receive(:build_cached_data).exactly(10).times.with(
@report,
@report.options[:grouping],
- 10,
anything(),
0.0
).and_return(@cached)
@@ -205,14 +228,12 @@ describe Simplabs::ReportsAsSparkline::ReportCache do
Simplabs::ReportsAsSparkline::ReportCache.should_receive(:build_cached_data).exactly(9).times.with(
@report,
@report.options[:grouping],
- 10,
anything(),
0.0
).and_return(@cached)
Simplabs::ReportsAsSparkline::ReportCache.should_receive(:build_cached_data).once.with(
@report,
@report.options[:grouping],
- 10,
@current_reporting_period.previous,
1.0
).and_return(@cached)
(DIR) diff --git a/spec/classes/report_spec.rb b/spec/classes/report_spec.rb
@@ -321,6 +321,26 @@ describe Simplabs::ReportsAsSparkline::Report do
result[6][1].should == 0.0
end
+ it 'should return correct results when run twice in a row with an end date further in the past on the second run' do
+ @report = Simplabs::ReportsAsSparkline::Report.new(User, :registrations,
+ :aggregation => :count,
+ :grouping => grouping,
+ :limit => 10,
+ :live_data => live_data
+ )
+ result = @report.run(:end_date => Time.now - 1.send(grouping)).to_a
+
+ result[9][1].should == 1.0
+ result[8][1].should == 0.0
+ result[7][1].should == 2.0
+
+ result = @report.run(:end_date => Time.now - 3.send(grouping)).to_a
+
+ result[9][1].should == 2.0
+ result[8][1].should == 0.0
+ result[7][1].should == 0.0
+ end
+
end
end
(DIR) diff --git a/spec/classes/reporting_period_spec.rb b/spec/classes/reporting_period_spec.rb
@@ -245,6 +245,54 @@ describe Simplabs::ReportsAsSparkline::ReportingPeriod do
(reporting_period1 == reporting_period2).should == false
end
+ describe 'when invoked with DateTimes or Times' do
+
+ describe 'for grouping :hour' do
+
+ it 'should return true when the date and hour are equal' do
+ date_time = DateTime.new(2008, 10, 30, 12)
+ reporting_period = Simplabs::ReportsAsSparkline::ReportingPeriod.new(Simplabs::ReportsAsSparkline::Grouping.new(:hour), date_time)
+
+ reporting_period.should == date_time
+ end
+
+ end
+
+ describe 'for grouping :day' do
+
+ it 'should return true when the date is equal' do
+ date_time = DateTime.new(2008, 10, 30)
+ reporting_period = Simplabs::ReportsAsSparkline::ReportingPeriod.new(Simplabs::ReportsAsSparkline::Grouping.new(:day), date_time)
+
+ reporting_period.should == date_time
+ end
+
+ end
+
+ describe 'for grouping :week' do
+
+ it 'should return true when the date of the first day in that week is equal' do
+ date_time = DateTime.new(2009, 5, 4) #monday (first day of the week for reports_asp_sparkline)
+ reporting_period = Simplabs::ReportsAsSparkline::ReportingPeriod.new(Simplabs::ReportsAsSparkline::Grouping.new(:week), date_time)
+
+ reporting_period.should == DateTime.new(2009, 5, 7) #thursday of same week, should be equal
+ end
+
+ end
+
+ describe 'for grouping :month' do
+
+ it 'should return true when the date of the first day in that month is equal' do
+ date_time = DateTime.new(2009, 5, 1)
+ reporting_period = Simplabs::ReportsAsSparkline::ReportingPeriod.new(Simplabs::ReportsAsSparkline::Grouping.new(:month), date_time)
+
+ reporting_period.should == DateTime.new(2009, 5, 17)
+ end
+
+ end
+
+ end
+
end
describe '.first' do
(DIR) diff --git a/spec/db/schema.rb b/spec/db/schema.rb
@@ -15,7 +15,6 @@ ActiveRecord::Schema.define(:version => 1) do
t.string :aggregation, :null => false
t.float :value, :null => false, :default => 0
t.datetime :reporting_period, :null => false
- t.integer :run_limit, :null => false
t.timestamps
end
@@ -23,16 +22,14 @@ ActiveRecord::Schema.define(:version => 1) do
:model_name,
:report_name,
:grouping,
- :aggregation,
- :run_limit
+ :aggregation
], :name => :name_model_grouping_agregation_run_limit
add_index :reports_as_sparkline_cache, [
:model_name,
:report_name,
:grouping,
:aggregation,
- :reporting_period,
- :run_limit
+ :reporting_period
], :unique => true, :name => :name_model_grouping_aggregation_period_run_limit
end