Fix resetting prepared statement 30/45030/8
authorOskar Świtalski <o.switalski@samsung.com>
Thu, 30 Jul 2015 12:14:12 +0000 (14:14 +0200)
committerRafal Krypa <r.krypa@samsung.com>
Tue, 11 Aug 2015 08:24:33 +0000 (01:24 -0700)
Prepared statement should be reset/finalized
after making new one, otherwise database will
be in BUSY state and locked.

Change-Id: I679d3d41b1de406112a93c6d0c73ff0d0aae5d63

src/common/include/privilege_db.h
src/common/privilege_db.cpp

index 1b3f7a2..83fb157 100644 (file)
@@ -76,6 +76,18 @@ private:
      */
     PrivilegeDb(const std::string &path = std::string(PRIVILEGE_DB_PATH));
 
+    /**
+     * Wrapper for prepared statement, it will reset statement at destruction.
+     */
+    class StatementWrapper {
+    public:
+        StatementWrapper(DB::SqlConnection::DataCommandAutoPtr &ref);
+        ~StatementWrapper();
+        DB::SqlConnection::DataCommand* operator->();
+    private:
+        DB::SqlConnection::DataCommandAutoPtr &m_ref;
+    };
+
     SecurityManager::DB::SqlConnection *mSqlConnection;
     const std::map<StmtType, const char * const > Queries = {
         { StmtType::EGetPkgPrivileges, "SELECT DISTINCT privilege_name FROM app_privilege_view WHERE pkg_name=? AND uid=? ORDER BY privilege_name"},
@@ -115,13 +127,13 @@ private:
     void initDataCommands();
 
     /**
-     * Return prepared query for given query type.
-     * The query will be reset before returning.
+     * Return wrapped prepared query for given query type.
+     * The query will be reset after wrapper destruction.
      *
      * @param queryType query identifier
-     * @return reference to prepared, reset query
+     * @return wrapped prepared query
      */
-    DB::SqlConnection::DataCommandAutoPtr & getStatement(StmtType queryType);
+    StatementWrapper getStatement(StmtType queryType);
 
     /**
      * Check if pkgId is already registered in database
index 8dca5f6..0498f21 100644 (file)
@@ -76,11 +76,22 @@ void PrivilegeDb::initDataCommands()
     }
 }
 
-DB::SqlConnection::DataCommandAutoPtr & PrivilegeDb::getStatement(StmtType queryType)
+PrivilegeDb::StatementWrapper::StatementWrapper(DB::SqlConnection::DataCommandAutoPtr &ref)
+    : m_ref(ref) {}
+
+PrivilegeDb::StatementWrapper::~StatementWrapper()
+{
+    m_ref->Reset();
+}
+
+DB::SqlConnection::DataCommand* PrivilegeDb::StatementWrapper::operator->()
+{
+    return m_ref.get();
+}
+
+PrivilegeDb::StatementWrapper PrivilegeDb::getStatement(StmtType queryType)
 {
-    auto &command = m_commands.at(static_cast<size_t>(queryType));
-    command->Reset();
-    return command;
+    return StatementWrapper(m_commands.at(static_cast<size_t>(queryType)));
 }
 
 PrivilegeDb::~PrivilegeDb()
@@ -119,7 +130,7 @@ void PrivilegeDb::RollbackTransaction(void)
 bool PrivilegeDb::PkgIdExists(const std::string &pkgId)
 {
     return try_catch<bool>([&] {
-        auto &command = getStatement(StmtType::EPkgIdExists);
+        auto command = getStatement(StmtType::EPkgIdExists);
         command->BindString(1, pkgId);
         return command->Step();
     });
@@ -128,7 +139,7 @@ bool PrivilegeDb::PkgIdExists(const std::string &pkgId)
 bool PrivilegeDb::GetAppPkgId(const std::string &appId, std::string &pkgId)
 {
     return try_catch<bool>([&] {
-        auto &command = getStatement(StmtType::EGetPkgId);
+        auto command = getStatement(StmtType::EGetPkgId);
         command->BindString(1, appId);
 
         if (!command->Step()) {
@@ -147,7 +158,7 @@ void PrivilegeDb::AddApplication(const std::string &appId,
         const std::string &pkgId, uid_t uid)
 {
     try_catch<void>([&] {
-        auto &command = getStatement(StmtType::EAddApplication);
+        auto command = getStatement(StmtType::EAddApplication);
         command->BindString(1, appId);
         command->BindString(2, pkgId);
         command->BindInteger(3, static_cast<unsigned int>(uid));
@@ -171,7 +182,7 @@ void PrivilegeDb::RemoveApplication(const std::string &appId, uid_t uid,
             return;
         }
 
-        auto &command = getStatement(StmtType::ERemoveApplication);
+        auto command = getStatement(StmtType::ERemoveApplication);
         command->BindString(1, appId);
         command->BindInteger(2, static_cast<unsigned int>(uid));
 
@@ -190,7 +201,7 @@ void PrivilegeDb::GetPkgPrivileges(const std::string &pkgId, uid_t uid,
         std::vector<std::string> &currentPrivileges)
 {
     try_catch<void>([&] {
-        auto &command = getStatement(StmtType::EGetPkgPrivileges);
+        auto command = getStatement(StmtType::EGetPkgPrivileges);
         command->BindString(1, pkgId);
         command->BindInteger(2, static_cast<unsigned int>(uid));
 
@@ -206,10 +217,8 @@ void PrivilegeDb::GetAppPrivileges(const std::string &appId, uid_t uid,
         std::vector<std::string> &currentPrivileges)
 {
     try_catch<void>([&] {
-        DB::SqlConnection::DataCommandAutoPtr &command =
-                m_commands.at(static_cast<size_t>(StmtType::EGetAppPrivileges));
+        auto command = getStatement(StmtType::EGetAppPrivileges);
 
-        command->Reset();
         command->BindString(1, appId);
         command->BindInteger(2, static_cast<unsigned int>(uid));
         currentPrivileges.clear();
@@ -225,7 +234,7 @@ void PrivilegeDb::GetAppPrivileges(const std::string &appId, uid_t uid,
 void PrivilegeDb::RemoveAppPrivileges(const std::string &appId, uid_t uid)
 {
     try_catch<void>([&] {
-        auto &command = getStatement(StmtType::ERemoveAppPrivileges);
+        auto command = getStatement(StmtType::ERemoveAppPrivileges);
         command->BindString(1, appId);
         command->BindInteger(2, static_cast<unsigned int>(uid));
         if (command->Step()) {
@@ -241,7 +250,7 @@ void PrivilegeDb::UpdateAppPrivileges(const std::string &appId, uid_t uid,
         const std::vector<std::string> &privileges)
 {
     try_catch<void>([&] {
-        auto &command = getStatement(StmtType::EAddAppPrivileges);
+        auto command = getStatement(StmtType::EAddAppPrivileges);
         command->BindString(1, appId);
         command->BindInteger(2, static_cast<unsigned int>(uid));
 
@@ -260,7 +269,7 @@ void PrivilegeDb::GetPrivilegeGroups(const std::string &privilege,
         std::vector<std::string> &groups)
 {
    try_catch<void>([&] {
-        auto &command = getStatement(StmtType::EGetPrivilegeGroups);
+        auto command = getStatement(StmtType::EGetPrivilegeGroups);
         command->BindString(1, privilege);
 
         while (command->Step()) {
@@ -274,7 +283,7 @@ void PrivilegeDb::GetPrivilegeGroups(const std::string &privilege,
 void PrivilegeDb::GetUserApps(uid_t uid, std::vector<std::string> &apps)
 {
    try_catch<void>([&] {
-        auto &command = getStatement(StmtType::EGetUserApps);
+        auto command = getStatement(StmtType::EGetUserApps);
         command->BindInteger(1, static_cast<unsigned int>(uid));
         apps.clear();
         while (command->Step()) {
@@ -289,10 +298,8 @@ void PrivilegeDb::GetAppIdsForPkgId(const std::string &pkgId,
         std::vector<std::string> &appIds)
 {
     try_catch<void>([&] {
-        DB::SqlConnection::DataCommandAutoPtr &command =
-                m_commands.at(static_cast<size_t>(StmtType::EGetAppsInPkg));
+        auto command = getStatement(StmtType::EGetAppsInPkg);
 
-        command->Reset();
         command->BindString(1, pkgId);
         appIds.clear();
 
@@ -309,7 +316,7 @@ void PrivilegeDb::GetDefaultMapping(const std::string &version_from,
                                     std::vector<std::string> &mappings)
 {
     try_catch<void>([&] {
-        auto &command = getStatement(StmtType::EGetDefaultMappings);
+        auto command = getStatement(StmtType::EGetDefaultMappings);
         command->BindString(1, version_from);
         command->BindString(2, version_to);
 
@@ -329,7 +336,7 @@ void PrivilegeDb::GetPrivilegeMappings(const std::string &version_from,
                                        std::vector<std::string> &mappings)
 {
     try_catch<void>([&] {
-        auto &command = getStatement(StmtType::EGetPrivilegeMappings);
+        auto command = getStatement(StmtType::EGetPrivilegeMappings);
         command->BindString(1, version_from);
         command->BindString(2, version_to);
         command->BindString(3, privilege);
@@ -350,10 +357,10 @@ void PrivilegeDb::GetPrivilegesMappings(const std::string &version_from,
                                         std::vector<std::string> &mappings)
 {
     try_catch<void>([&] {
-        auto &deleteCmd = getStatement(StmtType::EDeletePrivilegesToMap);
+        auto deleteCmd = getStatement(StmtType::EDeletePrivilegesToMap);
         deleteCmd->Step();
 
-        auto insertCmd = getStatement(StmtType::EInsertPrivilegeToMap);
+        auto insertCmd = getStatement(StmtType::EInsertPrivilegeToMap);
         for (auto &privilege : privileges) {
             if (privilege.empty())
                 continue;
@@ -365,7 +372,7 @@ void PrivilegeDb::GetPrivilegesMappings(const std::string &version_from,
         insertCmd->BindNull(1);
         insertCmd->Step();
 
-        auto &queryCmd = getStatement(StmtType::EGetPrivilegesMappings);
+        auto queryCmd = getStatement(StmtType::EGetPrivilegesMappings);
         queryCmd->BindString(1, version_from);
         queryCmd->BindString(2, version_to);