Prepare database queries during PrivilegeDb singleton init 65/30965/4
authorMarcin Lis <m.lis@samsung.com>
Thu, 27 Nov 2014 13:06:08 +0000 (14:06 +0100)
committerGerrit Code Review <gerrit@review.vlan103.tizen.org>
Wed, 3 Dec 2014 11:11:35 +0000 (03:11 -0800)
Avoid too many sqlite3_prepare_v2 calls, which take many cpu cycles to complete.
SQLite statements may be prepared once when DB object is created.

Change-Id: I99e4fd3fea63fd61396c9f7b2c3b13539f312d48
Signed-off-by: Marcin Lis <m.lis@samsung.com>
src/common/include/privilege_db.h
src/common/privilege_db.cpp
src/dpl/db/include/dpl/db/sql_connection.h

index a95ade8..1df7723 100644 (file)
@@ -82,6 +82,20 @@ private:
     };
 
     /**
+     * Container for initialized DataCommands, prepared for binding.
+     */
+    std::vector<DB::SqlConnection::DataCommandAutoPtr> m_commands;
+
+    /**
+     * Fills empty m_commands map with sql commands prepared for binding.
+     *
+     * Because the "sqlite3_prepare_v2" function takes many cpu cycles, the PrivilegeDb
+     * is optimized to call it only once for one query type.
+     * Designed to be used in the singleton contructor.
+     */
+    void initDataCommands();
+
+    /**
      * Check if pkgId is already registered in database
      *
      * @param pkgId - package identifier
index ac83ce6..cca5aaa 100644 (file)
@@ -60,6 +60,7 @@ PrivilegeDb::PrivilegeDb(const std::string &path)
         mSqlConnection = new DB::SqlConnection(path,
                 DB::SqlConnection::Flag::None,
                 DB::SqlConnection::Flag::RW);
+        initDataCommands();
     } catch (DB::SqlConnection::Exception::Base &e) {
         LogError("Database initialization error: " << e.DumpToString());
         ThrowMsg(PrivilegeDb::Exception::IOError,
@@ -68,6 +69,13 @@ PrivilegeDb::PrivilegeDb(const std::string &path)
     };
 }
 
+void PrivilegeDb::initDataCommands()
+{
+    for (auto &it : Queries) {
+        m_commands.push_back(mSqlConnection->PrepareDataCommand(it.second));
+    }
+}
+
 PrivilegeDb::~PrivilegeDb()
 {
     delete mSqlConnection;
@@ -103,26 +111,22 @@ void PrivilegeDb::RollbackTransaction(void)
 bool PrivilegeDb::PkgIdExists(const std::string &pkgId)
 {
     return try_catch<bool>([&] {
-        DB::SqlConnection::DataCommandAutoPtr command =
-                mSqlConnection->PrepareDataCommand(
-                        Queries.at(QueryType::EPkgIdExists));
-        command->BindString(1, pkgId.c_str());
-        if (command->Step()) {
-            // pkgId found in the database
-            command->Reset();
-            return true;
-        };
+        DB::SqlConnection::DataCommandAutoPtr &command =
+            m_commands.at(static_cast<size_t>(QueryType::EPkgIdExists));
 
-        // pkgId not found in the database
-        return false;
+        command->Reset();
+        command->BindString(1, pkgId.c_str());
+        return command->Step();
     });
 }
 
 bool PrivilegeDb::GetAppPkgId(const std::string &appId, std::string &pkgId)
 {
     return try_catch<bool>([&] {
-        DB::SqlConnection::DataCommandAutoPtr command =
-            mSqlConnection->PrepareDataCommand(Queries.at(QueryType::EGetPkgId));
+        DB::SqlConnection::DataCommandAutoPtr &command =
+            m_commands.at(static_cast<size_t>(QueryType::EGetPkgId));
+
+        command->Reset();
         command->BindString(1, appId.c_str());
 
         if (!command->Step()) {
@@ -143,10 +147,10 @@ void PrivilegeDb::AddApplication(const std::string &appId,
     pkgIdIsNew = !(this->PkgIdExists(pkgId));
 
     try_catch<void>([&] {
-        DB::SqlConnection::DataCommandAutoPtr command =
-                mSqlConnection->PrepareDataCommand(
-                        Queries.at(QueryType::EAddApplication));
+        DB::SqlConnection::DataCommandAutoPtr &command =
+                m_commands.at(static_cast<size_t>(QueryType::EAddApplication));
 
+        command->Reset();
         command->BindString(1, appId.c_str());
         command->BindString(2, pkgId.c_str());
         command->BindInteger(3, static_cast<unsigned int>(uid));
@@ -156,7 +160,6 @@ void PrivilegeDb::AddApplication(const std::string &appId,
                     Queries.at(QueryType::EAddApplication));
         };
 
-        command->Reset();
         LogDebug("Added appId: " << appId << ", pkgId: " << pkgId);
     });
 }
@@ -171,10 +174,10 @@ void PrivilegeDb::RemoveApplication(const std::string &appId, uid_t uid,
             return;
         }
 
-        DB::SqlConnection::DataCommandAutoPtr command =
-                mSqlConnection->PrepareDataCommand(
-                        Queries.at(QueryType::ERemoveApplication));
+        DB::SqlConnection::DataCommandAutoPtr &command =
+                m_commands.at(static_cast<size_t>(QueryType::ERemoveApplication));
 
+        command->Reset();
         command->BindString(1, appId.c_str());
         command->BindInteger(2, static_cast<unsigned int>(uid));
 
@@ -183,7 +186,6 @@ void PrivilegeDb::RemoveApplication(const std::string &appId, uid_t uid,
                     Queries.at(QueryType::ERemoveApplication));
         };
 
-        command->Reset();
         LogDebug("Removed appId: " << appId);
 
         pkgIdIsNoMore = !(this->PkgIdExists(pkgId));
@@ -194,9 +196,10 @@ void PrivilegeDb::GetPkgPrivileges(const std::string &pkgId, uid_t uid,
         std::vector<std::string> &currentPrivileges)
 {
     try_catch<void>([&] {
-        DB::SqlConnection::DataCommandAutoPtr command =
-                mSqlConnection->PrepareDataCommand(
-                        Queries.at(QueryType::EGetPkgPrivileges));
+        DB::SqlConnection::DataCommandAutoPtr &command =
+                m_commands.at(static_cast<size_t>(QueryType::EGetPkgPrivileges));
+
+        command->Reset();
         command->BindString(1, pkgId.c_str());
         command->BindInteger(2, static_cast<unsigned int>(uid));
 
@@ -211,9 +214,10 @@ void PrivilegeDb::GetPkgPrivileges(const std::string &pkgId, uid_t uid,
 void PrivilegeDb::RemoveAppPrivileges(const std::string &appId, uid_t uid)
 {
     try_catch<void>([&] {
-        DB::SqlConnection::DataCommandAutoPtr command =
-            mSqlConnection->PrepareDataCommand(Queries.at(QueryType::ERemoveAppPrivileges));
+        DB::SqlConnection::DataCommandAutoPtr &command =
+            m_commands.at(static_cast<size_t>(QueryType::ERemoveAppPrivileges));
 
+        command->Reset();
         command->BindString(1, appId.c_str());
         command->BindInteger(2, static_cast<unsigned int>(uid));
         if (command->Step()) {
@@ -229,8 +233,10 @@ void PrivilegeDb::UpdateAppPrivileges(const std::string &appId, uid_t uid,
         const std::vector<std::string> &privileges)
 {
     try_catch<void>([&] {
-        DB::SqlConnection::DataCommandAutoPtr command =
-            mSqlConnection->PrepareDataCommand(Queries.at(QueryType::EAddAppPrivileges));
+        DB::SqlConnection::DataCommandAutoPtr &command =
+            m_commands.at(static_cast<size_t>(QueryType::EAddAppPrivileges));
+
+        command->Reset();
         command->BindString(1, appId.c_str());
         command->BindInteger(2, static_cast<unsigned int>(uid));
 
@@ -249,9 +255,10 @@ void PrivilegeDb::GetPrivilegeGroups(const std::string &privilege,
         std::vector<std::string> &groups)
 {
    try_catch<void>([&] {
-        DB::SqlConnection::DataCommandAutoPtr command =
-                mSqlConnection->PrepareDataCommand(
-                        Queries.at(QueryType::EGetPrivilegeGroups));
+        DB::SqlConnection::DataCommandAutoPtr &command =
+                m_commands.at(static_cast<size_t>(QueryType::EGetPrivilegeGroups));
+
+        command->Reset();
         command->BindString(1, privilege.c_str());
 
         while (command->Step()) {
@@ -265,9 +272,10 @@ void PrivilegeDb::GetPrivilegeGroups(const std::string &privilege,
 void PrivilegeDb::GetUserApps(uid_t uid, std::vector<std::string> &apps)
 {
    try_catch<void>([&] {
-        DB::SqlConnection::DataCommandAutoPtr command =
-                mSqlConnection->PrepareDataCommand(
-                        Queries.at(QueryType::EGetUserApps));
+        DB::SqlConnection::DataCommandAutoPtr &command =
+                m_commands.at(static_cast<size_t>(QueryType::EGetUserApps));
+
+        command->Reset();
         command->BindInteger(1, static_cast<unsigned int>(uid));
         apps.clear();
         while (command->Step()) {
index 373ad7f..510bacb 100644 (file)
@@ -364,7 +364,7 @@ class SqlConnection
     };
 
     // Move on copy semantics
-    typedef std::auto_ptr<DataCommand> DataCommandAutoPtr;
+    typedef std::unique_ptr<DataCommand> DataCommandAutoPtr;
 
     // Open flags
     class Flag