4 * Created on: Oct 31, 2010
15 #include <sys/types.h>
20 #include "DeviceConfig.hh"
21 #include "StoreDay.hh"
22 #include "FileUtil.hh"
27 StoreDay::StoreDay(string device_id_param,
28 Date *date_time_param): Store(device_id_param, date_time_param) {
29 store_fname = get_file_name(device_id_param, date_time_param);
32 StoreDay::StoreDay(string fname_param): Store("", NULL) {
35 store_fname = fname_param;
38 StoreDay::~StoreDay() {
39 if (store_data != NULL) {
45 string StoreDay::get_year_dir_name(string device_id,
46 Date *date_time_param) {
51 snprintf(buffer, 10, "%d", date_time_param->year);
52 bd_name = DeviceConfig::get_base_dir_name();
53 bd_name = FileUtil::concat_paths(bd_name, device_id);
54 ret_val = bd_name + "/" + buffer;
58 string StoreDay::get_dir_name(string device_id,
59 Date *date_time_param) {
64 snprintf(buffer, 30, "%d/%02d", date_time_param->year, date_time_param->month);
65 bd_name = DeviceConfig::get_base_dir_name();
66 bd_name = FileUtil::concat_paths(bd_name, device_id);
67 ret_val = bd_name + "/" + buffer;
71 string StoreDay::get_file_name(string device_id,
72 Date *date_time_param) {
80 date_time_param->year,
81 date_time_param->month,
82 date_time_param->day);
84 fname = fname + DATAFILE_SUFFIX;
85 ret_val = get_dir_name(device_id, date_time_param);
86 ret_val = FileUtil::concat_paths(ret_val, fname);
90 void StoreDay::save(string device_id,
91 std::list<Data *> *data_list,
99 list<Data *>::iterator iter;
103 /* needs to be casted to long unsigned int value is "unsigned int" in some
104 toolchains and that would otherwise cause an warning/error
106 log_info("[%s] saving %lu data values.\n", device_id.c_str(),
107 (long unsigned int)data_list->size());
108 // TODO: add mutex to protect string_list while it's read and emptied
109 for(iter = data_list->begin(); iter != data_list->end(); iter++) {
110 data = (Data *)*iter;
111 date = data->get_date();
112 n_path = get_file_name(device_id, &date);
113 if (n_path.compare(f_path) != 0) {
114 if (ostream != NULL) {
119 log_info("[%s] Opening file for save: %s\n", device_id.c_str(), f_path.c_str());
120 ostream = FileUtil::open_for_writing(f_path.c_str());
122 if ((ostream != NULL) &&
123 (ostream->is_open() == true)) {
124 line = data->to_string(dec_precision);
125 if (line.length() > 0) {
126 log_debug("storing line: %s\n", line.c_str());
127 *ostream << line << endl;
131 log_error("[%s] File open for data save failed: %s\n", device_id.c_str(), f_path.c_str());
134 if (ostream != NULL) {
140 bool StoreDay::load() {
141 return Store::load(store_fname);
144 bool StoreDay::exist(string fname_param, bool writable) {
146 ret_val = FileUtil::file_exist(fname_param.c_str(), writable);
150 bool StoreDay::exist(string dev_id_param,
156 f_name = get_file_name(dev_id_param, date);
157 ret_val = FileUtil::file_exist(f_name.c_str(), writable);
161 bool StoreDay::exist_in_month(string dev_id_param,
167 dirname = StoreDay::get_dir_name(dev_id_param, date);
168 ret_val = FileUtil::dir_exist(dirname.c_str(), writable);
172 bool StoreDay::exist_in_year(string dev_id_param,
178 dirname = StoreDay::get_year_dir_name(dev_id_param, date);
179 ret_val = FileUtil::dir_exist(dirname.c_str(), writable);
183 bool StoreDay::exist(bool writable) {
184 return exist(store_fname, writable);
187 static int get_summary_period_as_freq_seconds(EnumSummaryPeriod period_type_param) {
191 switch(period_type_param) {
192 case PERIOD_SECONDLY:
195 case PERIOD_MINUTELY:
205 // -1 as freq means that show all data from the current store
212 plp::DataRange *StoreDay::get_sum(EnumSummaryPeriod period_type_param) {
229 frq_sec = get_summary_period_as_freq_seconds(period_type_param);
230 if (store_data == NULL) {
233 if ((succ == true) &&
234 (store_data != NULL)) {
235 row_count = store_data->get_count();
237 col_count = store_data->get_data_item_value_count();
239 ret_val = new DataRange();
240 for (ii = 0; ii < row_count; ii++) {
241 data = store_data->get(ii);
244 calc = data->clone();
245 limit_d = data->get_date().clone();
248 limit_d->inc_seconds(frq_sec);
250 date = data->get_date();
251 if ((ii <= (row_count -1)) &&
252 ((frq_sec == -1) || (date.before(limit_d)))) {
253 for (jj = 0; jj < col_count; jj++) {
254 calc->value_arr[jj] = calc->value_arr[jj] + data->value_arr[jj];
257 if ((ii >= (row_count -1)) ||
258 ((frq_sec != -1) && (date.before(limit_d) == false))) {
261 calc = data->clone();
262 if (limit_d != NULL) {
265 limit_d = data->get_date().clone();
268 limit_d->inc_seconds(frq_sec);
277 if (limit_d != NULL) {
286 plp::DataRange *StoreDay::get_mean(EnumSummaryPeriod period_type_param) {
305 frq_sec = get_summary_period_as_freq_seconds(period_type_param);
306 if (store_data == NULL) {
309 if ((succ == true) &&
310 (store_data != NULL)) {
311 row_count = store_data->get_count();
313 col_count = store_data->get_data_item_value_count();
315 ret_val = new DataRange();
316 for (ii = 0; ii < row_count; ii++) {
317 data = store_data->get(ii);
321 calc = data->clone();
322 limit_d = data->get_date().clone();
325 limit_d->inc_seconds(frq_sec);
327 date = data->get_date();
328 if ((ii <= (row_count -1)) &&
329 ((frq_sec == -1) || (date.before(limit_d)))) {
330 for (jj = 0; jj < col_count; jj++) {
331 calc->value_arr[jj] = calc->value_arr[jj] + data->value_arr[jj];
335 if ((ii >= (row_count -1)) ||
336 ((frq_sec != -1) && (date.before(limit_d) == false))) {
337 for (jj = 0; jj < col_count; jj++) {
338 calc->value_arr[jj] = calc->value_arr[jj] / d_count;
343 calc = data->clone();
344 if (limit_d != NULL) {
347 limit_d = data->get_date().clone();
350 limit_d->inc_seconds(frq_sec);
359 if (limit_d != NULL) {
368 plp::DataRange *StoreDay::get_delta(EnumSummaryPeriod period_type_param) {
387 frq_sec = get_summary_period_as_freq_seconds(period_type_param);
388 if (store_data == NULL) {
391 if ((succ == true) &&
392 (store_data != NULL)) {
393 row_count = store_data->get_count();
395 col_count = store_data->get_data_item_value_count();
397 ret_val = new DataRange();
398 for (ii = 0; ii < row_count; ii++) {
399 data = store_data->get(ii);
402 calc1 = data->clone();
403 limit_d = data->get_date().clone();
406 limit_d->inc_seconds(frq_sec);
412 date = data->get_date();
413 if ((ii <= (row_count -1)) &&
414 ((frq_sec == -1) || (date.before(limit_d)))) {
418 calc2 = data->clone();
420 if ((ii >= (row_count -1)) ||
421 ((frq_sec != -1) && (date.before(limit_d) == false))) {
423 calc2 = calc1->clone();
425 for (jj = 0; jj < col_count; jj++) {
426 calc2->value_arr[jj] = calc2->value_arr[jj] - calc1->value_arr[jj];
430 calc1 = data->clone();
433 if (limit_d != NULL) {
436 limit_d = data->get_date().clone();
439 limit_d->inc_seconds(frq_sec);
452 if (limit_d != NULL) {
461 plp::DataRange *StoreDay::get_max_or_min(EnumSummaryPeriod period_type_param, bool max) {
477 frq_sec = get_summary_period_as_freq_seconds(period_type_param);
479 if (store_data == NULL) {
482 if ((succ == true) &&
483 (store_data != NULL)) {
484 row_count = store_data->get_count();
486 col_count = store_data->get_data_item_value_count();
488 ret_val = new DataRange();
489 for (ii = 0; ii < row_count; ii++) {
490 data = store_data->get(ii);
493 calc = data->clone();
494 limit_d = data->get_date().clone();
497 limit_d->inc_seconds(frq_sec);
499 date = data->get_date();
500 if ((ii <= (row_count -1)) &&
501 ((frq_sec == -1) || (date.before(limit_d)))) {
504 for (jj = 0; jj < col_count; jj++) {
505 if (calc->value_arr[jj] < data->value_arr[jj]) {
506 calc->value_arr[jj] = data->value_arr[jj];
512 for (jj = 0; jj < col_count; jj++) {
513 if (data->value_arr[jj] < calc->value_arr[jj]) {
514 calc->value_arr[jj] = data->value_arr[jj];
522 new_date = data->get_date();
523 calc->set_date(&new_date);
526 if ((ii >= (row_count -1)) ||
527 ((frq_sec != -1) && (date.before(limit_d) == false))) {
530 calc = data->clone();
531 if (limit_d != NULL) {
534 limit_d = data->get_date().clone();
537 limit_d->inc_seconds(frq_sec);
546 if (limit_d != NULL) {
555 plp::DataRange *StoreDay::get_max(EnumSummaryPeriod period_type_param) {
558 ret_val = get_max_or_min(period_type_param, true);
562 plp::DataRange *StoreDay::get_min(EnumSummaryPeriod period_type_param) {
565 ret_val = get_max_or_min(period_type_param, false);
569 DataRange *StoreDay::get_oldest_and_latest_data(string fname_param) {
582 if (store_data != NULL) {
583 row_count = store_data->get_count();
585 o_data = store_data->get(0);
586 n_data = store_data->get(row_count - 1);
590 if (range_data != NULL) {
591 row_count = range_data->get_count();
593 o_data = range_data->get(0);
594 n_data = range_data->get(row_count - 1);
598 in.open(fname_param.c_str());
599 if (in.is_open() == true) {
600 while (in.eof() == false) {
602 if (line.empty() == false) {
603 if (o_data == NULL) {
604 o_data = Data::parse_string(line);
609 if (prev_line.empty() == false) {
610 n_data = Data::parse_string(prev_line);
615 if ((o_data != NULL) &&
617 ret_val = new DataRange(o_data);
618 ret_val->add(n_data);
619 if (range_data != NULL) {
620 range_data = new DataRange(o_data);
621 range_data->add(n_data);
624 if (o_data != NULL) {
627 if (n_data != NULL) {
633 DataRange *StoreDay::get_oldest_and_latest_data() {
634 return get_oldest_and_latest_data(store_fname);
637 Data *StoreDay::get_oldest_data() {
643 dr = get_oldest_and_latest_data();
645 row_count = dr->get_count();
646 if (row_count >= 1) {
647 ret_val = dr->get(0);
654 Data *StoreDay::get_latest_data() {
660 dr = get_oldest_and_latest_data();
662 row_count = dr->get_count();
663 if (row_count == 2) {
664 ret_val = dr->get(1);
671 bool StoreDay::data_day_scan_days_in_month(string dev_id_param,
678 while((ret_val == false) &&
679 (new_date->before(max_date))) {
680 new_date->next_day();
681 fname = get_file_name(dev_id_param, new_date);
682 if (exist(fname, false) == true) {
686 if (new_date->is_last_day_of_month() == true) {
693 bool StoreDay::data_day_scan_month_in_year(string dev_id_param,
699 // next scan months dir existence under the first year
700 while((ret_val == false) &&
701 (new_date->before(max_date))) {
702 new_date->next_month();
703 if (exist_in_month(dev_id_param,
706 ret_val = data_day_scan_days_in_month(dev_id_param,
712 if (new_date->month == 12)
718 bool StoreDay::data_day_scan_years(string dev_id_param,
724 while((ret_val == false) &&
725 (new_date->before(max_date))) {
726 new_date->next_year();
727 if (exist_in_year(dev_id_param,
730 ret_val = data_day_scan_month_in_year(dev_id_param,
740 bool StoreDay::get_next_date_with_data(std::string dev_id_param,
741 plp::Date *next_date,
742 plp::Date *max_date) {
748 new_date = next_date->clone();
749 // scan first dates in current month
750 ret_val = data_day_scan_days_in_month(dev_id_param,
753 if (ret_val == false) {
754 ret_val = data_day_scan_month_in_year(dev_id_param,
757 if (ret_val == false) {
758 ret_val = data_day_scan_years(dev_id_param,
764 new_date->copy(next_date);
766 max_date->copy(next_date);