diff options
Diffstat (limited to 'query.c')
-rw-r--r-- | query.c | 155 |
1 files changed, 155 insertions, 0 deletions
@@ -0,0 +1,155 @@ +/* + * Created by yuuta on 4/1/22. + */ + +#include "tdutils.h" +#include "logic.h" +#include "log.h" +#include "db.h" + +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <assert.h> + +struct result { + char id[10]; + /* Title in selection */ + char *title; + /* Description in selection */ + char *description; + /* Text after sending */ + char *text; + char *url; +}; + +static void cb_answer(bool successful, struct TdObject *result, struct TdError *error, void *cb_arg) { + if (!successful) { + LOGEV("Cannot answer inline request: %s.", + error ? error->message_ : "(NULL)"); + } +} + +int handle_inline(struct TdUpdateNewInlineQuery *update) { + struct result results[10]; + memset(results, 0, sizeof(results)); + sqlite3_stmt *stmt; + int r; + if ((r = sqlite3_prepare_v2(db, + "SELECT id, t, url FROM says ORDER BY RANDOM() LIMIT 10;", + -1, + &stmt, + NULL))) { + goto sql_err; + sql_err: + snprintf(results[0].id, 10, "e%d", r); + char *msg = (char *) sqlite3_errstr(r); + LOGEV("Cannot query: %s.", msg); + results[0].title = "Error!"; + results[0].text = msg; + results[0].description = msg; + goto answer; + } + + int j = 0; + goto step; + step: + switch (r = sqlite3_step(stmt)) { + case SQLITE_ROW: { + char *t = (char *) sqlite3_column_text(stmt, 1); + char *url = (char *) sqlite3_column_text(stmt, 3); + + char *url1 = NULL; + char *title = NULL; + char *t1 = NULL; + + if (url && !(url1 = strdup(url))) { + LOGEV("Cannot allocate memory: %s.", strerror(errno)); + break; + } + if (!(title = strdup(t))) { + LOGEV("Cannot allocate memory: %s.", strerror(errno)); + break; + } + if (!(t1 = strdup(t))) { + LOGEV("Cannot allocate memory: %s.", strerror(errno)); + break; + } + results[j].title = title; + snprintf(results[j].id, 10, "%d", sqlite3_column_int(stmt, 0)); + results[j].text = t1; + results[j].url = url1; + results[j].description = url1; + if ((++j) > 9) break; + goto step; + } + case SQLITE_DONE: { + break; + } + default: { + goto sql_err; + } + } + + sqlite3_finalize(stmt); + + if (!j) { + results[0].title = "No data"; + results[0].description = "No data is available. Check it out later."; + sprintf(results[0].id, "e_nodat"); + results[0].text = "No data is available. Check it out later.\n\n" + "https://www.youtube.com/watch?v=dQw4w9WgXcQ"; + } + assert(results[0].title); + goto answer; + answer: + { + struct TdInputInlineQueryResultArticle *results_inline[10]; /* No need to memset(). Var 'i' will assure that. */ + int i; + for (i = 0; i < sizeof(results) / sizeof(struct result); i++) { + struct result res = results[i]; + if (!res.title) { + break; + } + results_inline[i] = TdCreateObjectInputInlineQueryResultArticle( + res.id, + NULL, + false, + res.title, + res.description, + NULL, + 0, + 0, + NULL, + (struct TdInputMessageContent *) TdCreateObjectInputMessageText( + TdCreateObjectFormattedText(res.text, + (struct TdVectorTextEntity *) TdCreateObjectVectorObject(0, + NULL)), + true, + false + )); + } + td_send(TdCreateObjectAnswerInlineQuery(update->id_, + false, + (struct TdVectorInputInlineQueryResult *) + TdCreateObjectVectorObject(i, + (struct TdObject **) results_inline), + 0, + NULL, + NULL, + NULL), + &cb_answer, + NULL); + for (i = 0; i < sizeof(results) / sizeof(struct result); i++) { + struct result res = results[i]; + if (!res.title) { + break; + } + free(res.title); + if (res.url) free(res.url); + free(res.text); + } + return r; + } +} |