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.
22 #include "InactiveDetector.h"
23 #include "InactiveDetectorStorage.h"
24 #include "InactiveDetectorStorageQueries.h"
25 #include "InactiveDetectorClassificator.h"
26 #include "AppInactiveDetectorTypes.h"
28 /*int ctx::InactiveDetectorStorage::create_table()
30 bool ret = __dbManager.createTable(0, WIFI_TABLE_NAME, WIFI_CREATE_TABLE_COLUMNS, NULL, NULL);
31 _D("Table Creation Request: %s", ret ? "SUCCESS" : "FAIL");
35 // expected Json format example: {timeframe: 1; isActive: 0}
36 int ctx::InactiveDetectorStorage::read(const char *subject, ctx::Json filter)
39 query = __getQueryGetApps(subject, filter);
41 IF_FAIL_RETURN(!query.empty(), ERR_OPERATION_FAILED);
43 bool ret = __dbManager.execute(STR_EQ(subject, APP_INACTIVE_SUBJ_GET_APPS_INACTIVE) ?
44 APP_INACTIVE_QUERY_ID_GET_APPS_INACTIVE : APP_INACTIVE_QUERY_ID_GET_APPS_ACTIVE,
47 IF_FAIL_RETURN(ret, ERR_OPERATION_FAILED);
52 std::string ctx::InactiveDetectorStorage::__getQueryGetApps(const char *subject, ctx::Json filter)
57 std::string query(GET_APP_INFO_INACTIVE_QUERY);
58 std::string placeholderTimeframe(APP_INACTIVE_DETECTOR_VALUE_PLACEHOLDER_TIMEFRAME);
59 std::string placeholderIsActive(APP_INACTIVE_DETECTOR_VALUE_PLACEHOLDER_CLUSTER);
61 filter.get(NULL, APP_INACTIVE_DETECTOR_DATA_TIMEFRAME, &timeframe);
62 filter.get(NULL, APP_INACTIVE_DETECTOR_DATA_ISACTIVE, &isActive);
64 std::stringstream timeframeStream;
65 timeframeStream << timeframe;
67 std::stringstream isActiveStream;
68 isActiveStream << isActive;
70 __injectParams(query, placeholderTimeframe, timeframeStream.str());
71 __injectParams(query, placeholderIsActive, isActiveStream.str());
76 std::string ctx::InactiveDetectorStorage::__getQueryUpdateApps(std::vector<AppInfo> *appsWithWeights)
78 std::string deleteQuery(DELETE_APP_ACTIVITY_CLASSIFIED_BY_TIMEFRAME);
79 std::string insertQuery(INSERT_APP_ACTIVITY_CLASSIFIED);
80 std::string placeholderTimeframe(APP_INACTIVE_DETECTOR_VALUE_PLACEHOLDER_TIMEFRAME);
81 std::string placeholderValues(APP_INACTIVE_DETECTOR_VALUE_PLACEHOLDER_VALUES);
82 std::string placeholderIsActive(APP_INACTIVE_DETECTOR_VALUE_PLACEHOLDER_CLUSTER);
84 std::stringstream timeframeStream;
85 timeframeStream << appsWithWeights->front().timeframe;
87 __injectParams(deleteQuery, placeholderTimeframe, timeframeStream.str());
88 __injectParams(insertQuery, placeholderValues, __getSubqueryFormValues(appsWithWeights));
90 std::stringstream result;
91 result << deleteQuery << insertQuery;
95 // foreach app_info id+cluster -> select for insert
96 std::string ctx::InactiveDetectorStorage::__getSubqueryFormValues(std::vector<AppInfo> *appsWithWeights)
98 std::stringstream selectElements;
100 for (auto row = appsWithWeights->begin(); row != appsWithWeights->end(); row++)
102 //SELECT 1 as isActive, 1 as timeframe, 3964 as context_app_info_id
103 std::stringstream selectElement;
104 selectElement << " SELECT " << row->isActive << " as ";
105 selectElement << APP_INACTIVE_DETECTOR_ACTIVITYCLASSIFIED_COLUMN_IS_ACTIVE;
106 selectElement << ", " << row->timeframe << " as ";
107 selectElement << APP_INACTIVE_DETECTOR_ACTIVITYCLASSIFIED_COLUMN_TIMEFRAME;
108 selectElement << ", " << row->id << " as ";
109 selectElement << APP_INACTIVE_DETECTOR_ACTIVITYCLASSIFIED_COLUMN_CONTEXT_APP_INFO_ID;
111 if ((row != appsWithWeights->end()) && (row == --appsWithWeights->end()))
112 selectElement << " UNION ";
114 selectElements << selectElement;
117 return selectElements.str();
120 void ctx::InactiveDetectorStorage::__jsonToObject(std::vector<Json>& records, std::vector<AppInfo> *appsWithWeights, bool resultMode)
122 for (auto row = records.begin(); row != records.end(); row++) {
123 AppInfo appWithWeight;
125 row->get(NULL, APP_INACTIVE_DETECTOR_APPINFO_COLUMN_PACKAGE_NAME, &appWithWeight.packageName);
126 row->get(NULL, APP_INACTIVE_DETECTOR_APPINFO_COLUMN_IS_NODISPLAY, &appWithWeight.isNodisplay);
127 row->get(NULL, APP_INACTIVE_DETECTOR_APPINFO_COLUMN_IS_ENABLED, &appWithWeight.isEnabled);
128 row->get(NULL, APP_INACTIVE_DETECTOR_APPINFO_COLUMN_IS_ATBOOT, &appWithWeight.isAtBoot);
129 row->get(NULL, APP_INACTIVE_DETECTOR_APPINFO_COLUMN_IS_PRELOADED, &appWithWeight.isPreloaded);
130 row->get(NULL, APP_INACTIVE_DETECTOR_VIRTUAL_COLUMN_WEIGHT, &appWithWeight.weight);
132 row->get(NULL, APP_INACTIVE_DETECTOR_APPINFO_COLUMN_ID, &appWithWeight.id);
133 row->get(NULL, APP_INACTIVE_DETECTOR_APPINFO_COLUMN_TIMESTAMP, &appWithWeight.timestamp);
134 row->get(NULL, APP_INACTIVE_DETECTOR_VIRTUAL_COLUMN_WEIGHT, &appWithWeight.weight);
135 row->get(NULL, APP_INACTIVE_DETECTOR_ACTIVITYCLASSIFIED_COLUMN_IS_ACTIVE, &appWithWeight.isActive);
138 appsWithWeights->push_back(appWithWeight);
142 void ctx::InactiveDetectorStorage::onExecuted(unsigned int queryId, int error, std::vector<Json>& records)
144 if (error != ERR_NONE) {
145 _E("queryId:%d, error:%d", queryId, error);
149 std::vector<AppInfo> *appsWithWeights = NULL;
150 if (queryId == APP_INACTIVE_QUERY_ID_GET_APPS_INACTIVE || queryId == APP_INACTIVE_QUERY_ID_GET_APPS_ACTIVE) {
151 __jsonToObject(records, appsWithWeights, TRUE);
152 } else if (queryId == APP_INACTIVE_QUERY_ID_GET_APPS_WEIGHT) {
153 __jsonToObject(records, appsWithWeights, FALSE);
155 if (appsWithWeights->size() > 0) {
156 InactiveDetectorClassificator inactDetClassificator;
157 int err = inactDetClassificator.classify(appsWithWeights);
159 if (err == ERR_NONE) {
161 query = __getQueryUpdateApps(appsWithWeights);
162 bool ret = __dbManager.execute(APP_INACTIVE_QUERY_ID_UPDATE_CLUSTERS, query.c_str(), this);
163 _D("load visits execute query result: %s", ret ? "SUCCESS" : "FAIL");
165 _E("classification queryId:%d, error:%d", queryId, err);
168 } else if (queryId == APP_INACTIVE_QUERY_ID_UPDATE_CLUSTERS) {
169 _D("UPDATE_CLUSTERS execute query id: %d", queryId);
171 _E("unknown queryId:%d", queryId);
175 void ctx::InactiveDetectorStorage::__injectParams(std::string& str, const std::string& from, const std::string& to)
181 while((startPos = str.find(from, startPos)) != std::string::npos) {
182 str.replace(startPos, from.length(), to);
183 startPos += to.length();
188 int ctx::InactiveDetectorStorage::updateRanks()
193 int ctx::InactiveDetectorStorage::getAppsInfoWithWeights(double timestampFrom)
195 std::stringstream timestampStream;
196 timestampStream << timestampFrom;
197 std::string timestampStr = timestampStream.str();
199 std::string query(GET_APP_INFO_W_WEIGHT_QUERY);
200 std::string placeholder(APP_INACTIVE_DETECTOR_VALUE_PLACEHOLDER_TIMESTAMP);
202 __injectParams(query, placeholder, timestampStr);
204 bool ret = __dbManager.execute(APP_INACTIVE_QUERY_ID_GET_APPS_WEIGHT, query.c_str(), this);
205 _D("load visits execute query result: %s", ret ? "SUCCESS" : "FAIL");