]> pilppa.org Git - libplp.git/blob - src/DataReader.cc
Nullpointer bug fix if device's datastore was empty while reading data.
[libplp.git] / src / DataReader.cc
1 /*
2  * DataReader.cc
3  *
4  *  Created on: Nov 7, 2010
5  *      Author: lamikr
6  */
7 #include <sstream>
8
9 #include <dirent.h>
10 #include <malloc.h>
11 #include <errno.h>
12 #include <string.h>
13
14 #include "log.h"
15
16 #include "DataReader.hh"
17 #include "DeviceConfig.hh"
18 #include "FileUtil.hh"
19 #include "StoreDay.hh"
20 #include "StoreCache.hh"
21
22 using namespace std;
23 using namespace plp;
24
25 template <class NumberDataType>
26 bool string_to_number(NumberDataType& result,
27                  const std::string& string_param,
28                  std::ios_base& (*format)(std::ios_base&))
29 {
30         istringstream iss(string_param);
31         return !(iss >> format >> result).fail();
32 }
33
34 DataReader::DataReader(string device_id_param) {
35         string  base_dir;
36
37         device_config   = NULL;
38         device_id       = device_id_param;
39         base_dir        = DeviceConfig::get_base_dir_name();
40         device_dir      = FileUtil::concat_paths(base_dir, device_id);
41         device_ch_dir   = FileUtil::concat_paths(base_dir, "cache");
42         device_ch_dir   = FileUtil::concat_paths(device_ch_dir, device_id);
43 }
44
45 DataReader::~DataReader() {
46         if (device_config != NULL) {
47                 delete(device_config);
48                 device_config   = NULL;
49         }
50 }
51
52 Data *DataReader::find_latest_data(vector<string> year_name_vector_param) {
53         string  year_name;
54         int     size;
55         Data    *ret_val;
56         Date    date;
57         int     val_int;
58
59         ret_val = NULL;
60         size    = year_name_vector_param.size();
61         if (size > 0) {
62                 // dirs are alphabetically sorted
63                 year_name       = year_name_vector_param.at(size - 1);
64                 string_to_number<int>(val_int, year_name, dec);
65                 date.year       = val_int;
66                 ret_val         = StoreCache::get_latest_data(&date, device_id, PERIOD_YEARLY);
67         }
68         return ret_val;
69 }
70
71 Data *DataReader::get_latest_data() {
72         vector<string>  y_list;
73         Data            *ret_val;
74
75         ret_val = NULL;
76         y_list  = FileUtil::get_subdirectories(device_dir);
77         if (y_list.size() > 0) {
78                 ret_val = find_latest_data(y_list);
79         }
80         return ret_val;
81 }
82
83 Data *DataReader::find_oldest_data(vector<string> year_name_vector_param) {
84         int     size;
85         string  year_name;
86         Data    *ret_val;
87         Date    date;
88         int     val_int;
89
90         ret_val = NULL;
91         size    = year_name_vector_param.size();
92         if (size > 0) {
93                 // dirs are alphabetically sorted
94                 year_name       = year_name_vector_param.at(0);
95                 string_to_number<int>(val_int, year_name, dec);
96                 date.year       = val_int;
97                 ret_val         = StoreCache::get_oldest_data(&date, device_id, PERIOD_YEARLY);
98         }
99         return ret_val;
100 }
101
102 DataRange *DataReader::get_data_range() {
103         DataRange       *ret_val;
104         vector<string>  y_list;
105         Data            *o_data;
106         Data            *n_data;
107
108         ret_val = NULL;
109         y_list  = FileUtil::get_subdirectories(device_dir);
110         o_data  = find_oldest_data(y_list);
111         if (o_data != NULL) {
112                 n_data  = find_latest_data(y_list);
113                 if (n_data != NULL) {
114                         ret_val = new DataRange(o_data);
115                         ret_val->add(n_data);
116                         delete(n_data);
117                 }
118                 delete(o_data);
119         }
120         return ret_val;
121 }
122
123 EnumSummaryPeriod get_period_type(Date *start_date,
124                         Date *end_date) {
125         int                     diff;
126         EnumSummaryPeriod       ret_val;
127
128         ret_val = PERIOD_YEARLY;
129         diff    = end_date->year - start_date->year;
130         if (diff != 0) {
131                 ret_val = PERIOD_YEARLY;
132         }
133         else {
134                 diff    = end_date->month - start_date->month;
135                 if (diff != 0) {
136                         ret_val = PERIOD_MONTHLY;
137                 }
138                 else {
139                         diff    = end_date->day - start_date->day;
140                         if (diff != 0) {
141                                 ret_val = PERIOD_DAILY;
142                         }
143                         else {
144                                 diff    = end_date->hour - start_date->hour;
145                                 if (diff != 0) {
146                                         ret_val = PERIOD_HOURLY;
147                                 }
148                                 else {
149                                         diff    = end_date->min - start_date->min;
150                                         if (diff != 0) {
151                                                 ret_val = PERIOD_MINUTELY;
152                                         }
153                                         else {
154                                                 ret_val = PERIOD_SECONDLY;
155                                         }
156                                 }
157                         }
158                 }
159         }
160         return ret_val;
161 }
162
163 DataRange *DataReader::get_summary(Date *date_param,
164                                 EnumSummaryCalculationType calc_type_param,
165                                 EnumSummaryPeriod period_type_param) {
166         DataRange       *ret_val;
167         StoreCache      *store;
168
169         ret_val = NULL;
170         //store = new StoreDay(device_id, date_param);
171         store   = new StoreCache(device_id, date_param);
172         if (store != NULL) {
173                 switch(calc_type_param) {
174                         case SUM:
175                                 ret_val = store->get_sum(period_type_param);
176                                 break;
177                         case DELTA:
178                                 ret_val = store->get_delta(period_type_param);
179                                 break;
180                         case MAX:
181                                 ret_val = store->get_max(period_type_param);
182                                 break;
183                         case MIN:
184                                 ret_val = store->get_min(period_type_param);
185                                 break;
186                         case MEAN:
187                         default:
188                                 ret_val = store->get_mean(period_type_param);
189                                 break;
190                 }
191                 if (ret_val != NULL) {
192                         ret_val->printout();
193                 }
194                 else {
195                         log_error("Could not read data log for device: %s\n", device_id.c_str());
196                 }
197         }
198         else {
199                 log_error("Could not read data log for device: %s\n", device_id.c_str());
200         }
201         delete(store);
202         return ret_val;
203 }
204
205 DataRange *DataReader::get_yearly_summary(Date *date,
206                                 EnumSummaryCalculationType calc_type_param) {
207         return get_summary(date, calc_type_param, PERIOD_YEARLY);
208 }
209
210 DataRange *DataReader::get_yearly_summary(Date *date) {
211         DataRange       *ret_val;
212
213         if (device_config == NULL) {
214                 device_config           = DeviceConfig::get_device_config(device_id);
215                 summary_calc_type       = device_config->get_summary_calculation_type();
216         }
217         ret_val = get_yearly_summary(date, summary_calc_type);
218         return ret_val;
219 }
220
221 DataRange *DataReader::get_yearly_summary(Date *start_date,
222                                         Date *end_date) {
223         DataRange       *ret_val;
224         DataRange       *data;
225         Date            *date;
226
227         ret_val = NULL;
228         date    = start_date->clone();
229         while(date->before_or_equal_year(end_date)) {
230                 data    = get_yearly_summary(date);
231                 if (data != NULL) {
232                         if (ret_val == NULL) {
233                                 ret_val = new DataRange(data);
234                         }
235                         else {
236                                 ret_val->add(data);
237                         }
238                         delete(data);
239                 }
240                 date->next_year();
241         }
242         delete(date);
243         return ret_val;
244 }
245
246 DataRange *DataReader::get_monthly_summary(Date *date,
247                                 EnumSummaryCalculationType calc_type_param) {
248         return get_summary(date, calc_type_param, PERIOD_MONTHLY);
249 }
250
251 DataRange *DataReader::get_monthly_summary(Date *date) {
252         DataRange       *ret_val;
253
254         if (device_config == NULL) {
255                 device_config           = DeviceConfig::get_device_config(device_id);
256                 summary_calc_type       = device_config->get_summary_calculation_type();
257         }
258         ret_val = get_monthly_summary(date, summary_calc_type);
259         return ret_val;
260 }
261
262 DataRange *DataReader::get_monthly_summary(Date *start_date,
263                                         Date *end_date) {
264         DataRange       *ret_val;
265         DataRange       *data;
266         Date            *date;
267
268         ret_val = NULL;
269         date    = start_date->clone();
270         while(date->before_or_equal_month(end_date)) {
271                 data    = get_monthly_summary(date);
272                 if (data != NULL) {
273                         if (ret_val == NULL) {
274                                 ret_val = new DataRange(data);
275                         }
276                         else {
277                                 ret_val->add(data);
278                         }
279                         delete(data);
280                 }
281                 date->next_month();
282         }
283         delete(date);
284         return ret_val;
285 }
286
287 /*
288  * Get Daily summary from the latest date
289  */
290 DataRange *DataReader::get_daily_summary() {
291         if (device_config == NULL) {
292                 device_config           = DeviceConfig::get_device_config(device_id);
293                 summary_calc_type       = device_config->get_summary_calculation_type();
294         }
295         return get_daily_summary(summary_calc_type);
296 }
297
298 /*
299  * Get Daily summary specified by the calc_type from the latest date.
300  */
301 DataRange *DataReader::get_daily_summary(EnumSummaryCalculationType calc_type_param) {
302         Data            *data;
303         Date            date;
304         DataRange       *ret_val;
305
306         ret_val = NULL;
307         data    = get_latest_data();
308         if (data != NULL) {
309                 date    = data->get_date();
310                 ret_val = get_daily_summary(&date, calc_type_param);
311         }
312         return ret_val;
313 }
314
315 DataRange *DataReader::get_daily_summary(Date *date,
316                                 EnumSummaryCalculationType calc_type_param) {
317         return get_summary(date, calc_type_param, PERIOD_DAILY);
318 }
319
320 DataRange *DataReader::get_daily_summary(Date *date) {
321         DataRange       *ret_val;
322
323         if (device_config == NULL) {
324                 device_config           = DeviceConfig::get_device_config(device_id);
325                 summary_calc_type       = device_config->get_summary_calculation_type();
326         }
327         ret_val = get_daily_summary(date, summary_calc_type);
328         return ret_val;
329 }
330
331 DataRange *DataReader::get_daily_summary(Date *start_date,
332                                         Date *end_date) {
333         DataRange       *ret_val;
334         DataRange       *data;
335         Date            *date;
336
337         ret_val = NULL;
338         date    = start_date->clone();
339         while(date->before_or_equal_day(end_date)) {
340                 data    = get_daily_summary(date);
341                 if (data != NULL) {
342                         if (ret_val == NULL) {
343                                 ret_val = new DataRange(data);
344                         }
345                         else {
346                                 ret_val->add(data);
347                         }
348                         delete(data);
349                 }
350                 date->next_day();
351         }
352         delete(date);
353         return ret_val;
354 }
355
356 DataRange *DataReader::get_hourly_summary(Date *date,
357                 EnumSummaryCalculationType calc_type_param) {
358         return get_summary(date, calc_type_param, PERIOD_HOURLY);
359 }
360
361 DataRange *DataReader::get_hourly_summary(Date *date) {
362         DataRange       *ret_val;
363
364         if (device_config == NULL) {
365                 device_config           = DeviceConfig::get_device_config(device_id);
366                 summary_calc_type       = device_config->get_summary_calculation_type();
367         }
368         ret_val = get_hourly_summary(date, summary_calc_type);
369         return ret_val;
370 }
371
372 DataRange *DataReader::get_hourly_summary(Date *start_date,
373                                         Date *end_date) {
374         DataRange       *ret_val;
375         DataRange       *dta_lst;
376         Data            *data;
377         Date            *date;
378         int             cnt;
379         int             ii;
380
381         ret_val = NULL;
382         date    = start_date->clone();
383         while(date->before_or_equal_hour(end_date)) {
384                 dta_lst = get_hourly_summary(date);
385                 cnt     = dta_lst->get_count();
386                 for(ii = 0; ii < cnt; ii++) {
387                         data    = dta_lst->get(ii);
388                         if (data != NULL) {
389                                 if (ret_val == NULL) {
390                                         ret_val = new DataRange(data);
391                                 }
392                                 else {
393                                         ret_val->add(data);
394                                 }
395                                 delete(data);
396                         }
397                 }
398                 date->next_day();
399         }
400         delete(date);
401         return ret_val;
402 }
403
404 DataRange *DataReader::get_data(Date *start_date,
405                                 Date *end_date) {
406         DataRange               *ret_val;
407         EnumSummaryPeriod       period;
408
409         ret_val = NULL;
410         period  = get_period_type(start_date, end_date);
411         switch(period) {
412                 case PERIOD_YEARLY:
413                         log_debug("get yearly summary: %s - %s\n", start_date->to_string().c_str(), end_date->to_string().c_str());
414                         ret_val = get_yearly_summary(start_date, end_date);
415                         break;
416                 case PERIOD_MONTHLY:
417                         log_debug("get monthly summary\n");
418                         ret_val = get_monthly_summary(start_date, end_date);
419                         break;
420                 case PERIOD_DAILY:
421                         log_debug("get daily summary\n");
422                         ret_val = get_daily_summary(start_date, end_date);
423                         break;
424                 case PERIOD_HOURLY:
425                         log_debug("get hourly summary\n");
426                         ret_val = get_hourly_summary(start_date, end_date);
427                         break;
428                 case PERIOD_MINUTELY:
429                         log_debug("get minute summary data\n");
430                         break;
431                 case PERIOD_SECONDLY:
432                 default:
433                         log_debug("get second summary data\n");
434                         break;
435         }
436         return ret_val;
437 }
438
439 string DataReader::get_device_id() {
440         return device_id;
441 }
442
443 /**
444  * Read device type from the device specific config file
445  */
446 string DataReader::get_device_type() {
447         string  ret_val;
448
449         if (device_config == NULL) {
450                 device_config   = DeviceConfig::get_device_config(device_id);
451                 ret_val         = device_config->get_cfg_value(DEVICE_CONFIG_VALUE_KEY__TYPE);
452         }
453         return ret_val;
454 }