Refactor plugin parser 90/220790/8
authorhyunho <hhstark.kang@samsung.com>
Mon, 23 Dec 2019 08:11:04 +0000 (17:11 +0900)
committerHyunho Kang <hhstark.kang@samsung.com>
Mon, 30 Dec 2019 07:50:35 +0000 (07:50 +0000)
Change-Id: Ifb72236eaadda723df63d058860755d8c653b098
Signed-off-by: hyunho <hhstark.kang@samsung.com>
parser/complication_parser_plugin.cc
parser/complication_parser_plugin_internal.cc
scripts/504.watchface_complication_upgrade.sh
unittest/data/test.sql
unittest/src/test-main.cc
watchface-common/watchface-util.cc
watchface-common/watchface-util.h
watchface-complication-provider/complication-provider.cc
watchface-complication/db-manager.cc

index a2944ee..588fb47 100644 (file)
 #include <bundle.h>
 #include <bundle_cpp.h>
 
+#include <memory>
+#include <list>
+
 #include "watchface-complication/include/watchface-complication-internal.h"
 #include "watchface-complication/include/watchface-complication.h"
+#include "watchface-common/watchface-util.h"
 #include "watchface-common/watchface-common-internal.h"
 
 #include "parser/complication_parser_plugin_internal.h"
@@ -52,6 +56,7 @@
 
 using namespace std;
 using namespace tizen_base;
