admin_data 1.1.12 → 1.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|