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) {
228 frq_sec = get_summary_period_as_freq_seconds(period_type_param);
229 if (store_data == NULL) {
232 if ((succ == true) &&
233 (store_data != NULL)) {
234 row_count = store_data->get_count();
236 col_count = store_data->get_data_item_value_count();
238 ret_val = new DataRange();
239 for (ii = 0; ii < row_count; ii++) {
240 data = store_data->get(ii);
243 calc = data->clone();
244 limit_d = data->get_date().clone();
247 limit_d->inc_seconds(frq_sec);
249 date = data->get_date();
250 if ((ii <= (row_count -1)) &&
251 ((frq_sec == -1) || (date.before(limit_d)))) {
252 for (jj = 0; jj < col_count; jj++) {
253 calc->value_arr[jj] = calc->value_arr[jj] + data->value_arr[jj];
256 if ((ii >= (row_count -1)) ||
257 ((frq_sec != -1) && (date.before(limit_d) == false))) {
260 calc = data->clone();
261 if (limit_d != NULL) {
264 limit_d = data->get_date().clone();
267 limit_d->inc_seconds(frq_sec);
276 if (limit_d != NULL) {
285 plp::DataRange *StoreDay::get_mean(EnumSummaryPeriod period_type_param) {
303 frq_sec = get_summary_period_as_freq_seconds(period_type_param);
304 if (store_data == NULL) {
307 if ((succ == true) &&
308 (store_data != NULL)) {
309 row_count = store_data->get_count();
311 col_count = store_data->get_data_item_value_count();
313 ret_val = new DataRange();
314 for (ii = 0; ii < row_count; ii++) {
315 data = store_data->get(ii);
319 calc = data->clone();
320 limit_d = data->get_date().clone();
323 limit_d->inc_seconds(frq_sec);
325 date = data->get_date();
326 if ((ii <= (row_count -1)) &&
327 ((frq_sec == -1) || (date.before(limit_d)))) {
328 for (jj = 0; jj < col_count; jj++) {
329 calc->value_arr[jj] = calc->value_arr[jj] + data->value_arr[jj];
333 if ((ii >= (row_count -1)) ||
334 ((frq_sec != -1) && (date.before(limit_d) == false))) {
335 for (jj = 0; jj < col_count; jj++) {
336 calc->value_arr[jj] = calc->value_arr[jj] / d_count;
341 calc = data->clone();
342 if (limit_d != NULL) {
345 limit_d = data->get_date().clone();
348 limit_d->inc_seconds(frq_sec);
357 if (limit_d != NULL) {
366 plp::DataRange *StoreDay::get_delta(EnumSummaryPeriod period_type_param) {
384 frq_sec = get_summary_period_as_freq_seconds(period_type_param);
385 if (store_data == NULL) {
388 if ((succ == true) &&
389 (store_data != NULL)) {
390 row_count = store_data->get_count();
392 col_count = store_data->get_data_item_value_count();
394 ret_val = new DataRange();
395 for (ii = 0; ii < row_count; ii++) {
396 data = store_data->get(ii);
399 calc1 = data->clone();
400 limit_d = data->get_date().clone();
403 limit_d->inc_seconds(frq_sec);
409 date = data->get_date();
410 if ((ii <= (row_count -1)) &&
411 ((frq_sec == -1) || (date.before(limit_d)))) {
415 calc2 = data->clone();
417 if ((ii >= (row_count -1)) ||
418 ((frq_sec != -1) && (date.before(limit_d) == false))) {
420 calc2 = calc1->clone();
422 for (jj = 0; jj < col_count; jj++) {
423 calc2->value_arr[jj] = calc2->value_arr[jj] - calc1->value_arr[jj];
427 calc1 = data->clone();
430 if (limit_d != NULL) {
433 limit_d = data->get_date().clone();
436 limit_d->inc_seconds(frq_sec);
449 if (limit_d != NULL) {
458 plp::DataRange *StoreDay::get_max_or_min(EnumSummaryPeriod period_type_param, bool max) {
474 frq_sec = get_summary_period_as_freq_seconds(period_type_param);
475 if (store_data == NULL) {
478 if ((succ == true) &&
479 (store_data != NULL)) {
480 row_count = store_data->get_count();
482 col_count = store_data->get_data_item_value_count();
484 ret_val = new DataRange();
485 for (ii = 0; ii < row_count; ii++) {
486 data = store_data->get(ii);
489 calc = data->clone();
490 limit_d = data->get_date().clone();
493 limit_d->inc_seconds(frq_sec);
495 date = data->get_date();
496 if ((ii <= (row_count -1)) &&
497 ((frq_sec == -1) || (date.before(limit_d)))) {
500 for (jj = 0; jj < col_count; jj++) {
501 if (calc->value_arr[jj] < data->value_arr[jj]) {
502 calc->value_arr[jj] = data->value_arr[jj];
508 for (jj = 0; jj < col_count; jj++) {
509 if (data->value_arr[jj] < calc->value_arr[jj]) {
510 calc->value_arr[jj] = data->value_arr[jj];
518 new_date = data->get_date();
519 calc->set_date(&new_date);
522 if ((ii >= (row_count -1)) ||
523 ((frq_sec != -1) && (date.before(limit_d) == false))) {
526 calc = data->clone();
527 if (limit_d != NULL) {
530 limit_d = data->get_date().clone();
533 limit_d->inc_seconds(frq_sec);
542 if (limit_d != NULL) {
551 plp::DataRange *StoreDay::get_max(EnumSummaryPeriod period_type_param) {
554 ret_val = get_max_or_min(period_type_param, true);
558 plp::DataRange *StoreDay::get_min(EnumSummaryPeriod period_type_param) {
561 ret_val = get_max_or_min(period_type_param, false);
565 DataRange *StoreDay::get_oldest_and_latest_data(string fname_param) {
578 if (store_data != NULL) {
579 row_count = store_data->get_count();
581 o_data = store_data->get(0);
582 n_data = store_data->get(row_count - 1);
586 if (range_data != NULL) {
587 row_count = range_data->get_count();
589 o_data = range_data->get(0);
590 n_data = range_data->get(row_count - 1);
594 in.open(fname_param.c_str());
595 if (in.is_open() == true) {
596 while (in.eof() == false) {
598 if (line.empty() == false) {
599 if (o_data == NULL) {
600 o_data = Data::parse_string(line);
605 if (prev_line.empty() == false) {
606 n_data = Data::parse_string(prev_line);
611 if ((o_data != NULL) &&
613 ret_val = new DataRange(o_data);
614 ret_val->add(n_data);
615 if (range_data != NULL) {
616 range_data = new DataRange(o_data);
617 range_data->add(n_data);
620 if (o_data != NULL) {
623 if (n_data != NULL) {
629 DataRange *StoreDay::get_oldest_and_latest_data() {
630 return get_oldest_and_latest_data(store_fname);
633 Data *StoreDay::get_oldest_data() {
639 dr = get_oldest_and_latest_data();
641 row_count = dr->get_count();
642 if (row_count >= 1) {
643 ret_val = dr->get(0);
650 Data *StoreDay::get_latest_data() {
656 dr = get_oldest_and_latest_data();
658 row_count = dr->get_count();
659 if (row_count == 2) {
660 ret_val = dr->get(1);
667 bool StoreDay::data_day_scan_days_in_month(string dev_id_param,
674 while((ret_val == false) &&
675 (new_date->before(max_date))) {
676 new_date->next_day();
677 fname = get_file_name(dev_id_param, new_date);
678 if (exist(fname, false) == true) {
682 if (new_date->is_last_day_of_month() == true) {
689 bool StoreDay::data_day_scan_month_in_year(string dev_id_param,
695 // next scan months dir existence under the first year
696 while((ret_val == false) &&
697 (new_date->before(max_date))) {
698 new_date->next_month();
699 if (exist_in_month(dev_id_param,
702 ret_val = data_day_scan_days_in_month(dev_id_param,
708 if (new_date->month == 12)
714 bool StoreDay::data_day_scan_years(string dev_id_param,
720 while((ret_val == false) &&
721 (new_date->before(max_date))) {
722 new_date->next_year();
723 if (exist_in_year(dev_id_param,
726 ret_val = data_day_scan_month_in_year(dev_id_param,
736 bool StoreDay::get_next_date_with_data(std::string dev_id_param,
737 plp::Date *next_date,
738 plp::Date *max_date) {
744 new_date = next_date->clone();
745 // scan first dates in current month
746 ret_val = data_day_scan_days_in_month(dev_id_param,
749 if (ret_val == false) {
750 ret_val = data_day_scan_month_in_year(dev_id_param,
753 if (ret_val == false) {
754 ret_val = data_day_scan_years(dev_id_param,
760 new_date->copy(next_date);
762 max_date->copy(next_date);