diff --git a/inc/lektor/database.h b/inc/lektor/database.h index 5772ac9e9bbaf05da9c4455d369ef891e40dbbe1..34ddd8c2f26767158d287ac1eae07d006fc5d213 100644 --- a/inc/lektor/database.h +++ b/inc/lektor/database.h @@ -85,8 +85,23 @@ struct lkt_callback { bool database_queue_list(sqlite3 *db, size_t from, size_t to, struct lkt_callback *callback); /* Search the database */ -bool database_search_queue_init(sqlite3 *db, char *col_name, char *rgx, sqlite3_stmt **ret); -bool database_search_iter(sqlite3 *db, sqlite3_stmt *item, struct lkt_callback *callback, bool *need_free); +struct lkt_search { + sqlite3 *db; + sqlite3_stmt *stmt; + enum lkt_search_type { + lkt_search_database, + lkt_search_playlist, + lkt_search_queue, + } type; + void (*call)(void); /* Will be casted. */ + struct lkt_state *srv; + size_t c; +}; + +typedef bool (*lkt_search_database_func)(struct lkt_state *srv, size_t c, int id, int id_len, const char *row); + +bool database_search_queue_init(sqlite3 *db, char *col_name, char *rgx, struct lkt_search *ret); +bool database_search_iter(struct lkt_search *item); /* Next and prev operation on the queue. */ bool database_queue_next(sqlite3 *db, char filepath[PATH_MAX]); diff --git a/src/commands.c b/src/commands.c index 2ed168f5cf4141dbf6638aaf505acb50c91a91c8..c5ac47f5ae64cefdd1c4e88e278edbb4efbc250c 100644 --- a/src/commands.c +++ b/src/commands.c @@ -532,11 +532,10 @@ bool command_find(struct lkt_state *srv, size_t c, char *cmd_args[LKT_MESSAGE_ARGS_MAX], enum lkt_find_action action) { - sqlite3_stmt *stmt; char rgx[PATH_MAX], *col_name, *mpd_tag; - bool once, free_stmt; + bool once; struct lkt_message *not_found_msg; - struct lkt_callback callback = { .srv = srv, .c = c }; + struct lkt_search search = { .srv = srv, .c = c }; // Check args // if (cmd_args == NULL || cmd_args[0] == NULL) { @@ -547,13 +546,13 @@ command_find(struct lkt_state *srv, size_t c, char *cmd_args[LKT_MESSAGE_ARGS_MA // Select callback // switch (action) { case LKT_FND_ACT_RESPOND: - callback.call = lkt_callback_send_row_v1; + search.call = (void(*)(void)) lkt_callback_send_row_v1; break; case LKT_FND_ACT_PRINT: - callback.call = lkt_callback_print_row_v1; + search.call = (void(*)(void)) lkt_callback_print_row_v1; break; case LKT_FND_ACT_ENQUEUE: - callback.call = lkt_callback_insert_v1; + search.call = (void(*)(void)) lkt_callback_insert_v1; srv->mpd_idle_events |= MPD_IDLE_PLAYLIST; break; default: @@ -596,18 +595,14 @@ command_find(struct lkt_state *srv, size_t c, char *cmd_args[LKT_MESSAGE_ARGS_MA } // Make the search langand do the right action // - if (!database_search_queue_init(srv->db, col_name, rgx, &stmt)) { + if (!database_search_queue_init(srv->db, col_name, rgx, &search)) { fprintf(stderr, " ! command_find: Failed to init the search\n"); return false; } - for (once = false; database_search_iter(srv->db, stmt, &callback, &free_stmt); once |= true) + for (once = false; database_search_iter(&search); once |= true) continue; - // End // - if (free_stmt) - sqlite3_finalize(stmt); - if (!once) { no_rgx: not_found_msg = lkt_message_new(); diff --git a/src/database/find.c b/src/database/find.c index 22f60e0a4940abc7acf725be78be05dc300ecf7d..7230c9d2901748a44a89ab40288c261933ccf1ad 100644 --- a/src/database/find.c +++ b/src/database/find.c @@ -8,7 +8,7 @@ #include <string.h> bool -database_search_queue_init(sqlite3 *db, char *col_name, char *rgx, sqlite3_stmt **ret) +database_search_queue_init(sqlite3 *db, char *col_name, char *rgx, struct lkt_search *ret) { if (ret == NULL) { fprintf(stderr, " ! database_search_init: Exit because return pointer is NULL\n"); @@ -25,24 +25,23 @@ database_search_queue_init(sqlite3 *db, char *col_name, char *rgx, sqlite3_stmt snprintf(SQL_STMT, LKT_MAX_SQLITE_STATEMENT - 1, SQL_STMT_TEMPLATE, col_name); SQL_STMT[LKT_MAX_SQLITE_STATEMENT - 1] = 0; - SQLITE_PREPARE(db, *ret, SQL_STMT, error); - SQLITE_BIND_TEXT(db, *ret, 1, rgx, error); + SQLITE_PREPARE(db, ret->stmt, SQL_STMT, error); + SQLITE_BIND_TEXT(db, ret->stmt, 1, rgx, error); + ret->db = db; + /* Assign the callback. */ return true; error: - sqlite3_finalize(*ret); - *ret = NULL; + sqlite3_finalize(ret->stmt); return false; } bool -database_search_iter(sqlite3 *db, sqlite3_stmt *item, struct lkt_callback *callback, - bool *need_free) +database_search_iter(struct lkt_search *item) { const char *sql_row; int id, code, id_len; - *need_free = true; - code = sqlite3_step(item); + code = sqlite3_step(item->stmt); if (item == NULL) { fprintf(stderr, " * database_search_iter: Exit function because the sqlite3_stmt* is NULL\n"); @@ -52,16 +51,24 @@ database_search_iter(sqlite3 *db, sqlite3_stmt *item, struct lkt_callback *callb if (code == SQLITE_DONE) goto error_or_done; - if (code == SQLITE_ROW) { - id = sqlite3_column_int(item, 0); - sql_row = (const char *) sqlite3_column_text(item, 1); - id_len = sqlite3_column_int(item, 2); - return callback->call(callback, id, id_len, sql_row); + if (code != SQLITE_ROW) + goto error; + + switch (item->type) { + case lkt_search_database: + id = sqlite3_column_int(item->stmt, 0); + sql_row = (const char *) sqlite3_column_text(item->stmt, 1); + id_len = sqlite3_column_int(item->stmt, 2); + return ((lkt_search_database_func) item->call)(item->srv, item->c, id, id_len, sql_row); + case lkt_search_queue: + case lkt_search_playlist: + default: + goto error; } - fprintf(stderr, " ! database_search_iter: sqlite3_step failed: %s\n", sqlite3_errmsg(db)); +error: + fprintf(stderr, " ! database_search_iter: sqlite3_step failed: %s\n", sqlite3_errmsg(item->db)); error_or_done: - sqlite3_finalize(item); - *need_free = false; + sqlite3_finalize(item->stmt); return false; }