Fix 'frequency' statistics for the trigger to emit proper results
[platform/core/context/statistics-context-provider.git] / src / social / db_handle.cpp
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include <sstream>
18 #include <contacts.h>
19 #include <types_internal.h>
20 #include <context_mgr.h>
21 #include <db_mgr.h>
22 #include "social_stats_types.h"
23 #include "db_handle.h"
24
25 ctx::social_db_handle::social_db_handle(const char* zone)
26         : stats_db_handle_base(zone)
27 {
28 }
29
30 ctx::social_db_handle::~social_db_handle()
31 {
32 }
33
34 int ctx::social_db_handle::read(const char* subject, ctx::json filter)
35 {
36         std::string query;
37
38         if (STR_EQ(subject, SOCIAL_SUBJ_FREQ_ADDRESS)) {
39                 query = create_sql_freq_address(filter);
40
41         } else if (STR_EQ(subject, SOCIAL_SUBJ_FREQUENCY)) {
42                 is_trigger_item = true;
43                 query = create_sql_frequency(filter);
44         }
45
46         IF_FAIL_RETURN(!query.empty(), ERR_OPERATION_FAILED);
47
48         bool ret = execute_query(subject, filter, query.c_str());
49         IF_FAIL_RETURN(ret, ERR_OPERATION_FAILED);
50
51         return ERR_NONE;
52 }
53
54 std::string ctx::social_db_handle::create_where_clause(ctx::json filter)
55 {
56         std::stringstream where_clause;
57         int comm_type = -1;
58
59         where_clause << stats_db_handle_base::create_where_clause(filter);
60
61         filter.get(NULL, SOCIAL_COMMUNICATION_TYPE, &comm_type);
62
63         switch(comm_type) {
64         case SOCIAL_COMMUNICATION_TYPE_CALL:
65                 where_clause <<
66                         " AND " SOCIAL_PHONE_LOG_TYPE " >= " << CONTACTS_PLOG_TYPE_VOICE_INCOMMING <<
67                         " AND " SOCIAL_PHONE_LOG_TYPE " <= " << CONTACTS_PLOG_TYPE_VIDEO_BLOCKED;
68                 break;
69         case SOCIAL_COMMUNICATION_TYPE_MESSAGE:
70                 where_clause <<
71                         " AND " SOCIAL_PHONE_LOG_TYPE " >= " << CONTACTS_PLOG_TYPE_MMS_INCOMMING <<
72                         " AND " SOCIAL_PHONE_LOG_TYPE " <= " << CONTACTS_PLOG_TYPE_MMS_BLOCKED;
73                 break;
74         default:
75                 break;
76         }
77
78         return where_clause.str();
79 }
80
81 std::string ctx::social_db_handle::create_sql_freq_address(ctx::json filter)
82 {
83         std::stringstream query;
84         int limit = DEFAULT_LIMIT;
85
86         filter.get(NULL, STATS_RESULT_SIZE, &limit);
87
88         query <<
89                 "SELECT " SOCIAL_ADDRESS ", " \
90                         "COUNT(*) AS " STATS_TOTAL_COUNT ", " \
91                         "SUM(" STATS_DURATION ") AS " STATS_TOTAL_DURATION ", " \
92                         "MAX(" STATS_UNIV_TIME ") AS " STATS_LAST_TIME \
93                 " FROM " SOCIAL_TABLE_CONTACT_LOG \
94                 " WHERE " << create_where_clause(filter) <<
95                 " GROUP BY " SOCIAL_ADDRESS \
96                 " ORDER BY COUNT(*) DESC" \
97                 " LIMIT " << limit;
98
99         return query.str();
100 }
101
102 std::string ctx::social_db_handle::create_sql_frequency(ctx::json filter)
103 {
104         ctx::json filter_cleaned;
105         std::string week_str;
106         std::string time_of_day;
107         std::string address;
108
109         if (!filter.get(NULL, SOCIAL_ADDRESS, &address)) {
110                 _E("Invalid parameter");
111                 return "";
112         }
113
114         /* TODO: Enable after fixing the log aggregator
115         if (filter.get(NULL, STATS_DAY_OF_WEEK, &week_str))
116                 filter_cleaned.set(NULL, STATS_DAY_OF_WEEK, week_str);
117
118         if (filter.get(NULL, STATS_TIME_OF_DAY, &time_of_day))
119                 filter_cleaned.set(NULL, STATS_TIME_OF_DAY, time_of_day);
120         */
121
122         std::stringstream query;
123
124         query <<
125                 "DELETE FROM " SOCIAL_TEMP_CONTACT_FREQ ";";
126
127         query <<
128                 "INSERT INTO " SOCIAL_TEMP_CONTACT_FREQ \
129                 " SELECT " SOCIAL_ADDRESS ", COUNT(*) AS " STATS_TOTAL_COUNT \
130                 " FROM " SOCIAL_TABLE_CONTACT_LOG \
131                 " WHERE " << create_where_clause(filter_cleaned) <<
132                 " GROUP BY " SOCIAL_ADDRESS ";";
133
134         query <<
135                 "INSERT OR IGNORE INTO " SOCIAL_TEMP_CONTACT_FREQ " (" SOCIAL_ADDRESS ")" \
136                 " VALUES ('" << address << "');";
137
138         query <<
139                 "SELECT S." SOCIAL_ADDRESS ", S." STATS_TOTAL_COUNT ", 1+COUNT(lesser." STATS_TOTAL_COUNT ") AS Rank" \
140                 " FROM " SOCIAL_TEMP_CONTACT_FREQ " AS S" \
141                 " LEFT JOIN " SOCIAL_TEMP_CONTACT_FREQ " AS lesser" \
142                 " ON S." STATS_TOTAL_COUNT " < lesser." STATS_TOTAL_COUNT \
143                 " WHERE S." SOCIAL_ADDRESS " = '" << address << "'";
144
145
146         return query.str();
147 }