+using namespace watchface_complication;
 
 struct support_event_tag_map {
   const char* name;
@@ -134,13 +139,13 @@ int complication_parser_plugin_fini(void) {
   return 0;
 }
 
-static char* _get_attribute(xmlNode* node, const char* name) {
+static string _get_attribute(xmlNode* node, const char* name) {
   xmlChar* val;
-  char* attr = NULL;
+  string attr = "";
 
   val = xmlGetProp(node, (const xmlChar*)name);
   if (val) {
-    attr = strdup(reinterpret_cast<char*>(val));
+    attr = string(reinterpret_cast<char*>(val));
     xmlFree(val);
   }
 
@@ -371,91 +376,19 @@ static string _make_raw_default_data(xmlNode* node, int support_type) {
   }
 }
 
-static int _insert_parsed_data(sqlite3* db, sqlite3_stmt* stmt, xmlNode* node,
-    int support_type, const char* pkgid, const char* appid,
-    const char* providerid, int period, bool trusted) {
-  int idx = 1;
-  int ret = sqlite3_bind_text(stmt, idx++, pkgid, -1, SQLITE_TRANSIENT);
-  if (ret != SQLITE_OK) {
-    LOGE("sqlite3_bind_text() error: %d(%s)", ret, sqlite3_errmsg(db));
-    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
-  }
-
-  ret = sqlite3_bind_text(stmt, idx++, appid, -1, SQLITE_TRANSIENT);
-  if (ret != SQLITE_OK) {
-    LOGE("sqlite3_bind_text() error: %d(%s)", ret, sqlite3_errmsg(db));
-    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
-  }
-
-  ret = sqlite3_bind_text(stmt, idx++, providerid, -1, SQLITE_TRANSIENT);
-  if (ret != SQLITE_OK) {
-    LOGE("sqlite3_bind_text() error: %d(%s)", ret, sqlite3_errmsg(db));
-    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
-  }
-
-  ret = sqlite3_bind_int(stmt, idx++, trusted ? 1 : 0);
-  if (ret != SQLITE_OK) {
-    LOGE("sqlite3_bind_int() error: %d(%s)", ret, sqlite3_errmsg(db));
-    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
-  }
-
-  ret = sqlite3_bind_int(stmt, idx++, period);
-  if (ret != SQLITE_OK) {
-    LOGE("sqlite3_bind_int() error: %d(%s)", ret, sqlite3_errmsg(db));
-    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
-  }
-
-  ret = sqlite3_bind_int(stmt, idx++, support_type);
-  if (ret != SQLITE_OK) {
-    LOGE("sqlite3_bind_int() error: %d(%s)", ret, sqlite3_errmsg(db));
-    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
-  }
-
-  string raw_default_data = _make_raw_default_data(node, support_type);
-  if (raw_default_data.empty())
-    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
-
-  ret = sqlite3_bind_text(stmt, idx, raw_default_data.c_str(),
-      -1, SQLITE_TRANSIENT);
-  if (ret != SQLITE_OK) {
-    LOGE("sqlite3_bind_text() error: %d(%s)", ret, sqlite3_errmsg(db));
-    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
-  }
-
-  ret = sqlite3_step(stmt);
-  if (ret != SQLITE_DONE) {
-    LOGE("step error: %d(%s)", ret, sqlite3_errmsg(db));
-    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
-  }
-
-  ret = sqlite3_reset(stmt);
-  if (ret != SQLITE_OK) {
-    LOGE("sqlite3_reset() error: %d", ret);
-    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
-  }
-  sqlite3_clear_bindings(stmt);
-  return WATCHFACE_COMPLICATION_ERROR_NONE;
-}
-
-static int _parse_support_type(xmlNode* node, sqlite3* db, const char* pkgid,
-      const char* appid, const char* providerid, int period, bool trusted) {
-  int ret;
-  sqlite3_stmt* stmt = nullptr;
+static bool _parse_support_type(xmlNode* node, shared_ptr<util::DBHelper>& db,
+    string providerid) {
 
   static const char query[] =
-    "INSERT INTO complication_provider ( "
-    "pkgid, appid, provider_id, trusted, period, "
-    "support_type, default_data) "
-    "VALUES (?, ?, ?, ?, ?, ?, ?)";
+    "INSERT INTO provider_support_types ( "
+    "provider_id, support_type, default_data) "
+    "VALUES (?, ?, ?)";
 
   if (node->children == NULL)
-    return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
+    return false;
 
-  ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
-  if (ret != SQLITE_OK) {
-    LOGE("prepare error: %d(%s)", ret, sqlite3_errmsg(db));
-    return WATCHFACE_COMPLICATION_ERROR_IO_ERROR;
-  }
+  if (!db->Prepare(query))
+    return false;
 
   xmlNode* c_node;
   for (c_node = node->children; c_node; c_node = c_node->next) {
@@ -465,396 +398,324 @@ static int _parse_support_type(xmlNode* node, sqlite3* db, const char* pkgid,
 
     int support_type = _get_support_type_tag(c_node);
     if (!support_type) {
-      LOGE("not supported type");
-      sqlite3_finalize(stmt);
-      return WATCHFACE_COMPLICATION_ERROR_INVALID_PARAMETER;
+      LOGE("Wrong supported type");
+      return false;
     }
 
-    ret = _insert_parsed_data(db,
-        stmt, c_node, support_type, pkgid, appid, providerid, period, trusted);
-    if (ret != WATCHFACE_COMPLICATION_ERROR_NONE) {
-      sqlite3_finalize(stmt);
-      return ret;
-    }
+    if (!db->Bind(1, providerid))
+      return false;
+
+    if (!db->Bind(2, support_type))
+      return false;
+
+    string raw_default_data = _make_raw_default_data(c_node, support_type);
+    if (raw_default_data.empty())
+      return false;
+
+    if (!db->Bind(3, raw_default_data))
+      return false;
+
+    if (db->Step() != SQLITE_DONE)
+      return false;
+
+    if (db->Reset() != SQLITE_OK)
+      return false;
   }
-  sqlite3_finalize(stmt);
 
-  return ret;
+  return true;
 }
 
-static int _parse_label(xmlNode* node, sqlite3* db, const char* providerid) {
-  int ret;
-  int idx;
-  sqlite3_stmt* stmt = NULL;
-  xmlChar* lang = NULL;
-
+static bool _parse_label(xmlNode* node, shared_ptr<util::DBHelper>& db,
+    string providerid) {
+  xmlChar* lang = nullptr;
   static const char query[] =
     "INSERT INTO provider_localized_info "
     "(provider_id, locale, provider_label) "
     "VALUES (?, ?, ?)";
 
-  ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
-  if (ret != SQLITE_OK) {
-    LOGE("prepare error: %d(%s)", ret, sqlite3_errmsg(db));
-    goto out;
-  }
-
-  lang = xmlNodeGetLang(node);
+  if (!db->Prepare(query))
+    return false;
 
-  idx = 1;
+  if (!db->Bind(1, providerid))
+    return false;
 
-  ret = sqlite3_bind_text(stmt, idx++, providerid, -1, SQLITE_TRANSIENT);
-  if (ret != SQLITE_OK) {
-    LOGE("sqlite3_bind_text() error: %d(%s)", ret, sqlite3_errmsg(db));
-    goto out;
-  }
-
-  if (lang)
-    ret = sqlite3_bind_text(stmt, idx++, reinterpret_cast<char*>(lang), -1,
-                        SQLITE_TRANSIENT);
-  else
-    ret = sqlite3_bind_text(stmt, idx++, "No Locale", -1, SQLITE_TRANSIENT);
-  if (ret != SQLITE_OK) {
-    LOGE("sqlite3_bind_text() error: %d(%s)", ret, sqlite3_errmsg(db));
-    goto out;
-  }
-
-  ret = sqlite3_bind_text(stmt, idx, reinterpret_cast<char*>(node->children->content),
-                        -1, SQLITE_TRANSIENT);
-  if (ret != SQLITE_OK) {
-    LOGE("sqlite3_bind_text() error: %d(%s)", ret, sqlite3_errmsg(db));
-    goto out;
-  }
-
-  ret = sqlite3_step(stmt);
-  if (ret != SQLITE_DONE) {
-    LOGE("step error: %d(%s)", ret, sqlite3_errmsg(db));
-    goto out;
+  lang = xmlNodeGetLang(node);
+  if (lang) {
+    bool ret = db->Bind(2, reinterpret_cast<char*>(lang));
+    xmlFree(lang);
+    if (!ret)
+      return false;
+  } else {
+    if (!db->Bind(2, "No Locale"))
+      return false;
   }
 
-  ret = 0;
-out:
-  if (stmt)
-    sqlite3_finalize(stmt);
+  if (!db->Bind(3, reinterpret_cast<char*>(node->children->content)))
+    return false;
 
-  if (lang)
-    xmlFree(lang);
+  if (db->Step() != SQLITE_DONE)
+    return false;
 
-  return ret;
+  if (db->Reset() != SQLITE_OK)
+    return false;
+  return true;
 }
 
-static int _parse_privilege(xmlNode* node, sqlite3* db,
-    const char* providerid) {
-  int ret;
-  sqlite3_stmt* stmt = NULL;
+static bool _parse_privilege(xmlNode* node, shared_ptr<util::DBHelper>& db,
+    string providerid) {
   xmlNode* tmp;
-
   static const char query[] =
     "INSERT INTO provider_privilege "
     "(provider_id, privilege) "
     "VALUES (?, ?)";
 
   if (node->children == NULL)
-    return -1;
-
-  ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
-  if (ret != SQLITE_OK) {
-    LOGE("prepare error: %d(%s)", ret, sqlite3_errmsg(db));
-    goto out;
-  }
+    return true;
 
+  if (!db->Prepare(query))
+    return false;
   for (tmp = node->children; tmp; tmp = tmp->next) {
-    if (!xmlStrcasecmp(tmp->name, (const xmlChar*)"privilege")) {
-      ret = sqlite3_bind_text(stmt, 1, providerid, -1, SQLITE_TRANSIENT);
-      if (ret != SQLITE_OK) {
-        LOGE("sqlite3_bind_text() error: %d(%s)", ret, sqlite3_errmsg(db));
-        goto out;
-      }
-
-      ret = sqlite3_bind_text(stmt, 2, (char*)tmp->children->content, -1,
-                        SQLITE_TRANSIENT);
-      if (ret != SQLITE_OK) {
-        LOGE("sqlite3_bind_text() error: %d(%s)", ret, sqlite3_errmsg(db));
-        goto out;
-      }
-
-      ret = sqlite3_step(stmt);
-      if (ret != SQLITE_DONE) {
-        LOGE("step error: %d(%s)", ret, sqlite3_errmsg(db));
-        goto out;
-      }
-
-      ret = sqlite3_reset(stmt);
-      if (ret != SQLITE_OK) {
-        LOGE("sqlite3_reset() error: %d", ret);
-        goto out;
-      }
+    if (xmlStrcasecmp(tmp->name, (const xmlChar*)"privilege"))
+      continue;
 
-      sqlite3_clear_bindings(stmt);
-    }
+    if (!db->Bind(1, providerid))
+      return false;
+    if (!db->Bind(2, (char*)tmp->children->content))
+      return false;
+    if (db->Step() != SQLITE_DONE)
+      return false;
+    if (db->Reset() != SQLITE_OK)
+      return false;
   }
 
-  ret = 0;
-out:
-  if (stmt)
-    sqlite3_finalize(stmt);
-
-  return ret;
+  return true;
 }
 
-static int _parse_support_event(xmlNode* node, sqlite3* db,
-    const char* providerid) {
-  int ret;
-  sqlite3_stmt* stmt = NULL;
-  xmlNode* tmp;
+static bool _parse_support_event(xmlNode* node, shared_ptr<util::DBHelper>& db,
+    string providerid) {
+  if (node->children == nullptr)
+    return true;
+
   int support_events = 0;
+  for (xmlNode* tmp = node->children; tmp; tmp = tmp->next) {
+    if (xmlStrcasecmp(tmp->name, (const xmlChar*)"event"))
+      continue;
+
+    int ret = _get_support_event_tag(tmp);
+    if (ret != 0)
+      support_events |= ret;
+  }
+
+  if (support_events == 0)
+    return true;
 
   static const char query[] =
     "INSERT INTO provider_support_events "
     "(provider_id, support_events) "
     "VALUES (?, ?)";
 
-  if (node->children == NULL)
-    return -1;
-
-  for (tmp = node->children; tmp; tmp = tmp->next) {
-    if (!xmlStrcasecmp(tmp->name, (const xmlChar*)"event")) {
-      ret = _get_support_event_tag(tmp);
-      if (ret != 0)
-        support_events |= ret;
-    }
-  }
-
-  if (support_events != 0) {
-    ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
-    if (ret != SQLITE_OK) {
-      LOGE("prepare error: %d(%s)", ret, sqlite3_errmsg(db));
-      goto out;
-    }
-
-    ret = sqlite3_bind_text(stmt, 1, providerid, -1, SQLITE_TRANSIENT);
-    if (ret != SQLITE_OK) {
-      LOGE("sqlite3_bind_text() error: %d(%s)", ret, sqlite3_errmsg(db));
-      goto out;
-    }
-
-    ret = sqlite3_bind_int(stmt, 2, support_events);
-    if (ret != SQLITE_OK) {
-      LOGE("sqlite3_bind_int() error: %d(%s)", ret, sqlite3_errmsg(db));
-      goto out;
-    }
+  if (!db->Prepare(query))
+    return false;
 
-    ret = sqlite3_step(stmt);
-    if (ret != SQLITE_DONE) {
-      LOGE("step error: %d(%s)", ret, sqlite3_errmsg(db));
-      goto out;
-    }
+  if (!db->Bind(1, providerid))
+    return false;
 
-    ret = sqlite3_reset(stmt);
-    if (ret != SQLITE_OK) {
-      LOGE("sqlite3_reset() error: %d", ret);
-      goto out;
-    }
+  if (!db->Bind(2, support_events))
+    return false;
 
-    sqlite3_clear_bindings(stmt);
-  }
+  if (db->Step() != SQLITE_DONE)
+    return false;
 
-  ret = 0;
-out:
-  if (stmt)
-    sqlite3_finalize(stmt);
+  if (db->Reset() != SQLITE_OK)
+    return false;
 
-  return ret;
+  return true;
 }
 
-static int _parse_setup_appid(sqlite3* db, const char* providerid,
-      const char* setup_appid) {
-  int ret;
-  sqlite3_stmt* stmt = NULL;
+static bool _insert_setup_appid(shared_ptr<util::DBHelper>& db,
+    string providerid, string setup_appid) {
 
   static const char query[] =
     "INSERT INTO provider_setup_appid "
     "(provider_id, setup_appid) "
     "VALUES (?, ?)";
 
-  ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
-  if (ret != SQLITE_OK) {
-    LOGE("prepare error: %d(%s)", ret, sqlite3_errmsg(db));
-    goto out;
-  }
+  if (!db->Prepare(query))
+    return false;
 
-  ret = sqlite3_bind_text(stmt, 1, providerid, -1, SQLITE_TRANSIENT);
-  if (ret != SQLITE_OK) {
-    LOGE("sqlite3_bind_text() error: %d(%s)", ret, sqlite3_errmsg(db));
-    goto out;
-  }
-  ret = sqlite3_bind_text(stmt, 2, setup_appid, -1, SQLITE_TRANSIENT);
-  if (ret != SQLITE_OK) {
-    LOGE("sqlite3_bind_text() error: %d(%s)", ret, sqlite3_errmsg(db));
-    goto out;
-  }
+  if (!db->Bind(1, providerid))
+    return false;
 
-  ret = sqlite3_step(stmt);
-  if (ret != SQLITE_DONE) {
-    LOGE("step error: %s", sqlite3_errmsg(db));
-    goto out;
-  }
+  if (!db->Bind(2, setup_appid))
+    return false;
+
+  if (db->Step() != SQLITE_DONE)
+    return false;
+
+  if (db->Reset() != SQLITE_OK)
+    return false;
+
+  return true;
+}
+
+static bool _insert_complication(shared_ptr<util::DBHelper>& db,
+    string pkgid, string appid, string providerid, bool trusted, int period) {
+  static const char query[] =
+    "INSERT INTO complication_provider ( "
+    "pkgid, appid, provider_id, trusted, period) "
+    "VALUES (?, ?, ?, ?, ?)";
+
+  if (!db->Prepare(query))
+    return false;
+
+  if (!db->Bind(1, pkgid))
+    return false;
+
+  if (!db->Bind(2, appid))
+    return false;
+
+  if (!db->Bind(3, providerid))
+    return false;
+
+  if (!db->Bind(4, trusted))
+    return false;
 
-  ret = 0;
-out:
-  if (stmt)
-    sqlite3_finalize(stmt);
+  if (!db->Bind(5, period))
+    return false;
 
-  return ret;
+  if (db->Step() != SQLITE_DONE)
+    return false;
+
+  if (db->Reset() != SQLITE_OK)
+    return false;
+  return true;
 }
 
-static int _parse_complication(xmlNode* node, sqlite3* db, const char* pkgid,
-      const char* appid, const char* providerid, const char* setup_appid, bool trusted) {
+static bool _parse_complication(xmlNode* node, shared_ptr<util::DBHelper>& db,
+      string pkgid, string appid, string providerid, string setup_appid, bool trusted) {
   int period = -1;
 
-  xmlNode* tmp = NULL;
-  xmlNode* support_type_node = NULL;
+  xmlNode* tmp = nullptr;
+  xmlNode* support_type_node = nullptr;
+  xmlNode* privilege_node = nullptr;
+  xmlNode* support_event_node = nullptr;
+  list<xmlNode*> label_list;
 
   if (node->children == NULL)
-    return -1;
+    return false;
 
   for (tmp = node->children; tmp; tmp = tmp->next) {
     if (!xmlStrcasecmp(tmp->name, (const xmlChar*)"support-type")) {
       if (tmp->children == NULL)
-        return -1;
+        return false;
 
       support_type_node = tmp;
     } else if (!xmlStrcasecmp(tmp->name, (const xmlChar*)"period")) {
       if (tmp->children == NULL
         || tmp->children->content == NULL)
-        return -1;
+        return false;
 
       period = atoi(reinterpret_cast<char*>(tmp->children->content));
       if (period < 60)
         period = 60;
     } else if (!xmlStrcasecmp(tmp->name, (const xmlChar*)"label")) {
-      if (_parse_label(tmp, db, providerid)) {
-        LOGE("parse label fail");
-        return -1;
-      }
+      label_list.push_back(tmp);
     } else if (!xmlStrcasecmp(tmp->name, (const xmlChar*)"privileges")) {
-      if (_parse_privilege(tmp, db, providerid)) {
-        LOGE("parse privilege fail");
-        return -1;
-      }
+      privilege_node = tmp;
     } else if (!xmlStrcasecmp(tmp->name, (const xmlChar*)"support-event")) {
-      if (_parse_support_event(tmp, db, providerid)) {
-        LOGE("parse support event fail");
-        return -1;
-      }
+      support_event_node = tmp;
     }
   }
 
-  if (!support_type_node) {
+  if (!_insert_complication(db, pkgid, appid, providerid, trusted, period)) {
     LOGE("complication provider doesn't have support-type");
-    return -1;
+    return false;
   }
 
-  if (setup_appid) {
-    if (_parse_setup_appid(db, providerid, setup_appid)) {
-      LOGE("parse setup appid fail");
-      return -1;
-    }
+  if (!support_type_node) {
+    LOGE("complication provider doesn't have support-type");
+    return false;
   }
 
-  if (_parse_support_type(support_type_node, db, pkgid,
-      appid, providerid, period, trusted)) {
+  if (!_parse_support_type(support_type_node, db, providerid)) {
     LOGE("parse support type fail");
-    return -1;
+    return false;
   }
 
-  return 0;
-}
-
-static int _parse_service_application(xmlNode* node, const char* pkgid) {
-  int result = -1;
-  char* appid;
-  char* providerid;
-  char* setup_appid;
-  char* trusted_str;
-  bool trusted;
-  xmlNode* tmp;
-  sqlite3* db;
-
-  appid = _get_attribute(node, "appid");
-  if (appid == NULL)
-    return -1;
-
-  db = open_db(_get_target_uid());
-  if (db == NULL) {
-    LOGE("failed to open db");
-    goto out;
+  if (privilege_node != nullptr &&
+      !_parse_privilege(privilege_node, db, providerid)) {
+    LOGE("parse privilege fail");
+    return false;
   }
 
-  if (sqlite3_exec(db, "BEGIN TRANSACTION", NULL, NULL, NULL)) {
-    LOGE("begin transaction error");
-    goto out;
+  if (support_event_node != nullptr &&
+      !_parse_support_event(support_event_node, db, providerid)) {
+    LOGE("parse support event fail");
+    return false;
   }
 
-  for (tmp = node->children; tmp; tmp = tmp->next) {
-    if (!xmlStrcasecmp(tmp->name, (const xmlChar*)"complication")) {
-      providerid = _get_attribute(tmp, "provider-id");
-      if (providerid == NULL) {
-        LOGE("provider-id error");
-
-        if (sqlite3_exec(db, "ROLLBACK TRANSACTION", NULL, NULL, NULL))
-          LOGE("rollback transaction error");
-
-        goto out;
-      }
+  for (auto& i : label_list) {
+    if (!_parse_label(i, db, providerid)) {
+      LOGE("parse label fail");
+      return false;
+    }
+  }
 
-      setup_appid = _get_attribute(tmp, "setup-appid");
-      trusted_str = _get_attribute(tmp, "trusted");
-      if (trusted_str != NULL && strcasecmp(trusted_str, "true") == 0)
-        trusted = true;
-      else
-        trusted = false;
+  if (!setup_appid.empty()) {
+    if (!_insert_setup_appid(db, providerid, setup_appid)) {
+      LOGE("insert setup appid fail");
+      return false;
+    }
+  }
 
-      if (_parse_complication(tmp, db, pkgid, appid, providerid, setup_appid,
-          trusted)) {
-        LOGE("parse complication error");
+  return true;
+}
 
-        if (sqlite3_exec(db, "ROLLBACK TRANSACTION", NULL, NULL, NULL))
-          LOGE("rollback transaction error");
+static bool _parse_service_application(xmlNode* node, const char* pkgid) {
+  bool trusted;
+  xmlNode* tmp;
+  shared_ptr<util::DBHelper> db = make_shared<util::DBHelper>();
 
-        free(providerid);
+  string appid = _get_attribute(node, "appid");
+  if (appid.empty())
+    return false;
 
-        if (setup_appid)
-          free(setup_appid);
-        if (trusted_str)
-          free(trusted_str);
+  if (!db->Open(SQLITE_OPEN_READWRITE))
+    return false;
 
-        goto out;
-      }
+  if (!db->Exec("BEGIN TRANSACTION"))
+    return false;
 
-      free(providerid);
+  for (tmp = node->children; tmp; tmp = tmp->next) {
+    if (xmlStrcasecmp(tmp->name, (const xmlChar*)"complication"))
+      continue;
 
-      if (setup_appid)
-        free(setup_appid);
-      if (trusted_str)
-        free(trusted_str);
+    string providerid = _get_attribute(tmp, "provider-id");
+    if (providerid.empty()) {
+      LOGE("provider-id error");
+      if (!db->Exec("ROLLBACK TRANSACTION"))
+        return false;
     }
-  }
 
-  if (sqlite3_exec(db, "END TRANSACTION", NULL, NULL, NULL)) {
-    LOGE("end transaction error");
-    goto out;
+    string setup_appid = _get_attribute(tmp, "setup-appid");
+    string trusted_str = _get_attribute(tmp, "trusted");
+    if (!trusted_str.empty() && strcasecmp(trusted_str.c_str(), "true") == 0)
+      trusted = true;
+    else
+      trusted = false;
+
+    if (!_parse_complication(tmp, db, pkgid, appid, providerid, setup_appid,
+        trusted)) {
+      LOGE("parse complication error");
+      if (!db->Exec("ROLLBACK TRANSACTION"))
+        return false;
+    }
   }
 
-  result = 0;
-out:
-  if (db)
-    sqlite3_close_v2(db);
-
-  if (appid)
-    free(appid);
+  if (!db->Exec("END TRANSACTION"))
+    return false;
 
-  return result;
+  return true;
 }
 
 int complication_parser_plugin_parse_manifest(xmlDocPtr doc,
@@ -877,7 +738,7 @@ int complication_parser_plugin_parse_manifest(xmlDocPtr doc,
     if (xmlStrcasecmp(tmp->name, (const xmlChar*)"service-application"))
       continue;
 
-    if (_parse_service_application(tmp, pkgid)) {
+    if (!_parse_service_application(tmp, pkgid)) {
       LOGE("parse failed");
       return -1;
     }
@@ -886,93 +747,30 @@ int complication_parser_plugin_parse_manifest(xmlDocPtr doc,
   return 0;
 }
 
-static int _remove_complication(sqlite3* db, const char* pkgid) {
-  int ret;
-  unsigned int i;
-  sqlite3_stmt* stmt = NULL;
-
-  static const char* query[] = {
-    "DELETE FROM provider_privilege WHERE provider_id IN "
-    "(SELECT DISTINCT provider_id FROM complication_provider "
-    "WHERE pkgid=?)",
-    "DELETE FROM provider_localized_info WHERE provider_id IN "
-    "(SELECT DISTINCT provider_id FROM complication_provider "
-    "WHERE pkgid=?)",
-    "DELETE FROM provider_setup_appid WHERE provider_id IN "
-    "(SELECT DISTINCT provider_id FROM complication_provider "
-    "WHERE pkgid=?)",
-    "DELETE FROM provider_support_events WHERE provider_id IN "
-    "(SELECT DISTINCT provider_id FROM complication_provider "
-    "WHERE pkgid=?)",
-    "DELETE FROM complication_provider WHERE pkgid=?"
-  };
-
-  for (i = 0; i < (sizeof(query) / sizeof(*query)); i++) {
-    ret = sqlite3_prepare_v2(db, query[i], strlen(query[i]), &stmt, NULL);
-    if (ret != SQLITE_OK) {
-      LOGE("prepare error: %d(%s)", ret, sqlite3_errmsg(db));
-      goto out;
-    }
-
-    ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT);
-    if (ret != SQLITE_OK) {
-      LOGE("sqlite3_bind_text() error: %d(%s)", ret, sqlite3_errmsg(db));
-      goto out;
-    }
-
-    ret = sqlite3_step(stmt);
-    if (ret != SQLITE_DONE) {
-      LOGE("step error: %s", sqlite3_errmsg(db));
-      goto out;
-    }
-
-    sqlite3_finalize(stmt);
-    stmt = NULL;
-  }
-
-  ret = 0;
-
-out:
-  if (stmt)
-    sqlite3_finalize(stmt);
-
-  return ret;
-}
-
 int complication_parser_db_remove_complication(const char* pkgid) {
-  int ret;
-  sqlite3* db;
+  util::DBHelper db;
+  if (!db.Open(SQLITE_OPEN_READWRITE))
+    return -1;
 
-  db = open_db(_get_target_uid());
-  if (db == NULL)
+  if (!db.Exec("BEGIN TRANSACTION"))
     return -1;
 
-  ret = sqlite3_exec(db, "BEGIN TRANSACTION", NULL, NULL, NULL);
-  if (ret != SQLITE_OK) {
-    LOGE("begin transaction error %d", ret);
-    goto out;
+  if (!db.Prepare("DELETE FROM complication_provider WHERE pkgid=?")) {
+    if (!db.Exec("ROLLBACK TRANSACTION"))
+      return -1;
   }
 
-  if (_remove_complication(db, pkgid)) {
-    LOGE("failed to remove complication provider");
-
-    ret = sqlite3_exec(db, "ROLLBACK TRANSACTION", NULL, NULL, NULL);
-    if (ret != SQLITE_OK) {
-      LOGE("rollback transaction error %d", ret);
-    }
-    goto out;
+  if (!db.Bind(1, pkgid)) {
+    if (!db.Exec("ROLLBACK TRANSACTION"))
+      return -1;
   }
 
-  ret = sqlite3_exec(db, "END TRANSACTION", NULL, NULL, NULL);
-  if (ret != SQLITE_OK) {
-    LOGE("begin transaction error %d", ret);
-    goto out;
+  if (db.Step() != SQLITE_DONE) {
+    if (!db.Exec("ROLLBACK TRANSACTION"))
+      return -1;
   }
 
-  ret = 0;
-out:
-  if (db)
-    sqlite3_close_v2(db);
-
-  return ret;
+  if (!db.Exec("END TRANSACTION"))
+    return -1;
+  return 0;
 }
index 929f188..3028fc1 100644 (file)
@@ -23,6 +23,7 @@
 #include <dlog.h>
 #include <tzplatform_config.h>
 
+#include "watchface-common/watchface-util.h"
 #include "parser/complication_parser_plugin_internal.h"
 
 #define BUSY_WAITING_USEC 50000 /* 0.05 sec */
@@ -41,40 +42,48 @@ CREATE TABLE IF NOT EXISTS complication_provider ( \
   provider_id  TEXT NOT NULL, \
   trusted      INTEGER DEFAULT 0, \
   period       INTEGER DEFAULT -1, \
+  PRIMARY KEY (provider_id) \
+); \
+CREATE TABLE IF NOT EXISTS provider_support_types ( \
+  provider_id  TEXT NOT NULL, \
   support_type INTEGER DEFAULT 0, \
   default_data TEXT NOT NULL, \
-  PRIMARY KEY (provider_id, support_type) \
+  UNIQUE (provider_id, support_type), \
+  FOREIGN KEY (provider_id) REFERENCES complication_provider(provider_id) ON DELETE CASCADE \
 ); \
 CREATE TABLE IF NOT EXISTS provider_localized_info ( \
   provider_id    TEXT NOT NULL, \
   locale         TEXT NOT NULL DEFAULT 'No Locale', \
   provider_label TEXT, \
-  PRIMARY KEY (provider_id, locale) \
+  UNIQUE (provider_id, locale), \
+  FOREIGN KEY (provider_id) REFERENCES complication_provider(provider_id) ON DELETE CASCADE \
 ); \
 CREATE TABLE IF NOT EXISTS provider_privilege ( \
   provider_id  TEXT NOT NULL, \
   privilege    TEXT NOT NULL, \
-  PRIMARY KEY (provider_id, privilege) \
+  UNIQUE (provider_id, privilege) \
+  FOREIGN KEY (provider_id) REFERENCES complication_provider(provider_id) ON DELETE CASCADE \
 ); \
 CREATE TABLE IF NOT EXISTS provider_setup_appid ( \
   provider_id  TEXT NOT NULL, \
   setup_appid  TEXT, \
-  PRIMARY KEY (provider_id) \
+  FOREIGN KEY (provider_id) REFERENCES complication_provider(provider_id) ON DELETE CASCADE \
 ); \
 CREATE TABLE IF NOT EXISTS provider_support_events ( \
   provider_id  TEXT NOT NULL, \
   support_events  INTEGER DEFAULT 1, \
-  PRIMARY KEY (provider_id) \
+  FOREIGN KEY (provider_id) REFERENCES complication_provider(provider_id) ON DELETE CASCADE \
 ); \
 COMMIT TRANSACTION; "
 
-#define COMPLICATION_TBL_COUNT 5
+#define COMPLICATION_TBL_COUNT 6
 static const char* _complication_table_list[COMPLICATION_TBL_COUNT] = {
   "complication_provider",
   "provider_localized_info",
   "provider_privilege",
   "provider_setup_appid",
-  "provider_support_events"
+  "provider_support_events",
+  "provider_support_types"
 };
 
 static int _is_global(uid_t uid) {
@@ -123,8 +132,12 @@ static int _check_table_exist(sqlite3* db) {
     return -1;
   }
 
-  while (sqlite3_step(stmt) == SQLITE_ROW
-    && idx < COMPLICATION_TBL_COUNT) {
+  while (idx < COMPLICATION_TBL_COUNT) {
+    ret = sqlite3_step(stmt);
+    if (ret != SQLITE_ROW) {
+      LOGW("fail to get row");
+      break;
+    }
     val = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0));
     if (val == nullptr) {
       LOGW("name is nullptr");
@@ -136,11 +149,10 @@ static int _check_table_exist(sqlite3* db) {
 
     idx++;
   }
-
   sqlite3_finalize(stmt);
 
   if (idx != COMPLICATION_TBL_COUNT) {
-    LOGE("table count not matched");
+    LOGE("table count not matched, %d, %d", idx, COMPLICATION_TBL_COUNT);
     return -1;
   }
 
index 652ae8e..585b787 100644 (file)
@@ -24,9 +24,16 @@ CREATE TABLE IF NOT EXISTS complication_provider (
   provider_id  TEXT NOT NULL,
   trusted      INTEGER DEFAULT 0,
   period       INTEGER DEFAULT -1,
+  PRIMARY KEY (provider_id)
+);
+
+DROP TABLE IF EXISTS provider_support_types;
+CREATE TABLE IF NOT EXISTS provider_support_types (
+  provider_id  TEXT NOT NULL,
   support_type INTEGER DEFAULT 0,
   default_data TEXT NOT NULL,
-  PRIMARY KEY (provider_id, support_type)
+  UNIQUE (provider_id, support_type),
+  FOREIGN KEY (provider_id) REFERENCES complication_provider(provider_id) ON DELETE CASCADE
 );
 
 DROP TABLE IF EXISTS provider_localized_info;
@@ -34,28 +41,30 @@ CREATE TABLE IF NOT EXISTS provider_localized_info (
   provider_id    TEXT NOT NULL,
   locale         TEXT NOT NULL DEFAULT 'No Locale',
   provider_label TEXT,
-  PRIMARY KEY (provider_id, locale)
+  UNIQUE (provider_id, locale),
+  FOREIGN KEY (provider_id) REFERENCES complication_provider(provider_id) ON DELETE CASCADE
 );
 
 DROP TABLE IF EXISTS provider_privilege;
 CREATE TABLE IF NOT EXISTS provider_privilege (
   provider_id  TEXT NOT NULL,
   privilege    TEXT NOT NULL,
-  PRIMARY KEY (provider_id, privilege)
+  UNIQUE (provider_id, privilege)
+  FOREIGN KEY (provider_id) REFERENCES complication_provider(provider_id) ON DELETE CASCADE
 );
 
 DROP TABLE IF EXISTS provider_setup_appid;
 CREATE TABLE IF NOT EXISTS provider_setup_appid (
   provider_id  TEXT NOT NULL,
   setup_appid  TEXT,
-  PRIMARY KEY (provider_id)
+  FOREIGN KEY (provider_id) REFERENCES complication_provider(provider_id) ON DELETE CASCADE
 );
 
 DROP TABLE IF EXISTS provider_support_events;
 CREATE TABLE IF NOT EXISTS provider_support_events (
   provider_id  TEXT NOT NULL,
   support_events  INTEGER DEFAULT 1,
-  PRIMARY KEY (provider_id)
+  FOREIGN KEY (provider_id) REFERENCES complication_provider(provider_id) ON DELETE CASCADE
 );
 COMMIT TRANSACTION;
 
index 03ea2dc..2ec263f 100644 (file)
@@ -4,172 +4,136 @@ CREATE TABLE IF NOT EXISTS complication_provider (
   provider_id  TEXT NOT NULL,
   trusted      INTEGER DEFAULT 0,
   period       INTEGER DEFAULT -1,
+  PRIMARY KEY (provider_id)
+);
+CREATE TABLE IF NOT EXISTS provider_support_types (
+  provider_id  TEXT NOT NULL,
   support_type INTEGER DEFAULT 0,
   default_data TEXT NOT NULL,
-  PRIMARY KEY (provider_id, support_type)
+  FOREIGN KEY (provider_id) REFERENCES complication_provider(provider_id) ON DELETE CASCADE
 );
 CREATE TABLE IF NOT EXISTS provider_localized_info (
   provider_id    TEXT NOT NULL,
   locale         TEXT NOT NULL DEFAULT 'No Locale',
   provider_label TEXT,
-  PRIMARY KEY (provider_id, locale)
+  UNIQUE (provider_id, locale),
+  FOREIGN KEY (provider_id) REFERENCES complication_provider(provider_id) ON DELETE CASCADE
 );
 CREATE TABLE IF NOT EXISTS provider_privilege (
   provider_id  TEXT NOT NULL,
   privilege    TEXT NOT NULL,
-  PRIMARY KEY (provider_id, privilege)
+  UNIQUE (provider_id, privilege)
+  FOREIGN KEY (provider_id) REFERENCES complication_provider(provider_id) ON DELETE CASCADE
 );
 CREATE TABLE IF NOT EXISTS provider_setup_appid (
   provider_id  TEXT NOT NULL,
   setup_appid  TEXT,
-  PRIMARY KEY (provider_id)
+  FOREIGN KEY (provider_id) REFERENCES complication_provider(provider_id) ON DELETE CASCADE
 );
 CREATE TABLE IF NOT EXISTS provider_support_events (
   provider_id  TEXT NOT NULL,
   support_events  INTEGER DEFAULT 1,
-  PRIMARY KEY (provider_id)
+  FOREIGN KEY (provider_id) REFERENCES complication_provider(provider_id) ON DELETE CASCADE
 );
 
 INSERT INTO complication_provider (
-  pkgid, appid, provider_id, trusted, period,
-  support_type, default_data) VALUES (
+  pkgid, appid, provider_id, trusted, period) VALUES (
   'org.tizen.gmock_comp_provider',
   'org.tizen.gmock_comp_provider',
   'org.tizen.gmock_comp_provider/test',
   0,
-  1,
+  1
+);
+
+INSERT INTO provider_support_types (
+  provider_id, support_type, default_data) VALUES (
+  'org.tizen.gmock_comp_provider/test',
   2,
   'test'
 );
 
-INSERT INTO complication_provider (
-  pkgid, appid, provider_id, trusted, period,
-  support_type, default_data) VALUES (
-  'org.tizen.gmock_comp_provider',
-  'org.tizen.gmock_comp_provider',
+INSERT INTO provider_support_types (
+  provider_id, support_type, default_data) VALUES (
   'org.tizen.gmock_comp_provider/test',
-  0,
-  1,
   4,
   'test'
 );
 
-INSERT INTO complication_provider (
-  pkgid, appid, provider_id, trusted, period,
-  support_type, default_data) VALUES (
-  'org.tizen.gmock_comp_provider',
-  'org.tizen.gmock_comp_provider',
+INSERT INTO provider_support_types (
+  provider_id, support_type, default_data) VALUES (
   'org.tizen.gmock_comp_provider/test',
-  0,
-  1,
   8,
   'test'
 );
 
-INSERT INTO complication_provider (
-  pkgid, appid, provider_id, trusted, period,
-  support_type, default_data) VALUES (
-  'org.tizen.gmock_comp_provider',
-  'org.tizen.gmock_comp_provider',
+INSERT INTO provider_support_types (
+  provider_id, support_type, default_data) VALUES (
   'org.tizen.gmock_comp_provider/test',
-  0,
-  1,
   16,
   'test'
 );
 
-INSERT INTO complication_provider (
-  pkgid, appid, provider_id, trusted, period,
-  support_type, default_data) VALUES (
-  'org.tizen.gmock_comp_provider',
-  'org.tizen.gmock_comp_provider',
+INSERT INTO provider_support_types (
+  provider_id, support_type, default_data) VALUES (
   'org.tizen.gmock_comp_provider/test',
-  0,
-  1,
   32,
   'test'
 );
 
-INSERT INTO complication_provider (
-  pkgid, appid, provider_id, trusted, period,
-  support_type, default_data) VALUES (
-  'org.tizen.gmock_comp_provider',
-  'org.tizen.gmock_comp_provider',
+INSERT INTO provider_support_types (
+  provider_id, support_type, default_data) VALUES (
   'org.tizen.gmock_comp_provider/test',
-  0,
-  1,
   64,
   'test'
 );
 
 INSERT INTO complication_provider (
-  pkgid, appid, provider_id, trusted, period,
-  support_type, default_data) VALUES (
+  pkgid, appid, provider_id, trusted, period) VALUES (
   'org.tizen.gmock_comp_provider2',
   'org.tizen.gmock_comp_provider2',
   'org.tizen.gmock_comp_provider2/test',
   0,
-  1,
+  1
+);
+
+INSERT INTO provider_support_types (
+  provider_id, support_type, default_data) VALUES (
+  'org.tizen.gmock_comp_provider2/test',
   2,
   'test'
 );
 
-INSERT INTO complication_provider (
-  pkgid, appid, provider_id, trusted, period,
-  support_type, default_data) VALUES (
-  'org.tizen.gmock_comp_provider2',
-  'org.tizen.gmock_comp_provider2',
+INSERT INTO provider_support_types (
+  provider_id, support_type, default_data) VALUES (
   'org.tizen.gmock_comp_provider2/test',
-  0,
-  1,
   4,
   'test'
 );
 
-INSERT INTO complication_provider (
-  pkgid, appid, provider_id, trusted, period,
-  support_type, default_data) VALUES (
-  'org.tizen.gmock_comp_provider2',
-  'org.tizen.gmock_comp_provider2',
+INSERT INTO provider_support_types (
+  provider_id, support_type, default_data) VALUES (
   'org.tizen.gmock_comp_provider2/test',
-  0,
-  1,
   8,
   'test'
 );
 
-INSERT INTO complication_provider (
-  pkgid, appid, provider_id, trusted, period,
-  support_type, default_data) VALUES (
-  'org.tizen.gmock_comp_provider2',
-  'org.tizen.gmock_comp_provider2',
+INSERT INTO provider_support_types (
+  provider_id, support_type, default_data) VALUES (
   'org.tizen.gmock_comp_provider2/test',
-  0,
-  1,
   16,
   'test'
 );
 
-INSERT INTO complication_provider (
-  pkgid, appid, provider_id, trusted, period,
-  support_type, default_data) VALUES (
-  'org.tizen.gmock_comp_provider2',
-  'org.tizen.gmock_comp_provider2',
+INSERT INTO provider_support_types (
+  provider_id, support_type, default_data) VALUES (
   'org.tizen.gmock_comp_provider2/test',
-  0,
-  1,
   32,
   'test'
 );
 
-INSERT INTO complication_provider (
-  pkgid, appid, provider_id, trusted, period,
-  support_type, default_data) VALUES (
-  'org.tizen.gmock_comp_provider2',
-  'org.tizen.gmock_comp_provider2',
+INSERT INTO provider_support_types (
+  provider_id, support_type, default_data) VALUES (
   'org.tizen.gmock_comp_provider2/test',
-  0,
-  1,
   64,
   'test'
 );
@@ -181,85 +145,68 @@ INSERT INTO provider_setup_appid (
 );
 
 INSERT INTO complication_provider (
-  pkgid, appid, provider_id, trusted, period,
-  support_type, default_data) VALUES (
+  pkgid, appid, provider_id, trusted, period) VALUES (
   'org.tizen.gmock_comp_provider3',
   'org.tizen.gmock_comp_provider3',
   'org.tizen.gmock_comp_provider3/test',
   0,
-  1,
+  1
+);
+
+INSERT INTO provider_support_types (
+  provider_id, support_type, default_data) VALUES (
+  'org.tizen.gmock_comp_provider3/test',
   2,
   'test'
 );
 
-INSERT INTO complication_provider (
-  pkgid, appid, provider_id, trusted, period,
-  support_type, default_data) VALUES (
-  'org.tizen.gmock_comp_provider3',
-  'org.tizen.gmock_comp_provider3',
+INSERT INTO provider_support_types (
+  provider_id, support_type, default_data) VALUES (
   'org.tizen.gmock_comp_provider3/test',
-  0,
-  1,
   4,
   'test'
 );
 
-INSERT INTO complication_provider (
-  pkgid, appid, provider_id, trusted, period,
-  support_type, default_data) VALUES (
-  'org.tizen.gmock_comp_provider3',
-  'org.tizen.gmock_comp_provider3',
+INSERT INTO provider_support_types (
+  provider_id, support_type, default_data) VALUES (
   'org.tizen.gmock_comp_provider3/test',
-  0,
-  1,
   8,
   'test'
 );
 
-INSERT INTO complication_provider (
-  pkgid, appid, provider_id, trusted, period,
-  support_type, default_data) VALUES (
-  'org.tizen.gmock_comp_provider3',
-  'org.tizen.gmock_comp_provider3',
+INSERT INTO provider_support_types (
+  provider_id, support_type, default_data) VALUES (
   'org.tizen.gmock_comp_provider3/test',
-  0,
-  1,
   16,
   'test'
 );
 
-INSERT INTO complication_provider (
-  pkgid, appid, provider_id, trusted, period,
-  support_type, default_data) VALUES (
-  'org.tizen.gmock_comp_provider3',
-  'org.tizen.gmock_comp_provider3',
+INSERT INTO provider_support_types (
+  provider_id, support_type, default_data) VALUES (
   'org.tizen.gmock_comp_provider3/test',
-  0,
-  1,
   32,
   'test'
 );
 
-INSERT INTO complication_provider (
-  pkgid, appid, provider_id, trusted, period,
-  support_type, default_data) VALUES (
-  'org.tizen.gmock_comp_provider3',
-  'org.tizen.gmock_comp_provider3',
+INSERT INTO provider_support_types (
+  provider_id, support_type, default_data) VALUES (
   'org.tizen.gmock_comp_provider3/test',
-  0,
-  1,
   64,
   'test'
 );
 
 INSERT INTO complication_provider (
-  pkgid, appid, provider_id, trusted, period,
-  support_type, default_data) VALUES (
+  pkgid, appid, provider_id, trusted, period) VALUES (
   'org.tizen.gmock_comp_provider4',
   'org.tizen.gmock_comp_provider4',
   'org.tizen.gmock_comp_provider4/test',
   0,
-  1,
+  1
+);
+
+INSERT INTO provider_support_types (
+  provider_id, support_type, default_data) VALUES (
+  'org.tizen.gmock_comp_provider4/test',
   2,
   'test'
 );
@@ -271,13 +218,17 @@ INSERT INTO provider_privilege (
 );
 
 INSERT INTO complication_provider (
-  pkgid, appid, provider_id, trusted, period,
-  support_type, default_data) VALUES (
+  pkgid, appid, provider_id, trusted, period) VALUES (
   'org.tizen.gmock_comp_provider5',
   'org.tizen.gmock_comp_provider5',
   'org.tizen.gmock_comp_provider5/test',
   1,
-  1,
+  1
+);
+
+INSERT INTO provider_support_types (
+  provider_id, support_type, default_data) VALUES (
+  'org.tizen.gmock_comp_provider5/test',
   2,
   'test'
 );
\ No newline at end of file
index 0f3c62f..d4aedfa 100644 (file)
@@ -33,7 +33,7 @@ void UpdateDB() {
   }
 
   static const char query[] =
-    "UPDATE complication_provider "
+    "UPDATE provider_support_types "
     "SET default_data = ?";
 
   sqlite3_stmt* stmt = nullptr;
index 18c134a..1816ca7 100644 (file)
@@ -24,6 +24,7 @@
 #include <cynara-creds-gdbus.h>
 #include <cynara-session.h>
 #include <pkgmgr-info.h>
+#include <pkgmgr_installer_info.h>
 #include <system_info.h>
 
 #include <string>
@@ -45,6 +46,7 @@
 #define EDITABLE_PATH_PREFIX "/org/tizen/watchface_editable_"
 #define COMPLICATION_OBJECT_PATH "/org/tizen/watchface_complication"
 #define MAX_CACHE_COUNT 10
+#define ROOT_USER 0
 
 #define LOG_TAG "WATCHFACE_COMPLICATION"
 
@@ -518,5 +520,130 @@ out:
     free(info_s);
   }
 
+  const char* DBHelper::GetParserDataPath() const {
+    uid_t target_uid;
+    const char* path;
+    bool is_global;
+
+    pkgmgr_installer_info_get_target_uid(&target_uid);
+
+    if (target_uid == ROOT_USER
+      || target_uid == tzplatform_getuid(TZ_SYS_GLOBALAPP_USER))
+      is_global = true;
+    else
+      is_global = false;
+
+    if (!is_global)
+        tzplatform_set_user(target_uid);
+
+    path = tzplatform_mkpath(is_global ? TZ_SYS_DB : TZ_USER_DB,
+        ".complication_provider.db");
+    tzplatform_reset_user();
+
+    return path;
+  }
+
+  bool DBHelper::Open() {
+    const char* path = GetParserDataPath();
+    if (path == nullptr)
+      return false;
+
+    sqlite3* db = nullptr;
+    int ret = sqlite3_open_v2(path, &db, SQLITE_OPEN_READONLY, nullptr);
+    if (ret != SQLITE_OK) {
+      LOGE("open db(%s) error: %d", path, ret);
+      return false;
+    }
+    db_.reset(db);
+    Exec("PRAGMA foreign_keys = ON");
+
+    return true;
+  }
+
+  bool DBHelper::Open(int mode) {
+    const char* path = GetParserDataPath();
+    if (path == nullptr)
+      return false;
+
+    sqlite3* db = nullptr;
+    int ret = sqlite3_open_v2(path, &db, mode, nullptr);
+    if (ret != SQLITE_OK) {
+      LOGE("open db(%s) error: %d", path, ret);
+      return false;
+    }
+    db_.reset(db);
+    Exec("PRAGMA foreign_keys = ON");
+
+    return true;
+  }
+
+  void DBHelper::Close() {
+    db_.reset();
+  }
+
+  bool DBHelper::Exec(const std::string& query) {
+    if (sqlite3_exec(db_.get(), query.c_str(), NULL, NULL, NULL) != SQLITE_OK) {
+      LOGE("exec error %s", sqlite3_errmsg(db_.get()));
+      return false;
+    }
+    return true;
+  }
+
+  bool DBHelper::Prepare(const std::string& query) {
+    sqlite3_stmt* stmt = nullptr;
+    if (sqlite3_prepare_v2(db_.get(), query.c_str(), query.size(), &stmt,
+        nullptr) != SQLITE_OK) {
+      LOGE("prepare error: %s", sqlite3_errmsg(db_.get()));
+      return false;
+    }
+
+    stmt_.reset(stmt);
+
+    return true;
+  }
+
+  const DBHelper::Cursor& DBHelper::GetCursor() const {
+    return stmt_;
+  }
+
+  int DBHelper::Step() const {
+    int ret = sqlite3_step(stmt_.get());
+    if (ret != SQLITE_DONE || ret != SQLITE_ROW)
+      LOGE("step error: %s", sqlite3_errmsg(db_.get()));
+    return ret;
+  }
+
+  int DBHelper::Reset() const {
+    return sqlite3_reset(stmt_.get());
+  }
+
+  bool DBHelper::Bind(int pos, std::string text) {
+    int ret = sqlite3_bind_text(stmt_.get(), pos, text.c_str(),
+      -1, SQLITE_TRANSIENT);
+    if (ret != SQLITE_OK) {
+      LOGE("bind error: %s", sqlite3_errmsg(db_.get()));
+      return false;
+    }
+
+    return true;
+  }
+
+  bool DBHelper::Bind(int pos, int val) {
+    if (sqlite3_bind_int(stmt_.get(), pos, val) != SQLITE_OK) {
+      LOGE("bind error: %s", sqlite3_errmsg(db_.get()));
+      return false;
+    }
+
+    return true;
+  }
+
+  const char* DBHelper::GetText(int pos) const {
+    return reinterpret_cast<const char*>(sqlite3_column_text(stmt_.get(), pos));
+  }
+
+  int DBHelper::GetInt(int pos) const {
+    return sqlite3_column_int(stmt_.get(), pos);
+  }
+
 }  // namespace util
 }  // namespace watchface_complication
index 0578ec2..b26b714 100644 (file)
@@ -20,6 +20,8 @@
 #include <gio/gio.h>
 #include <bundle.h>
 #include <bundle_cpp.h>
+#include <sqlite3.h>
+#include <tzplatform_config.h>
 
 #include <string>
 #include "watchface-common/include/watchface-common.h"
@@ -79,6 +81,35 @@ namespace util {
   EXPORT_API int GetDataType(tizen_base::Bundle shared_data);
   EXPORT_API int ConvertAulError(int ret);
   EXPORT_API void DestroyTimeInfo(struct complication_time_info_s* info);
+
+  class EXPORT_API DBHelper {
+    public:
+      using Cursor = std::unique_ptr<sqlite3_stmt, decltype(sqlite3_finalize)*>;
+      DBHelper()
+          : db_(nullptr, sqlite3_close_v2), stmt_(nullptr, sqlite3_finalize) {}
+
+      bool Open();
+      bool Open(int mode);
+      void Close();
+      bool Prepare(const std::string& query);
+      bool Exec(const std::string& query);
+      const Cursor& GetCursor() const;
+      int Step() const;
+      int Reset() const;
+
+      bool Bind(int pos, std::string text);
+      bool Bind(int pos, int val);
+
+      const char* GetText(int pos) const;
+      int GetInt(int pos) const;
+
+    private:
+      const char* GetParserDataPath() const;
+
+    private:
+      std::unique_ptr<sqlite3, decltype(sqlite3_close_v2)*> db_;
+      Cursor stmt_;
+  };
 }  // namespace util
 }  // namespace watchface_complication
 
index f884bd3..888c1f6 100644 (file)
 #include "watchface-complication-provider/complication-provider-implementation.h"
 #include "watchface-complication-provider/include/watchface-complication-provider.h"
 
-#ifdef LOGE
-#undef LOGE
-#endif
-#define LOGE printf
-
 #ifdef LOG_TAG
 #undef LOG_TAG
 #endif
 
 #define LOG_TAG "WATCHFACE_COMPLICATION"
-#define PRIVILEGE_DATASHARING "http://tizen.org/privilege/datasharing"
 
 using namespace std;
 using namespace tizen_base;
index d3f56b7..4069f2e 100644 (file)
 #endif
 
 #define LOG_TAG "WATCHFACE_COMPLICATION"
-
 #define DEFAULT_LOCALE "No Locale"
-#define ROOT_USER 0
 
 using namespace tizen_base;
-
-namespace {
-class DBHelper {
- public:
-  using Cursor = std::unique_ptr<sqlite3_stmt, decltype(sqlite3_finalize)*>;
-  DBHelper()
-      : db_(nullptr, sqlite3_close_v2), stmt_(nullptr, sqlite3_finalize) {}
-
-  bool Open() {
-    const char* path = GetParserDataPath();
-    if (path == nullptr)
-      return false;
-
-    sqlite3* db = nullptr;
-    int ret = sqlite3_open_v2(path, &db, SQLITE_OPEN_READONLY, nullptr);
-    if (ret != SQLITE_OK) {
-      LOGE("open db(%s) error: %d", path, ret);
-      return false;
-    }
-
-    db_.reset(db);
-
-    return true;
-  }
-
-  void Close() {
-    db_.reset();
-  }
-
-  bool Prepare(const std::string& query) {
-    sqlite3_stmt* stmt = nullptr;
-    if (sqlite3_prepare_v2(db_.get(), query.c_str(), query.size(), &stmt,
-        nullptr) != SQLITE_OK) {
-      LOGE("prepare error: %s", sqlite3_errmsg(db_.get()));
-      return false;
-    }
-
-    stmt_.reset(stmt);
-
-    return true;
-  }
-
-  const Cursor& GetCursor() const {
-    return stmt_;
-  }
-
-  int Step() const {
-    return sqlite3_step(stmt_.get());
-  }
-
-  bool Bind(int pos, std::string text) {
-    int ret = sqlite3_bind_text(stmt_.get(), pos, text.c_str(),
-      -1, SQLITE_TRANSIENT);
-    if (ret != SQLITE_OK) {
-      LOGE("bind error: %s", sqlite3_errmsg(db_.get()));
-      return false;
-    }
-
-    return true;
-  }
-
-  bool Bind(int pos, int val) {
-    if (sqlite3_bind_int(stmt_.get(), pos, val) != SQLITE_OK) {
-      LOGE("bind error: %s", sqlite3_errmsg(db_.get()));
-      return false;
-    }
-
-    return true;
-  }
-
-  const char* GetText(int pos) const {
-    return reinterpret_cast<const char*>(sqlite3_column_text(stmt_.get(), pos));
-  }
-
-  int GetInt(int pos) const {
-    return sqlite3_column_int(stmt_.get(), pos);
-  }
-
- private:
-  const char* GetParserDataPath() const {
-    uid_t target_uid;
-    const char* path;
-    bool is_global;
-
-    pkgmgr_installer_info_get_target_uid(&target_uid);
-
-    if (target_uid == ROOT_USER
-      || target_uid == tzplatform_getuid(TZ_SYS_GLOBALAPP_USER))
-      is_global = true;
-    else
-      is_global = false;
-
-    if (!is_global)
-        tzplatform_set_user(target_uid);
-
-    path = tzplatform_mkpath(is_global ? TZ_SYS_DB : TZ_USER_DB,
-        ".complication_provider.db");
-    tzplatform_reset_user();
-
-    return path;
-  }
-
- private:
-  std::unique_ptr<sqlite3, decltype(sqlite3_close_v2)*> db_;
-  Cursor stmt_;
-};
-}  // namespace
-
 namespace watchface_complication {
 
 DBManager::DBManager() = default;
@@ -152,10 +42,11 @@ DBManager::~DBManager() = default;
 std::unique_ptr<Bundle> DBManager::GetDefaultData(const char* provider_id,
                                                   int support_type) {
   static const char query[] =
-    "SELECT trusted, appid, default_data FROM complication_provider "
-    "WHERE provider_id=? AND support_type=?";
+    "SELECT trusted, appid, default_data FROM complication_provider as A "
+    "LEFT JOIN provider_support_types as B ON A.provider_id = B.provider_id "
+    "WHERE A.provider_id=? AND support_type=?";
 
-  ::DBHelper db;
+  util::DBHelper db;
 
   if (!db.Open())
     return nullptr;
@@ -207,7 +98,7 @@ int DBManager::GetProviderPeriod(std::string& provider_id, int* period) {
   static const char query[] =
     "SELECT period FROM complication_provider WHERE provider_id=?";
 
-  ::DBHelper db;
+  util::DBHelper db;
 
   if (!db.Open())
     return WATCHFACE_COMPLICATION_ERROR_DB;
@@ -229,9 +120,10 @@ int DBManager::GetProviderPeriod(std::string& provider_id, int* period) {
 
 bool DBManager::IsProviderExist(std::string& provider_id, int support_type) {
   static const char query[] =
-    "SELECT trusted, appid FROM complication_provider "
-    "WHERE provider_id=? AND support_type=?";
-  ::DBHelper db;
+    "SELECT trusted, appid FROM complication_provider as A "
+    "LEFT JOIN provider_support_types as B ON A.provider_id = B.provider_id "
+    "WHERE A.provider_id=? AND support_type=?";
+  util::DBHelper db;
 
   if (!db.Open())
     return false;
@@ -268,7 +160,7 @@ bool DBManager::IsProviderExist(std::string& provider_id, int support_type) {
 std::string DBManager::GetProviderAppId(const char* provider_id) {
   static const char query[] =
     "SELECT trusted, appid FROM complication_provider WHERE provider_id=?";
-  ::DBHelper db;
+  util::DBHelper db;
 
   if (!db.Open())
     return std::string();
@@ -300,9 +192,11 @@ std::string DBManager::GetProviderAppId(const char* provider_id) {
 std::list<std::unique_ptr<DBManager::ProviderInfo>>
 DBManager::GetProviderListWithTypes(int supported_types) {
   static const char query[] =
-    "SELECT trusted, appid, provider_id, support_type FROM complication_provider "
+    "SELECT trusted, appid, A.provider_id, support_type FROM "
+    "complication_provider as A LEFT JOIN provider_support_types as B "
+    "ON A.provider_id = B.provider_id "
     "WHERE (support_type & ?) > 0";
-  ::DBHelper db;
+  util::DBHelper db;
 
   if (!db.Open())
     return {};
@@ -342,7 +236,7 @@ std::list<std::string> DBManager::GetProviderListWithAppId(
     const char* provider_app_id) {
   static const char query[] =
     "SELECT DISTINCT provider_id FROM complication_provider WHERE appid=?";
-  ::DBHelper db;
+  util::DBHelper db;
 
   if (!db.Open())
     return {};
@@ -368,9 +262,10 @@ std::list<std::string> DBManager::GetProviderListWithAppId(
 
 int DBManager::GetSupportTypes(std::string& provider_id, int* types) {
   static const char query[] =
-      "SELECT trusted, appid, SUM(support_type) FROM complication_provider "
-      "WHERE provider_id = ?";
-  ::DBHelper db;
+      "SELECT trusted, appid, SUM(support_type) FROM complication_provider as A "
+      "LEFT JOIN provider_support_types as B ON A.provider_id = B.provider_id "
+      "WHERE A.provider_id = ?";
+  util::DBHelper db;
 
   if (!db.Open())
     return WATCHFACE_COMPLICATION_ERROR_DB;
@@ -405,7 +300,7 @@ std::list<std::string> DBManager::GetRequiredPrivilegeList(
     std::string& provider_id) {
   static const char query[] =
     "SELECT DISTINCT privilege FROM provider_privilege WHERE provider_id=?";
-  ::DBHelper db;
+  util::DBHelper db;
 
   if (!db.Open())
     return {};
@@ -439,7 +334,7 @@ int DBManager::GetRequiredSupportEvents(
   int support_events = WATCHFACE_COMPLICATION_EVENT_NONE;
   static const char query[] =
     "SELECT support_events FROM provider_support_events WHERE provider_id=?";
-  ::DBHelper db;
+  util::DBHelper db;
 
   if (!db.Open())
     return -1;
@@ -503,7 +398,7 @@ std::string DBManager::GetLabel(const char* provider_id) {
   static const char query[] =
     "SELECT provider_label FROM provider_localized_info "
     "WHERE provider_id=? AND locale=?";
-  ::DBHelper db;
+  util::DBHelper db;
 
   if (!db.Open())
     return std::string();
@@ -558,7 +453,7 @@ std::string DBManager::GetLabel(const char* provider_id) {
 std::string DBManager::GetSetupAppId(const char* provider_id) {
   static const char query[] =
     "SELECT DISTINCT setup_appid FROM provider_setup_appid WHERE provider_id=?";
-  ::DBHelper db;
+  util::DBHelper db;
 
   if (!db.Open())
     return std::string();
@@ -585,7 +480,7 @@ std::string DBManager::GetSetupAppId(const char* provider_id) {
 int DBManager::GetTrustedInfo(std::string& provider_id, bool* trusted) {
   static const char query[] =
       "SELECT trusted FROM complication_provider WHERE provider_id = ?";
-  ::DBHelper db;
+  util::DBHelper db;
 
   if (!db.Open())
     return WATCHFACE_COMPLICATION_ERROR_DB;