Improve performence of app_info.db creation/insertion of a package in app_info.db 52/5452/10 accepted/tizen/20130723.173843 submit/tizen/20130723.135654
authorBaptiste DURAND <baptiste.durand@eurogiciel.fr>
Fri, 19 Jul 2013 17:21:49 +0000 (19:21 +0200)
committerBaptiste DURAND <baptiste.durand@eurogiciel.fr>
Fri, 19 Jul 2013 17:21:49 +0000 (19:21 +0200)
Fix TZPC-3461:Instead of making 1 SQL request for each local name, make just 1 SQL request to insert all locale name

packaging/ail.changes
src/ail_db.c
src/ail_db.h
src/ail_desktop.c

index 8b1942c..1f8412a 100644 (file)
@@ -1,3 +1,6 @@
+* Tue Jul 09 2013 Baptiste DURAND <baptiste.durand@eurogiciel.fr> accepted/tizen/20130628.165836@f5fdef3
+- Improve performence of app_info.db creation/insertion of a package in app_info.db
+
 * Fri Jun 28 2013 Baptiste DURAND <baptiste.durand@eurogiciel.fr> accepted/tizen/20130627.044239@e0cb252
 - manage package update.
 
index b8edd15..cc41d32 100755 (executable)
@@ -46,6 +46,23 @@ static __thread struct {
        .dbrw = NULL
 };
 
+
+static ail_error_e db_do_prepare(sqlite3 *db, const char *query, sqlite3_stmt **stmt)
+{
+       int ret;
+
+       retv_if(!query, AIL_ERROR_INVALID_PARAMETER);
+       retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
+       retv_if(!db, AIL_ERROR_DB_FAILED);
+
+       ret = sqlite3_prepare_v2(db, query, strlen(query), stmt, NULL);
+       if (ret != SQLITE_OK) {
+               _E("%s\n", sqlite3_errmsg(db));
+               return AIL_ERROR_DB_FAILED;
+       } else
+               return AIL_ERROR_OK;
+}
+
 ail_error_e db_open(db_open_mode mode)
 {
        int ret;
@@ -70,22 +87,14 @@ ail_error_e db_open(db_open_mode mode)
        return AIL_ERROR_OK;
 }
 
-
-
 ail_error_e db_prepare(const char *query, sqlite3_stmt **stmt)
 {
-       int ret;
-
-       retv_if(!query, AIL_ERROR_INVALID_PARAMETER);
-       retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
-       retv_if(!db_info.dbro, AIL_ERROR_DB_FAILED);
+       return db_do_prepare(db_info.dbro, query, stmt);
+}
 
-       ret = sqlite3_prepare_v2(db_info.dbro, query, strlen(query), stmt, NULL);
-       if (ret != SQLITE_OK) {
-               _E("%s\n", sqlite3_errmsg(db_info.dbro));
-               return AIL_ERROR_DB_FAILED;
-       } else 
-               return AIL_ERROR_OK;
+ail_error_e db_prepare_rw(const char *query, sqlite3_stmt **stmt)
+{
+       return db_do_prepare(db_info.dbrw, query, stmt);
 }
 
 
@@ -115,6 +124,17 @@ ail_error_e db_bind_int(sqlite3_stmt *stmt, int idx, int value)
        return AIL_ERROR_OK;
 }
 
+ail_error_e db_bind_text(sqlite3_stmt *stmt, int idx, char* value)
+{
+       int ret;
+
+       retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
+
+       ret = sqlite3_bind_text(stmt, idx, value, strlen(value), 0);
+       retv_with_dbmsg_if(ret != SQLITE_OK, AIL_ERROR_DB_FAILED);
+
+       return AIL_ERROR_OK;
+}
 
 
 ail_error_e db_step(sqlite3_stmt *stmt)
