From: Baptiste DURAND Date: Fri, 19 Jul 2013 17:21:49 +0000 (+0200) Subject: Improve performence of app_info.db creation/insertion of a package in app_info.db X-Git-Tag: accepted/tizen/20130723.173843^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7d9e2b39cc5e99bfa921c41f2a5dfe21e4235201;p=platform%2Fcore%2Fappfw%2Fail.git Improve performence of app_info.db creation/insertion of a package in app_info.db Fix TZPC-3461:Instead of making 1 SQL request for each local name, make just 1 SQL request to insert all locale name --- diff --git a/packaging/ail.changes b/packaging/ail.changes index 8b1942c..1f8412a 100644 --- a/packaging/ail.changes +++ b/packaging/ail.changes @@ -1,3 +1,6 @@ +* Tue Jul 09 2013 Baptiste DURAND 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 accepted/tizen/20130627.044239@e0cb252 - manage package update. diff --git a/src/ail_db.c b/src/ail_db.c index b8edd15..cc41d32 100755 --- a/src/ail_db.c +++ b/src/ail_db.c @@ -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) diff --git a/src/ail_db.h b/src/ail_db.h index 56b1b2a..a8b8b4b 100755 --- a/src/ail_db.h +++ b/src/ail_db.h @@ -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); diff --git a/src/ail_desktop.c b/src/ail_desktop.c index a1d19c5..cd03040 100755 --- a/src/ail_desktop.c +++ b/src/ail_desktop.c @@ -46,6 +46,14 @@ #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);