admin_data 1.1.12 → 1.1.13
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/Gemfile.lock +1 -1
- data/README.md +1 -1
- data/app/controllers/admin_data/analytics_controller.rb +38 -0
- data/app/controllers/admin_data/public_controller.rb +2 -0
- data/app/controllers/admin_data/search_controller.rb +10 -5
- data/app/helpers/admin_data/application_helper.rb +21 -0
- data/app/views/admin_data/analytics/_bar_chart.html.erb +39 -0
- data/app/views/admin_data/analytics/index.html.erb +41 -0
- data/app/views/admin_data/search/search/_advance_search_form.html.erb +1 -7
- data/app/views/admin_data/search/search/_listing.html.erb +4 -2
- data/app/views/admin_data/search/search/_search_form.html.erb +0 -1
- data/app/views/admin_data/shared/_secondary_navigation.html.erb +5 -0
- data/app/views/layouts/admin_data.html.erb +4 -1
- data/config/routes.rb +8 -5
- data/lib/admin_data/analytics.rb +176 -0
- data/lib/admin_data/exceptions.rb +5 -0
- data/lib/admin_data/search.rb +139 -137
- data/lib/admin_data/version.rb +1 -1
- data/lib/admin_data.rb +3 -0
- data/lib/public/images/sort_by_asc.jpg +0 -0
- data/lib/public/images/sort_by_desc.jpg +0 -0
- data/lib/public/images/sort_by_nothing.jpg +0 -0
- data/lib/public/javascripts/advance_search/sortby.js +14 -0
- data/lib/public/javascripts/analytics/report.js +7 -0
- data/lib/public/stylesheets/base.css +25 -1
- data/test/rails_root/Gemfile +15 -12
- data/test/rails_root/Gemfile.lock +8 -2
- data/test/rails_root/README.md +16 -8
- data/test/rails_root/app/models/car.rb +3 -0
- data/test/rails_root/config/application.rb +0 -27
- data/test/rails_root/config/cucumber.yml +0 -2
- data/test/rails_root/config/database.yml.mysql +22 -0
- data/test/rails_root/config/database.yml.pg +15 -0
- data/test/rails_root/config/{database.yml → database.yml.sqlite3} +1 -1
- data/test/rails_root/db/development.sqlite3 +0 -0
- data/test/rails_root/db/migrate/{20091030202259_create_users.rb → 20091030202259_create_tables.rb} +7 -1
- data/test/rails_root/db/schema.rb +6 -0
- data/test/rails_root/features/quick_search.feature +0 -11
- data/test/rails_root/lib/tasks/dbs.rake +30 -0
- data/test/rails_root/lib/tasks/sample_cars.rake +18 -0
- data/test/rails_root/test/unit/car_test.rb +100 -0
- metadata +30 -13
- data/app/views/admin_data/search/search/_sortby.html.erb +0 -19
- data/test/rails_root/features/advance_search/sort.feature +0 -16
- data/test/rails_root/test/performance/browsing_test.rb +0 -9
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -0,0 +1,38 @@
|
|
1
|
+
module AdminData
|
2
|
+
class AnalyticsController < ApplicationController
|
3
|
+
|
4
|
+
before_filter :get_class_from_params
|
5
|
+
before_filter :set_ivars
|
6
|
+
|
7
|
+
rescue_from AdminData::NoCreatedAtColumnException, :with => :render_no_created_at
|
8
|
+
|
9
|
+
def render_no_created_at
|
10
|
+
render :text => "Model #{@klass} does not have created_at column"
|
11
|
+
end
|
12
|
+
|
13
|
+
def daily
|
14
|
+
@chart_title = "#{@klass.name} records created in the last 30 days"
|
15
|
+
|
16
|
+
a = AdminData::Analytics.daily_report(@klass, Time.now)
|
17
|
+
@chart_data_s = a.map {|e| e.last }.join(', ')
|
18
|
+
@chart_data_x_axis = a.map {|e| e.first}.join(', ')
|
19
|
+
render :action => 'index'
|
20
|
+
end
|
21
|
+
|
22
|
+
def monthly
|
23
|
+
@chart_title = "#{@klass.name} rercords created last year"
|
24
|
+
a = AdminData::Analytics.monthly_report(@klass, Time.now)
|
25
|
+
@chart_data_s = a.map {|e| e.last }.join(', ')
|
26
|
+
@chart_data_x_axis = a.map {|e| e.first}.join(', ')
|
27
|
+
render :action => 'index'
|
28
|
+
end
|
29
|
+
|
30
|
+
def set_ivars
|
31
|
+
@chart_width = 950
|
32
|
+
@chart_height = 400
|
33
|
+
@chart_h_axis_title = ''
|
34
|
+
@chart_legend_name = 'Created'
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require File.join(AdminData::LIBPATH, 'admin_data', 'search')
|
2
|
-
|
3
1
|
class SearchAction
|
4
2
|
attr_accessor :relation, :success_message
|
5
3
|
|
@@ -27,12 +25,13 @@ module AdminData
|
|
27
25
|
|
28
26
|
layout 'search'
|
29
27
|
|
30
|
-
include Search
|
28
|
+
include AdminData::Search
|
31
29
|
|
32
30
|
before_filter :get_class_from_params
|
33
31
|
before_filter :ensure_valid_children_klass, :only => [:quick_search]
|
34
32
|
before_filter :ensure_is_authorized_for_update_opration, :only => [:advance_search]
|
35
33
|
before_filter :set_column_type_info, :only => [:advance_search]
|
34
|
+
before_filter :handle_sorting
|
36
35
|
|
37
36
|
|
38
37
|
def quick_search
|
@@ -48,7 +47,7 @@ module AdminData
|
|
48
47
|
@records = has_many_proxy.send(:paginate, h)
|
49
48
|
else
|
50
49
|
params[:query] = params[:query].strip unless params[:query].blank?
|
51
|
-
cond =
|
50
|
+
cond = build_quick_search_condition(@klass, params[:query])
|
52
51
|
h = { :page => params[:page], :per_page => per_page, :order => order, :conditions => cond }
|
53
52
|
@records = @klass.unscoped.paginate(h)
|
54
53
|
end
|
@@ -58,7 +57,7 @@ module AdminData
|
|
58
57
|
|
59
58
|
def advance_search
|
60
59
|
@page_title = "Advance search #{@klass.name.underscore}"
|
61
|
-
hash =
|
60
|
+
hash = build_advance_search_condition(@klass, params[:adv_search])
|
62
61
|
relation = hash[:cond]
|
63
62
|
errors = hash[:errors]
|
64
63
|
order = default_order
|
@@ -134,5 +133,11 @@ module AdminData
|
|
134
133
|
@column_type_info = "{#{column_type_info}}"
|
135
134
|
end
|
136
135
|
|
136
|
+
def handle_sorting
|
137
|
+
sort_order = params[:sortby] || 'id desc'
|
138
|
+
@sort_by_column_name, @sort_order = sort_order.split
|
139
|
+
@sort_css = @sort_order == 'asc' ? 'sort_by_asc' : 'sort_by_desc'
|
140
|
+
end
|
141
|
+
|
137
142
|
end
|
138
143
|
end
|
@@ -1,6 +1,27 @@
|
|
1
1
|
module AdminData
|
2
2
|
module ApplicationHelper
|
3
3
|
|
4
|
+
def get_sort_order(column)
|
5
|
+
if column == @sort_by_column_name && @sort_order == 'desc'
|
6
|
+
"#{column} asc"
|
7
|
+
else
|
8
|
+
"#{column} desc"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def get_sort_title_with_url(column, klass)
|
13
|
+
order = get_sort_order(column)
|
14
|
+
link_to column_title(klass, column), admin_data_search_path(:klass => klass, :query => params[:query], :sortby => order)
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_sort_class(column)
|
18
|
+
sort_class = 'sortable'
|
19
|
+
if column == @sort_by_column_name
|
20
|
+
sort_class << ' ' + @sort_css
|
21
|
+
end
|
22
|
+
sort_class
|
23
|
+
end
|
24
|
+
|
4
25
|
def parent_layout(layout)
|
5
26
|
@_content_for[:layout] = self.output_buffer
|
6
27
|
self.output_buffer = render(:file => "layouts/#{layout}")
|
@@ -0,0 +1,39 @@
|
|
1
|
+
|
2
|
+
<%= javascript_include_tag "https://www.google.com/jsapi" %>
|
3
|
+
<script>
|
4
|
+
google.load('visualization', '1', {'packages':['corechart']});
|
5
|
+
google.setOnLoadCallback(drawChart);
|
6
|
+
|
7
|
+
function drawChart() {
|
8
|
+
|
9
|
+
var data = new google.visualization.DataTable();
|
10
|
+
var raw_data = [['<%= chart_legend_name %>', <%= chart_data_s %>]];
|
11
|
+
|
12
|
+
var years = [<%= chart_data_x_axis %>];
|
13
|
+
|
14
|
+
data.addColumn('string', 'Year');
|
15
|
+
for (var i = 0; i < raw_data.length; ++i) {
|
16
|
+
data.addColumn('number', raw_data[i][0]);
|
17
|
+
}
|
18
|
+
|
19
|
+
data.addRows(years.length);
|
20
|
+
|
21
|
+
for (var j = 0; j < years.length; ++j) {
|
22
|
+
data.setValue(j, 0, years[j].toString());
|
23
|
+
}
|
24
|
+
|
25
|
+
for (var i = 0; i < raw_data.length; ++i) {
|
26
|
+
for (var j = 1; j < raw_data[i].length; ++j) {
|
27
|
+
data.setValue(j-1, i+1, raw_data[i][j]);
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
// Create and draw the visualization.
|
32
|
+
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
|
33
|
+
chart.draw(data,
|
34
|
+
{ title: '<%= chart_title %>',
|
35
|
+
width: <%= chart_width %>,
|
36
|
+
height: <%= chart_height %>,
|
37
|
+
hAxis: {title: '<%= chart_h_axis_title %>'}});
|
38
|
+
}
|
39
|
+
</script>
|
@@ -0,0 +1,41 @@
|
|
1
|
+
<%= render 'bar_chart', :chart_title => @chart_title,
|
2
|
+
:chart_h_axis_title => @chart_h_axis_title,
|
3
|
+
:chart_legend_name => @chart_legend_name,
|
4
|
+
:chart_data_s => @chart_data_s,
|
5
|
+
:chart_data_x_axis => @chart_data_x_axis,
|
6
|
+
:chart_width => @chart_width,
|
7
|
+
:chart_height => @chart_height %>
|
8
|
+
|
9
|
+
<div id="main">
|
10
|
+
|
11
|
+
<%= breadcrum do %>
|
12
|
+
<%= link_to @klass, admin_data_search_path(:klass => @klass.name) %>
|
13
|
+
<% end %>
|
14
|
+
|
15
|
+
<%= render 'admin_data/shared/flash_message', :model => @model %>
|
16
|
+
|
17
|
+
<div class="block" id="block-tables">
|
18
|
+
<div class="secondary-navigation">
|
19
|
+
<%= render 'admin_data/shared/secondary_navigation', :klass => @klass %>
|
20
|
+
<div class="clear"></div>
|
21
|
+
</div>
|
22
|
+
<div class="content rounded">
|
23
|
+
<div>
|
24
|
+
<h2 class="title" style='float:left;'>Analytics</h2>
|
25
|
+
|
26
|
+
<div style='float:left;margin-top:18px;margin-left:20px;'>
|
27
|
+
<%= radio_button_tag :report_type, admin_data_daily_analytics_path(:klass => @klass), params[:action] == 'daily' %> Daily
|
28
|
+
|
29
|
+
<%= radio_button_tag :report_type, admin_data_monthly_analytics_path(:klass => @klass), params[:action] == 'monthly' %> Monthly
|
30
|
+
</div>
|
31
|
+
<div style='clear:both;'></div>
|
32
|
+
</div>
|
33
|
+
|
34
|
+
|
35
|
+
<div class="inner">
|
36
|
+
<div id="chart_div"></div>
|
37
|
+
|
38
|
+
</div>
|
39
|
+
</div>
|
40
|
+
</div>
|
41
|
+
</div>
|
@@ -6,15 +6,9 @@
|
|
6
6
|
<div id='advance_search' class='search_box'>
|
7
7
|
<table id='advance_search_table' class='advtable'>
|
8
8
|
</table>
|
9
|
+
<input type="hidden" id="advance_search_sortby" name="sortby" value="<%=params[:sortby]%>" />
|
9
10
|
|
10
11
|
<div class='sortby_umbrella'>
|
11
|
-
<div class='group'>
|
12
|
-
<div class='sortby_text'>Sort by</div>
|
13
|
-
<select name='sortby' id='sortby'>
|
14
|
-
<%= AdminData::Util.build_sort_options(klass,params[:sortby]).html_safe %>
|
15
|
-
</select>
|
16
|
-
<br />
|
17
|
-
</div>
|
18
12
|
<div class='clear'></div>
|
19
13
|
<input type="submit" value="Search" class='submit_search' />
|
20
14
|
</div>
|
@@ -10,9 +10,11 @@
|
|
10
10
|
<table cellspacing="3" cellpadding="3" id="view_table" class='table colorize'>
|
11
11
|
|
12
12
|
<thead>
|
13
|
-
<tr>
|
13
|
+
<tr class='thead'>
|
14
14
|
<% columns_order(klass).each do |column| %>
|
15
|
-
<th
|
15
|
+
<th class='<%=get_sort_class(column)%>' data-sortby='<%=get_sort_order(column)%>'>
|
16
|
+
<%= get_sort_title_with_url(column, klass) %>
|
17
|
+
</th>
|
16
18
|
<% end %>
|
17
19
|
</tr>
|
18
20
|
</thead>
|
@@ -4,7 +4,6 @@
|
|
4
4
|
<div id='quick_search'>
|
5
5
|
<label class='label keyword_label'>Search keyword</label>
|
6
6
|
<input type="text" id="quick_search_input" name="query" value="<%=params[:query]%>" />
|
7
|
-
<%= render :partial => 'admin_data/search/search/sortby', :locals => {:klass => klass} %>
|
8
7
|
<div class='clear'></div>
|
9
8
|
<%= submit_tag 'Search', :name => nil, :disable_with => 'searching ...', :class => 'submit_search' %>
|
10
9
|
</div>
|
@@ -1,6 +1,7 @@
|
|
1
1
|
<%
|
2
2
|
quick_search_tab_active = params[:action] == 'quick_search' ? 'active' : ''
|
3
3
|
advance_search_tab_active = params[:action] == 'advance_search' ? 'active' : ''
|
4
|
+
analytics_tab_active = params[:controller] == 'admin_data/analytics' ? 'active' : ''
|
4
5
|
table_structure_tab_active = params[:controller] == 'admin_data/table_structure' ? 'active' : ''
|
5
6
|
add_new_record_tab_active = %w(new create).include?(params[:action]) ? 'active' : ''
|
6
7
|
%>
|
@@ -14,6 +15,10 @@
|
|
14
15
|
<%= link_to 'Advance Search', admin_data_advance_search_path(:klass => klass.name.underscore) %>
|
15
16
|
</li>
|
16
17
|
|
18
|
+
<li class="<%=analytics_tab_active%>">
|
19
|
+
<%= link_to 'Analytics', admin_data_daily_analytics_path(:klass => klass.name.underscore) %>
|
20
|
+
</li>
|
21
|
+
|
17
22
|
<li class="<%=table_structure_tab_active%>">
|
18
23
|
<%= link_to 'Table Structure', admin_data_table_structure_path(:klass => klass.name.underscore) %>
|
19
24
|
</li>
|
@@ -29,8 +29,11 @@
|
|
29
29
|
'advance_search/act_on_result',
|
30
30
|
'advance_search/build_first_row',
|
31
31
|
'advance_search/event_bindings',
|
32
|
-
'advance_search/trigger_submit_on_domready'
|
32
|
+
'advance_search/trigger_submit_on_domready',
|
33
|
+
'advance_search/sortby'
|
33
34
|
) %>
|
35
|
+
<% elsif params[:controller] == 'admin_data/analytics' %>
|
36
|
+
<%= javascript_include_tag('analytics/report') %>
|
34
37
|
<% end %>
|
35
38
|
|
36
39
|
<%= csrf_meta_tag %>
|
data/config/routes.rb
CHANGED
@@ -19,15 +19,18 @@ Rails.application.routes.draw do
|
|
19
19
|
match '/jstest', :to => :jstest, :as => :jstest
|
20
20
|
end
|
21
21
|
|
22
|
-
match '/table_structure/:klass' => "table_structure#index",
|
22
|
+
match '/table_structure/:klass' => "table_structure#index", :as => :table_structure
|
23
23
|
|
24
|
-
match '/quick_search/:klass'
|
24
|
+
match '/quick_search/:klass' => "search#quick_search", :as => :search
|
25
25
|
|
26
|
-
match '/advance_search/:klass'
|
26
|
+
match '/advance_search/:klass' => "search#advance_search", :as => :advance_search
|
27
27
|
|
28
|
-
match '/
|
28
|
+
match '/analytics/daily/:klass' => "analytics#daily", :as => :daily_analytics
|
29
|
+
match '/analytics/monthly/:klass' => "analytics#monthly", :as => :monthly_analytics
|
29
30
|
|
30
|
-
match '/
|
31
|
+
match '/feed/:klasss' => "feed#index", :defaults => { :format =>'rss' }, :as => :feed
|
32
|
+
|
33
|
+
match '/public/*file' => "public#serve", :as => :public
|
31
34
|
|
32
35
|
root :to => "home#index"
|
33
36
|
end
|
@@ -0,0 +1,176 @@
|
|
1
|
+
require "active_support/all"
|
2
|
+
|
3
|
+
module AdminData
|
4
|
+
module Analytics
|
5
|
+
|
6
|
+
# a utility class to handle date interpolation for different databases
|
7
|
+
class Dater
|
8
|
+
attr_accessor :adapter, :type
|
9
|
+
|
10
|
+
def initialize(adapter, type = 'daily')
|
11
|
+
@adapter = adapter
|
12
|
+
@type = type
|
13
|
+
end
|
14
|
+
|
15
|
+
def date_select_key
|
16
|
+
"date_data"
|
17
|
+
end
|
18
|
+
|
19
|
+
def group_by_key
|
20
|
+
if adapter =~ /postgresql/i
|
21
|
+
self.type == 'monthly' ? "date_part('year', created_at), date_part('month', created_at)" : "date_data"
|
22
|
+
elsif adapter =~ /mysql/i
|
23
|
+
self.type == 'monthly' ? "YEAR(created_at), MONTH(created_at)" : "date_data"
|
24
|
+
else
|
25
|
+
self.type == 'monthly' ? "strftime('%Y', created_at), strftime('%m', created_at)" : "date_data"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def count_select_key
|
30
|
+
"count_data"
|
31
|
+
end
|
32
|
+
|
33
|
+
def count_function
|
34
|
+
"count(*) as count_data"
|
35
|
+
end
|
36
|
+
|
37
|
+
def date_select_function
|
38
|
+
self.type == 'monthly' ? date_select_function_monthly : date_select_function_daily
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def date_select_function_monthly
|
44
|
+
if adapter =~ /mysql/i
|
45
|
+
"MONTH(created_at) as date_data"
|
46
|
+
elsif adapter =~ /postgresql/i
|
47
|
+
"date_part('month', created_at) as date_data"
|
48
|
+
else
|
49
|
+
"strftime('%m', created_at) as date_data"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def date_select_function_daily
|
54
|
+
if adapter =~ /mysql/i
|
55
|
+
"date_format(created_at, '%Y-%m-%d') as date_data"
|
56
|
+
else
|
57
|
+
"date(created_at) as date_data"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.monthly_report(klass, end_date)
|
64
|
+
begin_date = end_date.ago(1.year)
|
65
|
+
raise "begin_date should not be after end_date" if begin_date > end_date
|
66
|
+
raise AdminData::NoCreatedAtColumnException unless klass.columns.find {|r| r.name == 'created_at'}
|
67
|
+
|
68
|
+
begin_date = begin_date.beginning_of_day
|
69
|
+
end_date = end_date.end_of_day
|
70
|
+
|
71
|
+
dater = Dater.new(ActiveRecord::Base.connection.adapter_name, 'monthly')
|
72
|
+
|
73
|
+
query = klass.unscoped
|
74
|
+
query = query.where(["created_at >= ?", begin_date])
|
75
|
+
query = query.where(["created_at <= ?", end_date])
|
76
|
+
query = query.group(dater.group_by_key)
|
77
|
+
query = query.select(dater.date_select_function)
|
78
|
+
query = query.select(dater.count_function)
|
79
|
+
debug "sql: " + query.to_sql
|
80
|
+
result = query.all
|
81
|
+
debug "sql result: #{result.inspect}"
|
82
|
+
|
83
|
+
extract_data_from_result_set_monthly(result, dater, begin_date, end_date)
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.extract_data_from_result_set_monthly(result, dater, begin_date, end_date)
|
87
|
+
debug "extracting from result set now"
|
88
|
+
result_hash = {}
|
89
|
+
result.each do |record|
|
90
|
+
result_hash.merge!(record[dater.date_select_key].to_i => record[dater.count_select_key])
|
91
|
+
end
|
92
|
+
|
93
|
+
debug "result_hash.inspect is #{result_hash.inspect}"
|
94
|
+
|
95
|
+
current_month = begin_date.strftime('%m').to_i
|
96
|
+
months_order = (1..current_month).to_a.reverse + (current_month..12).to_a.reverse
|
97
|
+
months_order.uniq!.reverse!
|
98
|
+
|
99
|
+
debug "months order is #{months_order.inspect}"
|
100
|
+
|
101
|
+
final_hash = ActiveSupport::OrderedHash.new
|
102
|
+
months_order.each do |month|
|
103
|
+
month = month.to_i #sqlite3 has months as 03 instead of 3
|
104
|
+
m = Time.now.change(:month => month)
|
105
|
+
m = m.ago(1.year) if month > current_month
|
106
|
+
|
107
|
+
key = m.strftime('%b-%Y')
|
108
|
+
key = "'#{key}'"
|
109
|
+
if dater.adapter =~ /postgresql/i
|
110
|
+
value = result_hash[month]
|
111
|
+
elsif dater.adapter =~ /mysql/i
|
112
|
+
value = result_hash[month]
|
113
|
+
else
|
114
|
+
value = result_hash[month]
|
115
|
+
end
|
116
|
+
value = value.to_i
|
117
|
+
debug "month: #{month} key: #{key} value: #{value}"
|
118
|
+
final_hash.merge!(key => value)
|
119
|
+
end
|
120
|
+
|
121
|
+
final_hash.to_a.tap {|e| debug e.inspect }
|
122
|
+
end
|
123
|
+
|
124
|
+
def self.daily_report(klass, end_date)
|
125
|
+
begin_date = end_date.ago(1.month)
|
126
|
+
raise "begin_date should not be after end_date" if begin_date > end_date
|
127
|
+
raise AdminData::NoCreatedAtColumnException unless klass.columns.find {|r| r.name == 'created_at'}
|
128
|
+
|
129
|
+
begin_date = begin_date.beginning_of_day
|
130
|
+
end_date = end_date.end_of_day
|
131
|
+
|
132
|
+
dater = Dater.new(ActiveRecord::Base.connection.adapter_name)
|
133
|
+
|
134
|
+
query = klass.unscoped
|
135
|
+
query = query.where(["created_at >= ?", begin_date])
|
136
|
+
query = query.where(["created_at <= ?", end_date])
|
137
|
+
query = query.group(dater.group_by_key)
|
138
|
+
query = query.select(dater.date_select_function)
|
139
|
+
query = query.select(dater.count_function)
|
140
|
+
debug "sql: " + query.to_sql
|
141
|
+
result = query.all
|
142
|
+
debug "sql result: #{result.inspect}"
|
143
|
+
|
144
|
+
extract_data_from_result_set_daily(result, dater, begin_date, end_date).tap {|e| debug "formatted output: "+e.inspect}
|
145
|
+
end
|
146
|
+
|
147
|
+
def self.extract_data_from_result_set_daily(result, dater, begin_date, end_date)
|
148
|
+
count = result.map {|r| r[dater.count_select_key] }
|
149
|
+
dates = result.map {|r| r[dater.date_select_key] }
|
150
|
+
|
151
|
+
debug "count is: #{count.inspect}"
|
152
|
+
debug "dates is: #{dates.inspect}"
|
153
|
+
|
154
|
+
final_output= []
|
155
|
+
|
156
|
+
while(begin_date) do
|
157
|
+
s = begin_date.strftime('%Y-%m-%d')
|
158
|
+
final_count = if index = dates.index(s)
|
159
|
+
count[index].to_i
|
160
|
+
else
|
161
|
+
0
|
162
|
+
end
|
163
|
+
final_output << ["'#{s}'", final_count]
|
164
|
+
begin_date = begin_date.tomorrow
|
165
|
+
break if begin_date > end_date
|
166
|
+
end
|
167
|
+
final_output
|
168
|
+
end
|
169
|
+
|
170
|
+
def self.debug(msg)
|
171
|
+
puts msg
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|