index 56b1b2a..a8b8b4b 100755 (executable)
@@ -38,9 +38,11 @@ typedef int (*sqlite_query_callback)(void *data, int ncols, char **coltxt, char
 
 ail_error_e db_open(db_open_mode mode);
 ail_error_e db_prepare(const char *query, sqlite3_stmt **stmt);
+ail_error_e db_prepare_rw(const char *query, sqlite3_stmt **stmt);
 
 ail_error_e db_bind_bool(sqlite3_stmt *stmt, int idx, bool value);
 ail_error_e db_bind_int(sqlite3_stmt *stmt, int idx, int value);
+ail_error_e db_bind_text(sqlite3_stmt *stmt, int idx, char* value);
 
 ail_error_e db_step(sqlite3_stmt *stmt);
 
index a1d19c5..cd03040 100755 (executable)
 #define whitespace(c) (((c) == ' ') || ((c) == '\t'))
 #define argsdelimiter  " \t"
 
+#define SQL_INSERT_LOCALNAME_STR "insert into localname (package, locale, name) values "
+#define SQL_INSERT_LOCALNAME_STR_LEN (sizeof(SQL_INSERT_LOCALNAME_STR)-1)
+
+#define SQL_INSERT_LOCALNAME_INIT_STR  SQL_INSERT_LOCALNAME_STR"( ?, ?, ?) "
+
+#define SQL_LOCALNAME_TRIPLET_STR  ", ( ?, ?, ?)"
+#define SQL_LOCALNAME_TRIPLET_STR_LEN (sizeof(SQL_LOCALNAME_TRIPLET_STR)-1)
+
 typedef enum {
        NOTI_ADD,
        NOTI_UPDATE,
@@ -749,7 +757,97 @@ char *_pkgname_to_desktop(const char *package)
        return desktop;
 }
 
+static inline int _bind_local_info(desktop_info_s* info, sqlite3_stmt * stmt)
+{
+       int ret = 0;
+       unsigned long i = 0;
+       struct name_item *item;
+       GSList* localname;
+       retv_if(!info, AIL_ERROR_INVALID_PARAMETER);
+       retv_if(!info->localname, AIL_ERROR_INVALID_PARAMETER);
+       retv_if(!stmt, AIL_ERROR_INVALID_PARAMETER);
+       localname = info->localname;
+       while (localname) {
+               item = (struct name_item *)     localname->data;
+               if (item && item->locale && item->name) {
+                       // Bind values for a triplet : package, locale, name
+                       retv_if(db_bind_text(stmt, i+1, info->package) != AIL_ERROR_OK, AIL_ERROR_DB_FAILED);
+                       retv_if(db_bind_text(stmt, i+2, item->locale) != AIL_ERROR_OK, AIL_ERROR_DB_FAILED);
+                       retv_if(db_bind_text(stmt, i+3, item->name) != AIL_ERROR_OK, AIL_ERROR_DB_FAILED);
+                       i += 3;
+               }
+               localname = g_slist_next(localname);
+       }
+       return AIL_ERROR_OK;
+}
+
+
+static inline int _len_local_info(desktop_info_s* info)
+{
+       int len = 0;
+       struct name_item *item;
+       GSList* localname;
+       retv_if(!info, AIL_ERROR_INVALID_PARAMETER);
+       if(info->localname)     {
+               localname = info->localname;
+               while (localname) {
+                       item = (struct name_item *)     localname->data;
+                       if (item && item->locale && item->name)
+                               len ++;
+                       localname = g_slist_next(localname);
+               }
+       }
+       return len;
+}
+
+
+static inline int _insert_local_info(desktop_info_s* info)
+{
+       int len_query = SQL_INSERT_LOCALNAME_STR_LEN;
+       int nb_locale_args;
+       char *query;
+       int ret = AIL_ERROR_OK;
+       sqlite3_stmt *stmt = NULL;
+       int i = 0;
+       retv_if(!info, AIL_ERROR_INVALID_PARAMETER);
+       retv_if(!info->localname, AIL_ERROR_INVALID_PARAMETER);
 
+       nb_locale_args = _len_local_info(info);
+
+       retv_if(!nb_locale_args, AIL_ERROR_INVALID_PARAMETER);
+
+       len_query += SQL_LOCALNAME_TRIPLET_STR_LEN*nb_locale_args +1;
+
+       query = (char *) malloc(len_query);
+       retv_if(!query, AIL_ERROR_OUT_OF_MEMORY);
+       stpncpy(query, SQL_INSERT_LOCALNAME_INIT_STR, len_query);
+       for (i = 0; i <  nb_locale_args - 1; i++)
+               strcat(query, SQL_LOCALNAME_TRIPLET_STR);
+
+       do {
+               ret = db_prepare_rw(query, &stmt);
+               if (ret < 0) break;
+
+               ret = _bind_local_info(info, stmt);
+               if (ret < 0) {
+                       _E("Can't bind locale information to this query - %s. ",query);
+                       db_finalize(stmt);
+                       break;
+               }
+               ret = db_step(stmt);
+               if (ret != AIL_ERROR_NO_DATA) {
+                       /* Insert Request doesn't return any data.
+                        * db_step should returns AIL_ERROR_NO_DATA in this case. */
+                       _E("Can't execute this query - %s. ",query);
+                       db_finalize(stmt);
+                       break;
+               }
+               ret = db_finalize(stmt);
+       } while(0);
+
+       free(query);
+       return ret;
+}
 
 static inline int _strlen_desktop_info(desktop_info_s* info)
 {
@@ -1213,10 +1311,11 @@ static ail_error_e _insert_desktop_info(desktop_info_s *info)
        }
 
        ret = db_exec(query);
+       free(query);
        retv_if(ret != AIL_ERROR_OK, AIL_ERROR_DB_FAILED);
 
        if (info->localname)
-               g_slist_foreach(info->localname, _insert_localname, info);
+               _insert_local_info(info);
 
        _D("Add (%s).", info->package);
 
@@ -1309,7 +1408,7 @@ static ail_error_e _update_desktop_info(desktop_info_s *info)
        }
 
        if (info->localname)
-               g_slist_foreach(info->localname, _insert_localname, info);
+               _insert_local_info(info);
 
        _D("Update (%s).", info->package);