+bool _media_svc_is_keyword_included(const char *path, const char *keyword)
+{
+ bool ret = false;
+ void *handle = NULL;
+ bool (*svc_search) (const char *, const char *);
+
+ media_svc_retvm_if(!path, false, "Invalid path");
+ media_svc_retvm_if(!keyword, false, "Invalid keyword");
+
+ handle = dlopen(PATH_PLUGIN_LIB, RTLD_LAZY);
+ media_svc_retvm_if(!handle, false, "dlopen failed");
+
+ if (g_str_has_suffix(path, "epub") || g_str_has_suffix(path, "EPUB"))
+ svc_search = dlsym(handle, "media_svc_epub_is_keyword_included");
+ else
+ svc_search = dlsym(handle, "media_svc_pdf_is_keyword_included");
+
+ if (!svc_search) {
+ media_svc_error("dlsym failed - %s", dlerror());
+ dlclose(handle);
+ return false;
+ }
+
+ ret = svc_search(path, keyword);
+ dlclose(handle);
+
+ return ret;
+}
+
+static int __media_svc_create_wordbook_db(const char *path, sqlite3 **handle)
+{
+ int ret = SQLITE_OK;
+ sqlite3 *db_handle = NULL;
+ char *err = NULL;
+
+ ret = sqlite3_open_v2(path, &db_handle, SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, NULL);
+ media_svc_retvm_if(ret != SQLITE_OK, ret, "sqlite3_open_v2 failed : %d", ret);
+
+ ret = sqlite3_exec(db_handle, "PRAGMA journal_mode = OFF;", NULL, NULL, &err);
+ if (ret != SQLITE_OK)
+ goto ERROR;
+
+ ret = sqlite3_exec(db_handle, "CREATE TABLE IF NOT EXISTS files(id integer primary key autoincrement, path text unique, validity integer default 1);", NULL, NULL, &err);
+ if (ret != SQLITE_OK)
+ goto ERROR;
+
+ ret = sqlite3_exec(db_handle, "CREATE TABLE IF NOT EXISTS words(file_id integer, word text, frequency integer default 1, unique(file_id, word));", NULL, NULL, &err);
+ if (ret != SQLITE_OK)
+ goto ERROR;
+
+ ret = sqlite3_exec(db_handle, "CREATE TRIGGER IF NOT EXISTS TR_files_words DELETE ON files BEGIN DELETE FROM words WHERE file_id = old.id;END;", NULL, NULL, &err);
+ if (ret != SQLITE_OK)
+ goto ERROR;
+
+ *handle = db_handle;
+
+ return SQLITE_OK;
+
+ERROR:
+ media_svc_error("sqlite3_exec failed : %s", err);
+ SQLITE3_SAFE_FREE(err);
+ sqlite3_close_v2(db_handle);
+
+ return ret;
+}
+
+static bool __media_svc_get_wordbook_handle(uid_t uid, sqlite3 **handle)
+{
+ int ret = SQLITE_OK;
+ char *db_path = NULL;
+
+ ms_user_get_wordbook_db_path(uid, &db_path);
+ if (!db_path)
+ return false;
+
+ ret = sqlite3_open_v2(db_path, handle, SQLITE_OPEN_READWRITE, NULL);
+ if (ret != SQLITE_OK) {
+ ret = __media_svc_create_wordbook_db(db_path, handle);
+ free(db_path);
+ media_svc_retvm_if(ret != SQLITE_OK, false, "__media_svc_create_wordbook_db failed : %d", ret);
+ } else {
+ ret = sqlite3_exec(*handle, "PRAGMA journal_mode = OFF;", NULL, NULL, NULL);
+ if (ret != SQLITE_OK)
+ media_svc_error("Failed to change journal mode [%d]", ret);
+ }
+
+ return true;
+}
+
+static bool __media_svc_is_exist_in_wordbook(sqlite3 *db_handle, const char *path)
+{
+ int ret = SQLITE_OK;
+ char *err = NULL;
+ char *query = NULL;
+
+ query = sqlite3_mprintf("UPDATE files SET validity=1 WHERE path = %Q", path);
+
+ ret = sqlite3_exec(db_handle, query, NULL, NULL, &err);
+ SQLITE3_SAFE_FREE(query);
+ if (ret != SQLITE_OK) {
+ media_svc_error("Query failed. [%s]", err);
+ SQLITE3_SAFE_FREE(err);
+ return false;
+ }
+
+ return sqlite3_changes(db_handle) > 0 ? true : false;
+}
+
+static void __media_svc_insert_to_wordbook(sqlite3 *db_handle, const char *path)
+{
+ void *handle = NULL;
+ void (*svc_update) (sqlite3 *, const char *);
+ char *query = NULL;
+
+ query = sqlite3_mprintf("INSERT INTO files(path) VALUES(%Q);", path);
+ sqlite3_exec(db_handle, query, NULL, NULL, NULL);
+ sqlite3_free(query);
+
+ handle = dlopen(PATH_PLUGIN_LIB, RTLD_LAZY);
+ if (!handle) {
+ media_svc_error("dlopen failed");
+ return;
+ }
+
+ if (g_str_has_suffix(path, "epub") || g_str_has_suffix(path, "EPUB"))
+ svc_update = dlsym(handle, "media_svc_epub_insert_to_db");
+ else
+ svc_update = dlsym(handle, "media_svc_pdf_insert_to_db");
+
+ if (!svc_update) {
+ media_svc_error("dlsym failed - %s", dlerror());
+ dlclose(handle);
+ return;
+ }
+
+ svc_update(db_handle, path);
+ dlclose(handle);
+}
+
+void _media_svc_update_wordbook(const char *path, uid_t uid)
+{
+ sqlite3 *db_handle = NULL;
+
+ if (!path) {
+ media_svc_error("Invalid path");
+ return;
+ }
+
+ // check db..
+ if (!__media_svc_get_wordbook_handle(uid, &db_handle))
+ return;
+
+ if (__media_svc_is_exist_in_wordbook(db_handle, path)) {
+ sqlite3_close_v2(db_handle);
+ return;
+ }
+
+ // if no item, insert to db..
+ __media_svc_insert_to_wordbook(db_handle, path);
+ sqlite3_close_v2(db_handle);
+}
+
+void _media_svc_clean_wordbook(uid_t uid)
+{
+ sqlite3 *db_handle = NULL;
+
+ if (!__media_svc_get_wordbook_handle(uid, &db_handle))
+ return;
+
+ sqlite3_exec(db_handle, "DELETE FROM files where validity = 0;", NULL, NULL, NULL);
+ sqlite3_exec(db_handle, "UPDATE files SET validity = 0;", NULL, NULL, NULL);
+ sqlite3_close_v2(db_handle);
+}
+
+bool _media_svc_get_matched_list(const char *keyword, uid_t uid, GList **list)
+{
+ int ret = SQLITE_OK;
+ sqlite3 *handle = NULL;
+ sqlite3_stmt *stmt = NULL;
+ char *query = NULL;
+
+ media_svc_retvm_if(!list, false, "list is NULL");
+ media_svc_retvm_if(!keyword, false, "keyword is NULL");
+ media_svc_retvm_if(!__media_svc_get_wordbook_handle(uid, &handle), false, "Failed to get handle");
+
+ query = sqlite3_mprintf("SELECT files.path FROM files JOIN (SELECT file_id, sum(frequency) AS freq_sum FROM words WHERE word LIKE '%q%%' GROUP BY file_id ORDER BY freq_sum DESC) w ON files.id = w.file_id;", keyword);
+ ret = sqlite3_prepare_v2(handle, query, -1, &stmt, NULL);
+ SQLITE3_SAFE_FREE(query);
+
+ if (ret != SQLITE_OK) {
+ media_svc_error("Query failed[%d]", ret);
+ sqlite3_close_v2(handle);
+ return false;
+ }
+
+ while (sqlite3_step(stmt) == SQLITE_ROW)
+ *list = g_list_append(*list, g_strdup((char *)sqlite3_column_text(stmt, 0)));
+
+ sqlite3_finalize(stmt);
+ sqlite3_close_v2(handle);
+
+ return true;
+}