Remove profile build dependencies
[platform/core/context/context-service.git] / src / trigger / RuleManager.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 <TriggerTypes.h>
19 #include <TriggerRuleTypes.h>
20 #include <package_manager.h>
21 #include <Json.h>
22 #include "RuleManager.h"
23 #include "ContextMonitor.h"
24 #include "Rule.h"
25
26 #define RULE_TABLE "ContextTriggerRule"
27 #define RULE_IDS_JSON "{ \"" TRIG_KEY_ENABLED_IDS "\" : [ ] , \"" TRIG_KEY_DISABLED_IDS "\" : [ ] }";
28
29 using namespace ctx;
30 using namespace ctx::trigger;
31
32 static int __stringToInt(std::string str)
33 {
34         int i;
35         std::istringstream convert(str);
36
37         if (!(convert >> i))
38                 i = 0;
39
40         return i;
41 }
42
43 static std::string __intToString(int i)
44 {
45         std::ostringstream convert;
46         convert << i;
47         std::string str = convert.str();
48         return str;
49 }
50
51 RuleManager::RuleManager()
52 {
53 }
54
55 RuleManager::~RuleManager()
56 {
57         // Release rule instances
58         _D("Release rule instances");
59         for (auto it = __ruleMap.begin(); it != __ruleMap.end(); ++it) {
60                 Rule* rule = static_cast<Rule*>(it->second);
61
62                 int error = rule->stop();
63                 if (error != ERR_NONE) {
64                         _E("Failed to stop rule%d", it->first);
65                 }
66
67                 delete rule;
68         }
69         __ruleMap.clear();
70 }
71
72 bool RuleManager::init()
73 {
74         bool ret;
75         int error;
76
77         // Create tables into db (rule, template)
78         std::string q1 = std::string("status INTEGER DEFAULT 0 NOT NULL, creator TEXT DEFAULT '' NOT NULL,")
79                         + "packageId TEXT DEFAULT '' NOT NULL, description TEXT DEFAULT '',"
80                         + "details TEXT DEFAULT '' NOT NULL";
81         ret = __dbManager.createTableSync(RULE_TABLE, q1.c_str(), NULL);
82         IF_FAIL_RETURN_TAG(ret, false, _E, "Create rule table failed");
83
84         // Before re-enable rules, handle uninstalled app's rules
85         if (__getUninstalledApp() > 0) {
86                 error = __clearRuleOfUninstalledPackage(true);
87                 IF_FAIL_RETURN_TAG(error == ERR_NONE, false, _E, "Failed to remove uninstalled apps' rules while initialization");
88         }
89         ret = __reenableRule();
90
91         return ret;
92 }
93
94 void RuleManager::handleRuleOfUninstalledPackage(std::string pkgId)
95 {
96         __uninstalledPackages.insert(pkgId);
97         __clearRuleOfUninstalledPackage();
98 }
99
100 int RuleManager::__getUninstalledApp(void)
101 {
102         // Return number of uninstalled apps
103         std::string q1 = "SELECT DISTINCT packageId FROM ContextTriggerRule";
104
105         std::vector<Json> record;
106         bool ret = __dbManager.executeSync(q1.c_str(), &record);
107         IF_FAIL_RETURN_TAG(ret, -1, _E, "Query package ids of registered rules failed");
108
109         std::vector<Json>::iterator vecEnd = record.end();
110         for (std::vector<Json>::iterator vecPos = record.begin(); vecPos != vecEnd; ++vecPos) {
111                 Json elem = *vecPos;
112                 std::string pkgId;
113                 elem.get(NULL, "packageId", &pkgId);
114
115                 if (isUninstalledPackage(pkgId)) {
116                         __uninstalledPackages.insert(pkgId);
117                 }
118         }
119
120         return __uninstalledPackages.size();
121 }
122
123 bool RuleManager::isUninstalledPackage(std::string pkgId)
124 {
125         IF_FAIL_RETURN_TAG(!pkgId.empty(), false, _D, "Empty package id");
126
127         package_info_h pkgInfo;
128         int error = package_manager_get_package_info(pkgId.c_str(), &pkgInfo);
129
130         if (error == PACKAGE_MANAGER_ERROR_NONE) {
131                 package_info_destroy(pkgInfo);
132         } else if (error == PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE) {
133                 // Uninstalled package found
134                 _D("Uninstalled package found: %s", pkgId.c_str());
135                 return true;
136         } else {
137                 _E("Failed to get package info(%s): %d", pkgId.c_str(), error);
138         }
139
140         return false;
141 }
142
143 int RuleManager::__clearRuleOfUninstalledPackage(bool isInit)
144 {
145         if (__uninstalledPackages.size() <= 0) {
146                 return ERR_NONE;
147         }
148
149         int error;
150         bool ret;
151
152         _D("Clear uninstalled packages' rule started");
153         // Package list
154         std::string pkgList = "(";
155         std::set<std::string>::iterator it = __uninstalledPackages.begin();
156         pkgList += "packageId = '" + *it + "'";
157         it++;
158         for (; it != __uninstalledPackages.end(); ++it) {
159                 pkgList += " OR packageId = '" + *it + "'";
160         }
161         pkgList += ")";
162
163         // After event received, disable all the enabled rules of uninstalled apps
164         if (!isInit) {
165                 std::string q1 = "SELECT rowId FROM ContextTriggerRule WHERE status = 2 and (";
166                 q1 += pkgList;
167                 q1 += ")";
168
169                 std::vector<Json> record;
170                 ret = __dbManager.executeSync(q1.c_str(), &record);
171                 IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Failed to query enabled rules of uninstalled packages");
172
173                 std::vector<Json>::iterator vecEnd = record.end();
174                 for (std::vector<Json>::iterator vecPos = record.begin(); vecPos != vecEnd; ++vecPos) {
175                         Json elem = *vecPos;
176                         int ruleId;
177                         elem.get(NULL, "rowId", &ruleId);
178                         error = disableRule(ruleId);
179                         IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to disable rule");
180                 }
181                 _D("Uninstalled packages' rules are disabled");
182         }
183
184         // Delete rules of uninstalled packages from DB
185         std::string q2 = "DELETE FROM ContextTriggerRule WHERE " + pkgList;
186         std::vector<Json> dummy;
187         ret = __dbManager.executeSync(q2.c_str(), &dummy);
188         IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Failed to remove rules from db");
189         _D("Uninstalled packages' rules are deleted from db");
190
191         __uninstalledPackages.clear();
192
193         return ERR_NONE;
194 }
195
196 int RuleManager::pauseRuleWithItem(std::string& subject)
197 {
198         std::string q = "SELECT rowId FROM ContextTriggerRule WHERE (status=2) AND (details LIKE '%\"ITEM_NAME\":\"" + subject + "\"%');";
199         std::vector<Json> record;
200         bool ret = __dbManager.executeSync(q.c_str(), &record);
201         IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Failed to query rowIds to be paused");
202         IF_FAIL_RETURN(record.size() > 0, ERR_NONE);
203
204         _D("Pause rules related to %s", subject.c_str());
205         std::vector<Json>::iterator vecEnd = record.end();
206         for (std::vector<Json>::iterator vecPos = record.begin(); vecPos != vecEnd; ++vecPos) {
207                 Json elem = *vecPos;
208                 int rowId;
209                 elem.get(NULL, "rowId", &rowId);
210
211                 int error = pauseRule(rowId);
212                 IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to disable rules using custom item");
213         }
214
215         return ERR_NONE;
216 }
217
218 int RuleManager::resumeRuleWithItem(std::string& subject)
219 {
220         std::string q = "SELECT rowId FROM ContextTriggerRule WHERE (status=1) AND (details LIKE '%\"ITEM_NAME\":\"" + subject + "\"%');";
221         std::vector<Json> record;
222         bool ret = __dbManager.executeSync(q.c_str(), &record);
223         IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Query paused rule ids failed");
224         IF_FAIL_RETURN(record.size() > 0, ERR_NONE);
225
226         _D("Resume rules related to %s", subject.c_str());
227         std::string qRowId;
228         std::vector<Json>::iterator vecEnd = record.end();
229         for (std::vector<Json>::iterator vecPos = record.begin(); vecPos != vecEnd; ++vecPos) {
230                 Json elem = *vecPos;
231                 int rowId;
232                 elem.get(NULL, "rowId", &rowId);
233
234                 int error = enableRule(rowId);
235                 IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to resume rule");
236         }
237
238         return ERR_NONE;
239 }
240
241 bool RuleManager::__reenableRule(void)
242 {
243         int error;
244         std::string q = "SELECT rowId FROM ContextTriggerRule WHERE status = 2";
245
246         std::vector<Json> record;
247         bool ret = __dbManager.executeSync(q.c_str(), &record);
248         IF_FAIL_RETURN_TAG(ret, false, _E, "Query rowIds of enabled rules failed");
249         IF_FAIL_RETURN_TAG(record.size() > 0, true, _D, "No rule to re-enable");
250
251         _D(YELLOW("Re-enable rule started"));
252
253         std::string qRowId;
254         qRowId.clear();
255         std::vector<Json>::iterator vecEnd = record.end();
256         for (std::vector<Json>::iterator vecPos = record.begin(); vecPos != vecEnd; ++vecPos) {
257                 Json elem = *vecPos;
258                 int rowId;
259                 elem.get(NULL, "rowId", &rowId);
260
261                 error = enableRule(rowId);
262                 if (error == ERR_NOT_SUPPORTED) {
263                         qRowId += "(rowId = " + __intToString(rowId) + ") OR ";
264                 } else if (error != ERR_NONE) {
265                         _E("Re-enable rule%d failed(%d)", rowId, error);
266                 }
267         }
268         IF_FAIL_RETURN(!qRowId.empty(), true);
269         qRowId = qRowId.substr(0, qRowId.length() - 4);
270
271         // For rules which is failed to re-enable
272         std::string qUpdate = "UPDATE ContextTriggerRule SET status = 1 WHERE " + qRowId;
273         std::vector<Json> record2;
274         ret = __dbManager.executeSync(qUpdate.c_str(), &record2);
275         IF_FAIL_RETURN_TAG(ret, false, _E, "Failed to update rules as paused");
276
277         return true;
278 }
279
280 bool RuleManager::__ruleEquals(Json& lRule, Json& rRule)
281 {
282         // Compare event
283         Json lEvent, rEvent;
284         lRule.get(NULL, TRIG_RULE_KEY_EVENT, &lEvent);
285         rRule.get(NULL, TRIG_RULE_KEY_EVENT, &rEvent);
286
287         std::string lEOp, rEOp;
288         lRule.get(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_EVENT_LOGICAL_OP, &lEOp);
289         rRule.get(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_EVENT_LOGICAL_OP, &rEOp);
290
291         if (lEOp != rEOp || lEvent != rEvent)
292                 return false;
293
294         // Compare conditions
295         int lCondCnt, rCondCnt;
296         lCondCnt = lRule.getSize(NULL, TRIG_RULE_KEY_CONDITION);
297         rCondCnt = rRule.getSize(NULL, TRIG_RULE_KEY_CONDITION);
298         if (lCondCnt != rCondCnt)
299                 return false;
300
301         std::string lOp, rOp;
302         lRule.get(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_RULE_LOGICAL_OP, &lOp);
303         rRule.get(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_RULE_LOGICAL_OP, &rOp);
304         if (lOp != rOp)
305                 return false;
306
307         for (int i = 0; i < lCondCnt; i++) {
308                 bool found = false;
309                 Json lCond;
310                 lRule.getAt(NULL, TRIG_RULE_KEY_CONDITION, i, &lCond);
311
312                 std::string lCOp;
313                 lRule.getAt(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_CONDITION_LOGICAL_OP, i, &lCOp);
314
315                 for (int j = 0; j < lCondCnt; j++) {
316                         Json rCond;
317                         rRule.getAt(NULL, TRIG_RULE_KEY_CONDITION, j, &rCond);
318
319                         std::string rCOp;
320                         rRule.getAt(_TRIG_RULE_KEY_EXTRA, _TRIG_RULE_KEY_CONDITION_LOGICAL_OP, j, &rCOp);
321
322                         if (lCOp == rCOp && lCond == rCond) {
323                                 found = true;
324                                 break;
325                         }
326                 }
327                 if (!found)
328                         return false;
329         }
330
331         // Compare action
332         Json lAction, rAction;
333         lRule.get(NULL, TRIG_RULE_KEY_ACTION, &lAction);
334         rRule.get(NULL, TRIG_RULE_KEY_ACTION, &rAction);
335         if (lAction != rAction)
336                 return false;
337
338         return true;
339 }
340
341 int64_t RuleManager::__getDuplicatedRuleId(std::string pkgId, Json& rule)
342 {
343         std::string q = "SELECT rowId, description, details FROM ContextTriggerRule WHERE packageId = '";
344         q += pkgId;
345         q += "'";
346
347         std::vector<Json> record;
348         bool ret = __dbManager.executeSync(q.c_str(), &record);
349         IF_FAIL_RETURN_TAG(ret, false, _E, "Query rowId, details by package id failed");
350
351         std::string rDesc;
352         rule.get(NULL, TRIG_RULE_KEY_DESCRIPTION, &rDesc);
353         Json rDetails = rule.str();
354         rDetails.remove(NULL, TRIG_RULE_KEY_DESCRIPTION);
355
356         std::vector<Json>::iterator vecEnd = record.end();
357         for (std::vector<Json>::iterator vecPos = record.begin(); vecPos != vecEnd; ++vecPos) {
358                 Json elem = *vecPos;
359                 std::string dStr;
360                 Json details;
361
362                 elem.get(NULL, "details", &dStr);
363                 details = dStr;
364
365                 if (__ruleEquals(rDetails, details)) {
366                         int64_t rowId;
367                         elem.get(NULL, "rowId", &rowId);
368
369                         // Description comparison
370                         std::string desc;
371                         elem.get(NULL, "description", &desc);
372                         if (rDesc.compare(desc)) {
373                                 // Only description is changed
374                                 std::string qUpdate = "UPDATE ContextTriggerRule SET description='" + rDesc + "' WHERE rowId = " + __intToString(rowId);
375
376                                 std::vector<Json> dummy;
377                                 ret = __dbManager.executeSync(qUpdate.c_str(), &dummy);
378                                 if (ret) {
379                                         _D("Rule%lld description is updated", rowId);
380                                 } else {
381                                         _W("Failed to update description of rule%lld", rowId);
382                                 }
383                         }
384
385                         return rowId;
386                 }
387         }
388
389         return -1;
390 }
391
392 int RuleManager::__verifyRule(Json& rule, const char* creator)
393 {
394         ContextMonitor* ctxMonitor = ContextMonitor::getInstance();
395         IF_FAIL_RETURN_TAG(ctxMonitor, ERR_OUT_OF_MEMORY, _E, "Memory allocation failed");
396
397         // Event
398         Json event;
399         rule.get(NULL, TRIG_RULE_KEY_EVENT, &event);
400
401         std::list<std::string> eventKey;
402         event.getKeys(&eventKey);
403         IF_FAIL_RETURN_TAG(eventKey.size() == 1, ERR_INVALID_PARAMETER, _E, "Invalid event");
404
405         std::string eventName = *eventKey.begin();
406         IF_FAIL_RETURN_TAG(ctxMonitor->isSupported(eventName), ERR_NOT_SUPPORTED, _I, "Event(%s) is not supported", eventName.c_str());
407
408         if (!ctxMonitor->isAllowed(creator, eventName.c_str())) {
409                 _W("Permission denied for '%s'", eventName.c_str());
410                 return ERR_PERMISSION_DENIED;
411         }
412
413         // Conditions
414         Json cond;
415         for (int i = 0; rule.getAt(NULL, TRIG_RULE_KEY_CONDITION, i, &cond); i++) {
416                 std::list<std::string> condKey;
417                 cond.getKeys(&condKey);
418                 IF_FAIL_RETURN_TAG(condKey.size() == 1, ERR_INVALID_PARAMETER, _E, "Invalid condition");
419
420                 std::string condName = *condKey.begin();
421                 IF_FAIL_RETURN_TAG(ctxMonitor->isSupported(condName), ERR_NOT_SUPPORTED, _I, "Condition(%s) is not supported", condName.c_str());
422
423                 if (!ctxMonitor->isAllowed(creator, condName.c_str())) {
424                         _W("Permission denied for '%s'", condName.c_str());
425                         return ERR_PERMISSION_DENIED;
426                 }
427         }
428
429         return ERR_NONE;
430 }
431
432 int RuleManager::addRule(std::string creator, const char* pkgId, Json rule, Json* ruleId)
433 {
434         bool ret;
435         int64_t rid;
436
437         // Check if all items are supported && allowed to access
438         int err = __verifyRule(rule, creator.c_str());
439         IF_FAIL_RETURN(err == ERR_NONE, err);
440
441         // Check if duplicated rule exits
442         if ((rid = __getDuplicatedRuleId(pkgId, rule)) > 0) {
443                 // Save rule id
444                 ruleId->set(NULL, TRIG_KEY_RULE_ID, rid);
445                 _D("Duplicated rule found");
446                 return ERR_NONE;
447         }
448
449         // Insert rule to rule table, get rule id
450         Json record;
451         std::string description;
452         rule.get(NULL, TRIG_RULE_KEY_DESCRIPTION, &description);
453
454         Json details = rule.str();
455         details.remove(NULL, TRIG_RULE_KEY_DESCRIPTION);
456         record.set(NULL, "details", details.str());
457
458         record.set(NULL, "creator", creator);
459         if (pkgId) {
460                 record.set(NULL, "packageId", pkgId);
461         }
462         record.set(NULL, "description", description);
463
464         ret = __dbManager.insertSync(RULE_TABLE, record, &rid);
465         IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Insert rule to db failed");
466
467         // Save rule id
468         ruleId->set(NULL, TRIG_KEY_RULE_ID, rid);
469
470         _D("Add rule%d succeeded", (int)rid);
471         return ERR_NONE;
472 }
473
474
475 int RuleManager::removeRule(int ruleId)
476 {
477         bool ret;
478
479         // Delete rule from DB
480         std::string query = "DELETE FROM 'ContextTriggerRule' where rowId = ";
481         query += __intToString(ruleId);
482
483         std::vector<Json> record;
484         ret = __dbManager.executeSync(query.c_str(), &record);
485         IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Remove rule from db failed");
486
487         _D("Remove rule%d succeeded", ruleId);
488
489         return ERR_NONE;
490 }
491
492 int RuleManager::enableRule(int ruleId)
493 {
494         int error;
495         std::string query;
496         std::vector<Json> record;
497         std::vector<Json> dummy;
498         std::string pkgId;
499         Json jRule;
500         std::string tmp;
501         std::string idStr = __intToString(ruleId);
502
503         Rule* rule;
504
505         // Get rule Json by rule id;
506         query = "SELECT details, packageId FROM ContextTriggerRule WHERE rowId = ";
507         query += idStr;
508         error = (__dbManager.executeSync(query.c_str(), &record))? ERR_NONE : ERR_OPERATION_FAILED;
509         IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Query rule by rule id failed");
510
511         record[0].get(NULL, "details", &tmp);
512         jRule = tmp;
513         record[0].get(NULL, "packageId", &pkgId);
514
515         // Create a rule instance
516         rule = new(std::nothrow) Rule(ruleId, jRule, pkgId.c_str(), this);
517         IF_FAIL_RETURN_TAG(rule, ERR_OUT_OF_MEMORY, _E, "Failed to create rule instance");
518
519         // Start the rule
520         error = rule->start();
521         IF_FAIL_CATCH_TAG(error == ERR_NONE, _E, "Failed to start rule%d", ruleId);
522
523         // Update db to set 'enabled'
524         query = "UPDATE ContextTriggerRule SET status = 2 WHERE rowId = ";
525         query += idStr;
526         error = (__dbManager.executeSync(query.c_str(), &dummy))? ERR_NONE : ERR_OPERATION_FAILED;
527         IF_FAIL_CATCH_TAG(error == ERR_NONE, _E, "Update db failed");
528
529         // Add rule instance to __ruleMap
530         __ruleMap[ruleId] = rule;
531
532         _D(YELLOW("Enable Rule%d succeeded"), ruleId);
533         return ERR_NONE;
534
535 CATCH:
536         delete rule;
537         rule = NULL;
538
539         return error;
540 }
541
542 int RuleManager::disableRule(int ruleId)
543 {
544         bool ret;
545         int error;
546
547         auto it = __ruleMap.find(ruleId);
548         bool paused = (it == __ruleMap.end());
549
550         // For 'enabled' rule, not 'paused'
551         if (!paused) {
552                 // Stop the rule
553                 Rule* rule = static_cast<Rule*>(it->second);
554                 error = rule->stop();
555                 IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to stop rule%d", ruleId);
556
557                 // Remove rule instance from __ruleMap
558                 delete rule;
559                 __ruleMap.erase(it);
560         }
561
562         // Update db to set 'disabled'  // TODO skip while clear uninstalled rule
563         std::string query = "UPDATE ContextTriggerRule SET status = 0 WHERE rowId = ";
564         query += __intToString(ruleId);
565         std::vector<Json> record;
566         ret = __dbManager.executeSync(query.c_str(), &record);
567         IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Update db failed");
568
569         _D(YELLOW("Disable Rule%d succeeded"), ruleId);
570         return ERR_NONE;
571 }
572
573 int RuleManager::pauseRule(int ruleId)
574 {
575         bool ret;
576         int error;
577
578         auto it = __ruleMap.find(ruleId);
579         IF_FAIL_RETURN_TAG(it != __ruleMap.end(), ERR_OPERATION_FAILED, _E, "Rule instance not found");
580
581         // Stop the rule
582         Rule* rule = static_cast<Rule*>(it->second);
583         error = rule->stop();
584         IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to stop rule%d", ruleId);
585
586         // Update db to set 'paused'
587         std::string query = "UPDATE ContextTriggerRule SET status = 1 WHERE rowId = ";
588
589         query += __intToString(ruleId);
590         std::vector<Json> record;
591         ret = __dbManager.executeSync(query.c_str(), &record);
592         IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Update db failed");
593
594         // Remove rule instance from __ruleMap
595         delete rule;
596         __ruleMap.erase(it);
597
598         _D(YELLOW("Pause Rule%d"), ruleId);
599         return ERR_NONE;
600 }
601
602 int RuleManager::checkRule(std::string pkgId, int ruleId)
603 {
604         // Get package id
605         std::string q = "SELECT packageId FROM ContextTriggerRule WHERE rowId =";
606         q += __intToString(ruleId);
607
608         std::vector<Json> record;
609         bool ret = __dbManager.executeSync(q.c_str(), &record);
610         IF_FAIL_RETURN_TAG(ret, false, _E, "Query package id by rule id failed");
611
612         if (record.size() == 0) {
613                 return ERR_NO_DATA;
614         }
615
616         std::string p;
617         record[0].get(NULL, "packageId", &p);
618
619         if (p.compare(pkgId) == 0) {
620                 return ERR_NONE;
621         }
622
623         return ERR_NO_DATA;
624 }
625
626 bool RuleManager::isRuleEnabled(int ruleId)
627 {
628         std::string q = "SELECT status FROM ContextTriggerRule WHERE rowId =";
629         q += __intToString(ruleId);
630
631         std::vector<Json> record;
632         bool ret = __dbManager.executeSync(q.c_str(), &record);
633         IF_FAIL_RETURN_TAG(ret, false, _E, "Query enabled by rule id failed");
634
635         int status;
636         record[0].get(NULL, "status", &status);
637
638         return (status != 0);
639 }
640
641 int RuleManager::getRuleById(std::string pkgId, int ruleId, Json* requestResult)
642 {
643         std::string q = "SELECT description FROM ContextTriggerRule WHERE (packageId = '";
644         q += pkgId;
645         q += "') and (rowId = ";
646         q += __intToString(ruleId);
647         q += ")";
648
649         std::vector<Json> record;
650         bool ret = __dbManager.executeSync(q.c_str(), &record);
651         IF_FAIL_RETURN_TAG(ret, false, _E, "Query rule by rule id failed");
652
653         if (record.size() == 0) {
654                 return ERR_NO_DATA;
655         } else if (record.size() != 1) {
656                 return ERR_OPERATION_FAILED;
657         }
658
659         std::string description;
660         record[0].get(NULL, "description", &description);
661
662         (*requestResult).set(NULL, TRIG_KEY_RULE_ID, ruleId);
663         (*requestResult).set(NULL, TRIG_RULE_KEY_DESCRIPTION, description);
664
665         return ERR_NONE;
666 }
667
668 int RuleManager::getRuleIds(std::string pkgId, Json* requestResult)
669 {
670         (*requestResult) = RULE_IDS_JSON;
671
672         std::string q = "SELECT rowId, status FROM ContextTriggerRule WHERE (packageId = '";
673         q += pkgId;
674         q += "')";
675
676         std::vector<Json> record;
677         bool ret = __dbManager.executeSync(q.c_str(), &record);
678         IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Query rules failed");
679
680         std::vector<Json>::iterator vecEnd = record.end();
681         for (std::vector<Json>::iterator vecPos = record.begin(); vecPos != vecEnd; ++vecPos) {
682                 Json elem = *vecPos;
683                 std::string id;
684                 int status;
685
686                 elem.get(NULL, "rowId", &id);
687                 elem.get(NULL, "status", &status);
688
689                 if (status >= 1) {
690                         (*requestResult).append(NULL, TRIG_KEY_ENABLED_IDS, __stringToInt(id));
691                 } else if (status == 0) {
692                         (*requestResult).append(NULL, TRIG_KEY_DISABLED_IDS, __stringToInt(id));
693                 }
694         }
695
696         return ERR_NONE;
697 }