/** * Prepare a statement for running. * * @param mc mysql context * @param sh statement handle to prepare * @return #GNUNET_OK on success */ static int prepare_statement (struct GNUNET_MYSQL_StatementHandle *sh) { struct GNUNET_MYSQL_Context *mc = sh->mc; if (GNUNET_YES == sh->valid) return GNUNET_OK; if ((NULL == mc->dbf) && (GNUNET_OK != iopen (mc))) return GNUNET_SYSERR; sh->statement = mysql_stmt_init (mc->dbf); if (NULL == sh->statement) { GNUNET_MYSQL_statements_invalidate (mc); return GNUNET_SYSERR; } if (0 != mysql_stmt_prepare (sh->statement, sh->query, strlen (sh->query))) { GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "mysql", "prepare_statement: %s\n", sh->query); LOG_MYSQL (GNUNET_ERROR_TYPE_ERROR, "mysql_stmt_prepare", mc); mysql_stmt_close (sh->statement); sh->statement = NULL; GNUNET_MYSQL_statements_invalidate (mc); return GNUNET_SYSERR; } sh->valid = GNUNET_YES; return GNUNET_OK; }
/** * Destroy a mysql context. Also frees all associated prepared statements. * * @param mc context to destroy */ void GNUNET_MYSQL_context_destroy (struct GNUNET_MYSQL_Context *mc) { struct GNUNET_MYSQL_StatementHandle *sh; GNUNET_MYSQL_statements_invalidate (mc); while (NULL != (sh = mc->shead)) { GNUNET_CONTAINER_DLL_remove (mc->shead, mc->stail, sh); GNUNET_free (sh->query); GNUNET_free (sh); } GNUNET_free (mc); mysql_library_end (); }
/** * Run a SQL statement. * * @param mc mysql context * @param sql SQL statement to run * @return #GNUNET_OK on success * #GNUNET_SYSERR if there was a problem */ int GNUNET_MYSQL_statement_run (struct GNUNET_MYSQL_Context *mc, const char *sql) { if ( (NULL == mc->dbf) && (GNUNET_OK != iopen (mc)) ) return GNUNET_SYSERR; mysql_query (mc->dbf, sql); if (mysql_error (mc->dbf)[0]) { LOG_MYSQL (GNUNET_ERROR_TYPE_ERROR, "mysql_query", mc); GNUNET_MYSQL_statements_invalidate (mc); return GNUNET_SYSERR; } return GNUNET_OK; }
/** * Get all of the keys in the datastore. * * @param cls closure * @param proc function to call on each key * @param proc_cls closure for proc */ static void mysql_plugin_get_keys (void *cls, PluginKeyProcessor proc, void *proc_cls) { struct Plugin *plugin = cls; const char *query = "SELECT hash FROM gn090"; int ret; MYSQL_STMT *statement; struct GNUNET_HashCode key; MYSQL_BIND cbind[1]; unsigned long length; statement = GNUNET_MYSQL_statement_get_stmt (plugin->mc, plugin->get_all_keys); if (statement == NULL) { GNUNET_MYSQL_statements_invalidate (plugin->mc); return; } if (mysql_stmt_prepare (statement, query, strlen (query))) { GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "mysql", _("Failed to prepare statement `%s'\n"), query); GNUNET_MYSQL_statements_invalidate (plugin->mc); return; } GNUNET_assert (proc != NULL); if (mysql_stmt_execute (statement)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("`%s' for `%s' failed at %s:%d with error: %s\n"), "mysql_stmt_execute", query, __FILE__, __LINE__, mysql_stmt_error (statement)); GNUNET_MYSQL_statements_invalidate (plugin->mc); return; } memset (cbind, 0, sizeof (cbind)); cbind[0].buffer_type = MYSQL_TYPE_BLOB; cbind[0].buffer = &key; cbind[0].buffer_length = sizeof (key); cbind[0].length = &length; cbind[0].is_unsigned = GNUNET_NO; if (mysql_stmt_bind_result (statement, cbind)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("`%s' failed at %s:%d with error: %s\n"), "mysql_stmt_bind_result", __FILE__, __LINE__, mysql_stmt_error (statement)); GNUNET_MYSQL_statements_invalidate (plugin->mc); return; } while (0 == (ret = mysql_stmt_fetch (statement))) { if (sizeof (struct GNUNET_HashCode) == length) proc (proc_cls, &key, 1); } if (ret != MYSQL_NO_DATA) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("`%s' failed at %s:%d with error: %s\n"), "mysql_stmt_fetch", __FILE__, __LINE__, mysql_stmt_error (statement)); GNUNET_MYSQL_statements_invalidate (plugin->mc); return; } mysql_stmt_reset (statement); }