2 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * This file implements statistics entity handler methods.
20 * @file table-statistics.c
24 #include "table-statistics.h"
25 #include "db-internal.h"
27 /* DELETE statements */
28 #define DELETE_ALL "delete from statistics where time_stamp between ? and ?"
30 #define DELETE_APP "delete from statistics where binpath=? and " \
31 "time_stamp between ? and ? "
33 #define DELETE_IFACE "delete from statistics where iftype=? and " \
34 "time_stamp between ? and ?"
36 #define DELETE_APP_IFACE "delete from statistics where binpath=? and " \
37 "iftype=? and time_stamp between ? and ?"
39 #define DELETE_FIRST_BY_NUMBER "delete from statistics where time_stamp in " \
40 "(select time_stamp from statistics desc limit ?)"
42 /* SELECT statements */
43 #define SELECT_FOR_PERIOD "select binpath, hw_net_protocol_type, " \
44 "is_roaming, sum(received) as received, " \
45 "sum(sent) as sent, subscriber_id, ground, iftype, ifname from statistics " \
46 "where time_stamp between ? and ? " \
47 "group by binpath, is_roaming, subscriber_id order by received desc"
49 #define SELECT_FOR_PERIOD_IFACE "select binpath, hw_net_protocol_type, " \
50 "is_roaming, sum(received) as received, " \
51 "sum(sent) as sent, subscriber_id, ground, iftype, ifname from statistics " \
52 "where time_stamp between ? and ? " \
53 "and iftype=? group by binpath, is_roaming, subscriber_id order by received desc"
55 #define SELECT_CHUNKS "select binpath, hw_net_protocol_type, " \
56 "is_roaming, sum(received) as received, " \
57 "sum(sent) as sent, subscriber_id, ground, iftype, ifname, " \
58 "time_stamp - time_stamp % ? as timestamp " \
59 "from statistics where time_stamp between ? and ? " \
60 "group by binpath, timestamp, subscriber_id order by timestamp"
62 #define SELECT_CHUNKS_IFACE "select binpath, hw_net_protocol_type, " \
63 "is_roaming, sum(received) as received, " \
64 "sum(sent) as sent, subscriber_id, ground, iftype, ifname, " \
65 "time_stamp - time_stamp % ? as timestamp " \
66 "from statistics where time_stamp between ? and ? and iftype=?" \
67 "group by binpath, timestamp, subscriber_id order by timestamp"
69 #define SELECT_APP_DETAILS "select iftype, hw_net_protocol_type, " \
70 "is_roaming, sum(received) as received, sum(sent) as sent, " \
71 "ifname, subscriber_id, ground from statistics " \
72 "where time_stamp between ? and ? and binpath=? " \
73 "group by binpath, iftype, ifname, subscriber_id, hw_net_protocol_type, " \
75 "order by time_stamp, binpath, iftype, ifname, subscriber_id, " \
76 "hw_net_protocol_type, is_roaming"
78 #define SELECT_APP_DETAILS_IFACE "select iftype, hw_net_protocol_type, " \
79 "is_roaming, sum(received) as received, sum(sent) as sent, " \
80 "ifname, subscriber_id, ground from statistics " \
81 "where time_stamp between ? and ? and binpath=? and iftype=?" \
82 "group by hw_net_protocol_type, is_roaming, iftype, ifname, subscriber_id " \
83 "order by time_stamp, hw_net_protocol_type, is_roaming, iftype, " \
84 "ifname, subscriber_id"
86 #define SELECT_CHUNKS_APP "select iftype, hw_net_protocol_type, " \
87 "is_roaming, sum(received) as received, sum(sent) as sent, " \
88 "ifname, subscriber_id, ground, time_stamp - time_stamp % ? as time_stamp " \
90 "group by iftype, ifname, time_stamp, hw_net_protocol_type, is_roaming " \
91 "order by time_stamp, iftype, ifname, hw_net_protocol_type, is_roaming"
93 #define SELECT_CHUNKS_APP_IFACE "select iftype, hw_net_protocol_type, " \
94 "is_roaming, sum(received) as received, sum(sent) as sent, " \
95 "ifname, subscriber_id, ground, time_stamp - time_stamp % ? as time_stamp " \
96 "from statistics where time_stamp between ? and ? and binpath = ? " \
98 "group by time_stamp, hw_net_protocol_type, is_roaming, " \
99 "iftype, ifname, subscriber_id " \
100 "order by time_stamp, iftype, ifname, subscriber_id, hw_net_protocol_type, " \
103 #define SELECT_TOTAL "select iftype, hw_net_protocol_type, " \
104 "is_roaming, sum(received) as received, sum(sent) as sent, " \
105 "ifname, subscriber_id, ground from statistics " \
106 "where (time_stamp between ? and ?) " \
107 "and binpath NOT LIKE 'TOTAL_%' " \
108 "group by iftype, ifname, subscriber_id, hw_net_protocol_type, is_roaming " \
109 "order by time_stamp, iftype, ifname, subscriber_id, hw_net_protocol_type, " \
112 #define SELECT_TOTAL_IFACE "select iftype, hw_net_protocol_type, " \
113 "is_roaming, sum(received) as received, sum(sent) as sent, " \
114 "ifname, subscriber_id, ground from statistics " \
115 "where (time_stamp between ? and ?) and iftype=? " \
116 "and binpath NOT LIKE 'TOTAL_%' " \
117 "group by hw_net_protocol_type, is_roaming, " \
118 "iftype, ifname, subscriber_id " \
119 "order by time_stamp, iftype, ifname, subscriber_id, hw_net_protocol_type, " \
122 #define SELECT_CHUNKS_TOTAL "select iftype, hw_net_protocol_type, " \
123 "is_roaming, sum(received) as received, sum(sent) as sent, " \
124 "ifname, subscriber_id, ground, time_stamp - time_stamp % ? as time_stamp " \
125 "from statistics where time_stamp between ? and ? " \
126 "and binpath NOT LIKE 'TOTAL_%' " \
127 "group by time_stamp, iftype, ifname, subscriber_id, hw_net_protocol_type, " \
129 "order by time_stamp, iftype, ifname, subscriber_id, hw_net_protocol_type, " \
132 #define SELECT_CHUNKS_TOTAL_IFACE "select iftype, hw_net_protocol_type, " \
133 "is_roaming, sum(received) as received, sum(sent) as sent, " \
134 "ifname, subscriber_id, ground, time_stamp - time_stamp % ? as time_stamp " \
135 "from statistics where time_stamp between ? and ? " \
137 "and binpath NOT LIKE 'TOTAL_%' " \
138 "group by time_stamp, hw_net_protocol_type, is_roaming, iftype, ifname, subscriber_id " \
139 "order by time_stamp, hw_net_protocol_type, is_roaming, iftype, " \
140 "ifname, subscriber_id"
142 /* INSERT statement */
143 #define INSERT_VALUES "insert into statistics " \
144 "(binpath, received, sent, time_stamp, " \
145 "iftype, is_roaming, hw_net_protocol_type, " \
146 "ifname, subscriber_id, ground) " \
147 "values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
149 static void __finalize_delete(void);
151 #define PREPARE_DELETE(stm, query) do { \
152 rc = sqlite3_prepare_v2(db, query, -1, &stm, NULL); \
153 if (rc != SQLITE_OK) { \
155 __finalize_delete(); \
156 STC_LOGE("Failed to prepare \"%s\"query" \
162 static void __finalize_select(void);
164 #define PREPARE_SELECT(stm, query) do { \
165 rc = sqlite3_prepare_v2(db, query, -1, &stm, NULL); \
166 if (rc != SQLITE_OK) { \
168 __finalize_select(); \
169 STC_LOGE("Failed to prepare \"%s\"query" \
175 static void __finalize_insert(void);
177 #define PREPARE_INSERT(stm, query) do { \
178 rc = sqlite3_prepare_v2(db, query, -1, &stm, NULL); \
179 if (rc != SQLITE_OK) { \
181 __finalize_insert(); \
182 STC_LOGE("Failed to prepare \"%s\"query" \
188 #define FINALIZE(stm) do { \
190 sqlite3_finalize(stm); \
195 /* DELETE statements */
196 /* the following array is strictly ordered
197 * to find required statement the following code will be used:
198 * (app ? 1 : 0) | (iftype ? 2 : 0)
200 static sqlite3_stmt *delete_query[5];
202 /* SELECT statements */
203 static sqlite3_stmt *select_for_period;
204 static sqlite3_stmt *select_for_period_iface;
205 static sqlite3_stmt *select_chunks;
206 static sqlite3_stmt *select_chunks_iface;
207 static sqlite3_stmt *select_app_details;
208 static sqlite3_stmt *select_app_details_iface;
209 static sqlite3_stmt *select_chunks_app;
210 static sqlite3_stmt *select_chunks_app_iface;
211 static sqlite3_stmt *select_total;
212 static sqlite3_stmt *select_total_iface;
213 static sqlite3_stmt *select_chunks_total;
214 static sqlite3_stmt *select_chunks_total_iface;
216 /* INSERT statements */
217 static sqlite3_stmt *update_statistics_query;
219 static int __prepare_delete(sqlite3 *db)
221 __STC_LOG_FUNC_ENTER__;
223 static int initialized;
226 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
227 return SQLITE_OK; //LCOV_EXCL_LINE
230 PREPARE_DELETE(delete_query[0], DELETE_ALL);
231 PREPARE_DELETE(delete_query[1], DELETE_APP);
232 PREPARE_DELETE(delete_query[2], DELETE_IFACE);
233 PREPARE_DELETE(delete_query[3], DELETE_APP_IFACE);
234 PREPARE_DELETE(delete_query[4], DELETE_FIRST_BY_NUMBER);
237 __STC_LOG_FUNC_EXIT__;
241 static void __finalize_delete(void)
243 __STC_LOG_FUNC_ENTER__;
246 for (i = 0; i < sizeof(delete_query) / sizeof(*delete_query); i++)
247 FINALIZE(delete_query[i]);
249 __STC_LOG_FUNC_EXIT__;
252 static int __prepare_select(sqlite3 *db)
254 __STC_LOG_FUNC_ENTER__;
256 static int initialized;
259 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
260 return SQLITE_OK; //LCOV_EXCL_LINE
263 PREPARE_SELECT(select_for_period, SELECT_FOR_PERIOD);
264 PREPARE_SELECT(select_for_period_iface, SELECT_FOR_PERIOD_IFACE);
265 PREPARE_SELECT(select_chunks, SELECT_CHUNKS);
266 PREPARE_SELECT(select_chunks_iface, SELECT_CHUNKS_IFACE);
267 PREPARE_SELECT(select_app_details, SELECT_APP_DETAILS);
268 PREPARE_SELECT(select_app_details_iface, SELECT_APP_DETAILS_IFACE);
269 PREPARE_SELECT(select_chunks_app, SELECT_CHUNKS_APP);
270 PREPARE_SELECT(select_chunks_app_iface, SELECT_CHUNKS_APP_IFACE);
271 PREPARE_SELECT(select_total, SELECT_TOTAL);
272 PREPARE_SELECT(select_total_iface, SELECT_TOTAL_IFACE);
273 PREPARE_SELECT(select_chunks_total, SELECT_CHUNKS_TOTAL);
274 PREPARE_SELECT(select_chunks_total_iface, SELECT_CHUNKS_TOTAL_IFACE);
277 __STC_LOG_FUNC_EXIT__;
281 static void __finalize_select(void)
283 __STC_LOG_FUNC_ENTER__;
285 FINALIZE(select_for_period);
286 FINALIZE(select_for_period_iface);
287 FINALIZE(select_chunks);
288 FINALIZE(select_chunks_iface);
289 FINALIZE(select_app_details);
290 FINALIZE(select_app_details_iface);
291 FINALIZE(select_chunks_app);
292 FINALIZE(select_chunks_app_iface);
293 FINALIZE(select_total);
294 FINALIZE(select_total_iface);
295 FINALIZE(select_chunks_total);
296 FINALIZE(select_chunks_total_iface);
298 __STC_LOG_FUNC_EXIT__;
301 static int __prepare_insert(sqlite3 *db)
303 __STC_LOG_FUNC_ENTER__;
305 static int initialized;
308 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
309 return SQLITE_OK; //LCOV_EXCL_LINE
312 PREPARE_INSERT(update_statistics_query, INSERT_VALUES);
315 __STC_LOG_FUNC_EXIT__;
319 static void __finalize_insert(void)
321 __STC_LOG_FUNC_ENTER__;
323 FINALIZE(update_statistics_query);
325 __STC_LOG_FUNC_EXIT__;
328 static int __is_iftype_defined(const stc_iface_type_e iftype)
330 __STC_LOG_FUNC_ENTER__;
331 __STC_LOG_FUNC_EXIT__;
332 return iftype < STC_IFACE_LAST_ELEM &&
333 iftype > STC_IFACE_UNKNOWN &&
334 iftype != STC_IFACE_ALL;
337 /* the following array is strictly ordered
338 * to find required statement the following code will be used:
339 * (iface ? 1 : 0) | (total ? 2 : 0) | (chunks ? 4 : 0)
341 static sqlite3_stmt **details_stms[] = {
343 &select_app_details_iface,
347 &select_chunks_app_iface,
348 &select_chunks_total,
349 &select_chunks_total_iface
352 static sqlite3_stmt *__select_statement(const char *app_id,
353 const table_statistics_select_rule *rule)
355 __STC_LOG_FUNC_ENTER__;
356 const int stm_index = __is_iftype_defined(rule->iftype) |
357 ((strlen(app_id) > 0) ? 0 : 2) | (rule->granularity ? 4 : 0);
358 STC_LOGD("stm index %d", stm_index);
359 __STC_LOG_FUNC_EXIT__;
360 return *details_stms[stm_index];
364 stc_error_e table_statistics_reset_first_n_entries(int num)
366 __STC_LOG_FUNC_ENTER__;
367 stc_error_e error_code = STC_ERROR_NONE;
370 STC_LOGE("Invalid number of entries");
371 return STC_ERROR_INVALID_PARAMETER;
374 DB_ACTION(sqlite3_bind_int(delete_query[4], 1, num));
376 if (sqlite3_step(delete_query[4]) != SQLITE_DONE) {
377 STC_LOGE("Failed to drop collected statistics.");
378 error_code = STC_ERROR_DB_FAILED;
379 __STC_LOG_FUNC_EXIT__;
382 sqlite3_reset(delete_query[4]);
387 stc_error_e table_statistics_reset(const table_statistics_reset_rule *rule)
389 __STC_LOG_FUNC_ENTER__;
391 stc_error_e error_code = STC_ERROR_NONE;
392 int pos = 1; /* running through positions where to
393 bind parameters in the query */
395 if (!rule || !rule->interval) {
396 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
397 return STC_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
400 /* pick a statement depending on parameters.
401 See comment for delete_query */
402 stmt = delete_query[(rule->app_id ? 1 : 0) |
403 (rule->iftype != STC_IFACE_UNKNOWN &&
404 rule->iftype != STC_IFACE_LAST_ELEM ? 2 : 0)];
407 DB_ACTION(sqlite3_bind_text(stmt, pos++, rule->app_id, -1,
410 if (rule->iftype != STC_IFACE_LAST_ELEM &&
411 rule->iftype != STC_IFACE_UNKNOWN)
412 DB_ACTION(sqlite3_bind_int(stmt, pos++, rule->iftype));
414 DB_ACTION(sqlite3_bind_int64(stmt, pos++, rule->interval->from));
415 DB_ACTION(sqlite3_bind_int64(stmt, pos++, rule->interval->to));
417 if (sqlite3_step(stmt) != SQLITE_DONE) {
418 STC_LOGE("Failed to drop collected statistics."); //LCOV_EXCL_LINE
419 error_code = STC_ERROR_DB_FAILED; //LCOV_EXCL_LINE
420 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
421 goto handle_error; //LCOV_EXCL_LINE
424 STC_LOGD("Entry deleted successfully.");
430 stc_error_e table_statistics_foreach_app(const table_statistics_select_rule *rule,
431 table_statistics_info_cb info_cb,
434 __STC_LOG_FUNC_ENTER__;
435 table_statistics_info data;
437 stc_error_e error_code = STC_ERROR_NONE;
439 int pos = 1;/* running through positions where to
440 bind parameters in the query */
441 stc_db_tm_interval_s interval;
443 memset(&data, 0, sizeof(data));
445 if (!rule || !info_cb) {
446 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
447 return STC_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
450 /* pick a statement depending on parameters */
451 if (rule->granularity) {
452 stmt = __is_iftype_defined(rule->iftype) ?
453 select_chunks_iface : select_chunks;
455 DB_ACTION(sqlite3_bind_int64(stmt, pos++, rule->granularity));
456 data.interval = &interval;
458 stmt = __is_iftype_defined(rule->iftype)
459 ? select_for_period_iface : select_for_period;
462 DB_ACTION(sqlite3_bind_int64(stmt, pos++, rule->from));
463 DB_ACTION(sqlite3_bind_int64(stmt, pos++, rule->to));
465 if (__is_iftype_defined(rule->iftype)) {
466 data.iftype = rule->iftype;
467 DB_ACTION(sqlite3_bind_int(stmt, pos++, rule->iftype));
471 rc = sqlite3_step(stmt);
474 data.app_id = (char *)sqlite3_column_text(stmt, 0);
475 data.hw_net_protocol_type = sqlite3_column_int(stmt, 1);
476 data.roaming = sqlite3_column_int(stmt, 2);
477 data.cnt.in_bytes = sqlite3_column_int64(stmt, 3);
478 data.cnt.out_bytes = sqlite3_column_int64(stmt, 4);
479 data.subscriber_id = (char *)sqlite3_column_text(stmt, 5);
480 data.ground = sqlite3_column_int(stmt, 6);
481 data.iftype = sqlite3_column_int(stmt, 7);
482 data.ifname = (char *)sqlite3_column_text(stmt, 8);
484 if (rule->granularity) {
485 interval.from = sqlite3_column_int64(stmt, 9);
486 interval.to = interval.from + rule->granularity;
489 if (info_cb(&data, user_data) == STC_CANCEL)
490 rc = SQLITE_DONE; //LCOV_EXCL_LINE
491 __STC_LOG_FUNC_EXIT__;
494 __STC_LOG_FUNC_EXIT__;
498 error_code = STC_ERROR_DB_FAILED; //LCOV_EXCL_LINE
499 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
500 break; //LCOV_EXCL_LINE
502 } while (rc == SQLITE_ROW);
506 __STC_LOG_FUNC_EXIT__;
510 stc_error_e table_statistics_per_app(const char *app_id,
511 table_statistics_select_rule *rule,
512 table_statistics_info_cb info_cb,
515 __STC_LOG_FUNC_ENTER__;
516 table_statistics_info data;
518 stc_error_e error_code = STC_ERROR_NONE;
520 int pos = 1; /* running through positions
521 where to bind parameters in the query */
522 stc_db_tm_interval_s interval;
524 memset(&data, 0, sizeof(data));
526 if (!rule || !info_cb) {
527 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
528 return STC_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
531 /* pick a statement depending on parameters.
532 See comment for details_stms */
533 stmt = __select_statement(app_id, rule);
535 if (rule->granularity) {
536 DB_ACTION(sqlite3_bind_int64(stmt, pos++, rule->granularity));
537 data.interval = &interval;
540 DB_ACTION(sqlite3_bind_int64(stmt, pos++, rule->from));
541 DB_ACTION(sqlite3_bind_int64(stmt, pos++, rule->to));
543 if (strlen(app_id) > 0) {
544 DB_ACTION(sqlite3_bind_text(stmt, pos++, app_id, -1,
546 data.app_id = (char *)app_id;
549 if (__is_iftype_defined(rule->iftype))
550 DB_ACTION(sqlite3_bind_int(stmt, pos++, rule->iftype));
553 rc = sqlite3_step(stmt);
556 data.iftype = sqlite3_column_int(stmt, 0);
557 data.hw_net_protocol_type = sqlite3_column_int(stmt, 1);
558 data.roaming = sqlite3_column_int(stmt, 2);
559 data.cnt.in_bytes = sqlite3_column_int64(stmt, 3);
560 data.cnt.out_bytes = sqlite3_column_int64(stmt, 4);
561 data.ifname = (char *)sqlite3_column_text(stmt, 5);
562 data.subscriber_id = (char *)sqlite3_column_text(stmt, 6);
563 data.ground = sqlite3_column_int(stmt, 7);
565 if (rule->granularity) {
566 interval.from = sqlite3_column_int64(stmt, 8);
567 interval.to = interval.from + rule->granularity;
570 if (info_cb(&data, user_data) == STC_CANCEL)
571 rc = SQLITE_DONE; //LCOV_EXCL_LINE
572 __STC_LOG_FUNC_EXIT__;
575 __STC_LOG_FUNC_EXIT__;
579 error_code = STC_ERROR_DB_FAILED; //LCOV_EXCL_LINE
580 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
581 break; //LCOV_EXCL_LINE
583 } while (rc == SQLITE_ROW);
587 __STC_LOG_FUNC_EXIT__;
591 stc_error_e table_statistics_insert(stc_db_classid_iftype_key *stat_key,
592 stc_db_app_stats *stat,
593 time_t last_touch_time)
595 stc_error_e error_code = STC_ERROR_NONE;
596 sqlite3_stmt *stmt = update_statistics_query;
597 stc_hw_net_protocol_type_e hw_net_protocol_type = STC_PROTOCOL_UNKNOWN;
599 if (!stat->rcv_count && !stat->snd_count) {
600 error_code = STC_ERROR_INVALID_PARAMETER;
604 DB_ACTION(sqlite3_bind_text(stmt, 1, stat->app_id, -1,
606 DB_ACTION(sqlite3_bind_int(stmt, 2, stat->rcv_count));
607 DB_ACTION(sqlite3_bind_int(stmt, 3, stat->snd_count));
608 DB_ACTION(sqlite3_bind_int64(stmt, 4,
609 (sqlite3_int64)(last_touch_time)));
610 DB_ACTION(sqlite3_bind_int(stmt, 5, (int)(stat_key->iftype)));
611 DB_ACTION(sqlite3_bind_int(stmt, 6, (int)(stat->is_roaming)));
612 DB_ACTION(sqlite3_bind_int(stmt, 7, (int)hw_net_protocol_type));
613 DB_ACTION(sqlite3_bind_text(stmt, 8, stat_key->ifname, -1,
615 DB_ACTION(sqlite3_bind_text(stmt, 9,
616 stat_key->subscriber_id ? stat_key->subscriber_id : "" , -1,
618 DB_ACTION(sqlite3_bind_int(stmt, 10, (int)stat->ground));
620 /*we want to reuse tree*/
623 if (sqlite3_step(stmt) != SQLITE_DONE) {
624 STC_LOGE("Failed to record appstat. %s", //LCOV_EXCL_LINE
625 sqlite3_errmsg(stc_db_get_database()));
626 error_code = STC_ERROR_DB_FAILED; //LCOV_EXCL_LINE
627 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
628 goto handle_error; //LCOV_EXCL_LINE
632 STC_LOGD("App stat recorded [%s]", stat->app_id);
640 * This function will be somewhere consumer and will not be placed in this file.
643 stc_error_e table_statistics_store_result(app_stat_tree *stats)
647 pthread_rwlock_rdlock(&stats->guard);
648 WALK_TREE(stats->tree, print_appstat);
649 pthread_rwlock_unlock(&stats->guard);
652 stats->last_touch_time = current_time;
654 /* it's reader only, we don't modify tree, don't reduce it,
655 * due we want to reuse it in next iteration */
656 pthread_rwlock_rdlock(&stats->guard);
657 g_tree_foreach((GTree *) stats->tree, __store_application_stat,
658 &stats->last_touch_time);
660 pthread_rwlock_unlock(&stats->guard);
662 change_db_entries_num_num(g_tree_nnodes((GTree *)stats->tree));
664 return STC_ERROR_NONE;
668 stc_error_e table_statistics_prepare(sqlite3 *db)
670 __STC_LOG_FUNC_ENTER__;
672 stc_error_e error_code = STC_ERROR_NONE;
675 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
676 return STC_ERROR_DB_FAILED; //LCOV_EXCL_LINE
679 DB_ACTION(__prepare_delete(db));
680 DB_ACTION(__prepare_select(db));
681 DB_ACTION(__prepare_insert(db));
685 __STC_LOG_FUNC_EXIT__;
689 void table_statistics_finalize(void)
691 __STC_LOG_FUNC_ENTER__;
695 __STC_LOG_FUNC_EXIT__;