Missing declarations
[oweals/gnunet.git] / src / mysql / mysql.c
index 0fc98308c0622d2dec47e3258d1504bb006fa7f6..098213b3358a40787ece6227d2e175bd7e859128 100644 (file)
  */
 struct GNUNET_MYSQL_Context
 {
-  
+
   /**
    * Our configuration.
    */
   const struct GNUNET_CONFIGURATION_Handle *cfg;
-  
+
   /**
    * Our section.
    */
@@ -125,11 +125,12 @@ struct GNUNET_MYSQL_StatementHandle
  * Obtain the location of ".my.cnf".
  *
  * @param cfg our configuration
+ * @param section the section
  * @return NULL on error
  */
 static char *
 get_my_cnf_path (const struct GNUNET_CONFIGURATION_Handle *cfg,
-                const char *section)
+                 const char *section)
 {
   char *cnffile;
   char *home_dir;
@@ -147,12 +148,10 @@ get_my_cnf_path (const struct GNUNET_CONFIGURATION_Handle *cfg,
     GNUNET_log_from_strerror (GNUNET_ERROR_TYPE_ERROR, "mysql", "getpwuid");
     return NULL;
   }
-  if (GNUNET_YES ==
-      GNUNET_CONFIGURATION_have_value (cfg, section, "CONFIG"))
+  if (GNUNET_YES == GNUNET_CONFIGURATION_have_value (cfg, section, "CONFIG"))
   {
     GNUNET_assert (GNUNET_OK ==
-                   GNUNET_CONFIGURATION_get_value_filename (cfg,
-                                                            section,
+                   GNUNET_CONFIGURATION_get_value_filename (cfg, section,
                                                             "CONFIG",
                                                             &cnffile));
     configured = GNUNET_YES;
@@ -171,17 +170,16 @@ get_my_cnf_path (const struct GNUNET_CONFIGURATION_Handle *cfg,
   GNUNET_free (home_dir);
   configured = GNUNET_NO;
 #endif
-  GNUNET_log_from (GNUNET_ERROR_TYPE_INFO,
-                  "mysql",
-                  _("Trying to use file `%s' for MySQL configuration.\n"), cnffile);
+  GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "mysql",
+                   _("Trying to use file `%s' for MySQL configuration.\n"),
+                   cnffile);
   if ((0 != STAT (cnffile, &st)) || (0 != ACCESS (cnffile, R_OK)) ||
       (!S_ISREG (st.st_mode)))
   {
     if (configured == GNUNET_YES)
-      GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
-                      "mysql",
-                      _("Could not access file `%s': %s\n"), cnffile,
-                      STRERROR (errno));
+      GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "mysql",
+                       _("Could not access file `%s': %s\n"), cnffile,
+                       STRERROR (errno));
     GNUNET_free (cnffile);
     return NULL;
   }
@@ -222,55 +220,45 @@ iopen (struct GNUNET_MYSQL_Context *mc)
   mysql_options (mc->dbf, MYSQL_OPT_WRITE_TIMEOUT, (const void *) &timeout);
   mysql_dbname = NULL;
   if (GNUNET_YES ==
-      GNUNET_CONFIGURATION_have_value (mc->cfg, mc->section,
-                                       "DATABASE"))
+      GNUNET_CONFIGURATION_have_value (mc->cfg, mc->section, "DATABASE"))
     GNUNET_assert (GNUNET_OK ==
-                   GNUNET_CONFIGURATION_get_value_string (mc->cfg,
-                                                          mc->section,
+                   GNUNET_CONFIGURATION_get_value_string (mc->cfg, mc->section,
                                                           "DATABASE",
                                                           &mysql_dbname));
   else
     mysql_dbname = GNUNET_strdup ("gnunet");
   mysql_user = NULL;
   if (GNUNET_YES ==
-      GNUNET_CONFIGURATION_have_value (mc->cfg, mc->section,
-                                       "USER"))
+      GNUNET_CONFIGURATION_have_value (mc->cfg, mc->section, "USER"))
   {
     GNUNET_assert (GNUNET_OK ==
-                   GNUNET_CONFIGURATION_get_value_string (mc->cfg,
-                                                          mc->section,
+                   GNUNET_CONFIGURATION_get_value_string (mc->cfg, mc->section,
                                                           "USER", &mysql_user));
   }
   mysql_password = NULL;
   if (GNUNET_YES ==
-      GNUNET_CONFIGURATION_have_value (mc->cfg, mc->section,
-                                       "PASSWORD"))
+      GNUNET_CONFIGURATION_have_value (mc->cfg, mc->section, "PASSWORD"))
   {
     GNUNET_assert (GNUNET_OK ==
-                   GNUNET_CONFIGURATION_get_value_string (mc->cfg,
-                                                          mc->section,
+                   GNUNET_CONFIGURATION_get_value_string (mc->cfg, mc->section,
                                                           "PASSWORD",
                                                           &mysql_password));
   }
   mysql_server = NULL;
   if (GNUNET_YES ==
-      GNUNET_CONFIGURATION_have_value (mc->cfg, mc->section,
-                                       "HOST"))
+      GNUNET_CONFIGURATION_have_value (mc->cfg, mc->section, "HOST"))
   {
     GNUNET_assert (GNUNET_OK ==
-                   GNUNET_CONFIGURATION_get_value_string (mc->cfg,
-                                                          mc->section,
+                   GNUNET_CONFIGURATION_get_value_string (mc->cfg, mc->section,
                                                           "HOST",
                                                           &mysql_server));
   }
   mysql_port = 0;
   if (GNUNET_YES ==
-      GNUNET_CONFIGURATION_have_value (mc->cfg, mc->section,
-                                       "PORT"))
+      GNUNET_CONFIGURATION_have_value (mc->cfg, mc->section, "PORT"))
   {
     GNUNET_assert (GNUNET_OK ==
-                   GNUNET_CONFIGURATION_get_value_number (mc->cfg,
-                                                          mc->section,
+                   GNUNET_CONFIGURATION_get_value_number (mc->cfg, mc->section,
                                                           "PORT", &mysql_port));
   }
 
@@ -300,7 +288,7 @@ iopen (struct GNUNET_MYSQL_Context *mc)
  */
 struct GNUNET_MYSQL_Context *
 GNUNET_MYSQL_context_create (const struct GNUNET_CONFIGURATION_Handle *cfg,
-                            const char *section)
+                             const char *section)
 {
   struct GNUNET_MYSQL_Context *mc;
 
@@ -308,19 +296,19 @@ GNUNET_MYSQL_context_create (const struct GNUNET_CONFIGURATION_Handle *cfg,
   mc->cfg = cfg;
   mc->section = section;
   mc->cnffile = get_my_cnf_path (cfg, section);
-  
+
   return mc;
 }
 
 
 /**
  * Close database connection and all prepared statements (we got a DB
- * disconnect error).
+ * error).
  *
  * @param mc mysql context
  */
-static void
-iclose (struct GNUNET_MYSQL_Context *mc)
+void
+GNUNET_MYSQL_statements_invalidate (struct GNUNET_MYSQL_Context *mc)
 {
   struct GNUNET_MYSQL_StatementHandle *sh;
 
@@ -343,7 +331,7 @@ iclose (struct GNUNET_MYSQL_Context *mc)
 
 /**
  * Destroy a mysql context.  Also frees all associated prepared statements.
- * 
+ *
  * @param mc context to destroy
  */
 void
@@ -351,7 +339,7 @@ GNUNET_MYSQL_context_destroy (struct GNUNET_MYSQL_Context *mc)
 {
   struct GNUNET_MYSQL_StatementHandle *sh;
 
-  iclose (mc);
+  GNUNET_MYSQL_statements_invalidate (mc);
   while (NULL != (sh = mc->shead))
   {
     GNUNET_CONTAINER_DLL_remove (mc->shead, mc->stail, sh);
@@ -359,6 +347,7 @@ GNUNET_MYSQL_context_destroy (struct GNUNET_MYSQL_Context *mc)
     GNUNET_free (sh);
   }
   GNUNET_free (mc);
+  mysql_library_end ();
 }
 
 
@@ -372,7 +361,7 @@ GNUNET_MYSQL_context_destroy (struct GNUNET_MYSQL_Context *mc)
  */
 struct GNUNET_MYSQL_StatementHandle *
 GNUNET_MYSQL_statement_prepare (struct GNUNET_MYSQL_Context *mc,
-                               const char *query)
+                                const char *query)
 {
   struct GNUNET_MYSQL_StatementHandle *sh;
 
@@ -392,8 +381,7 @@ GNUNET_MYSQL_statement_prepare (struct GNUNET_MYSQL_Context *mc,
  *         GNUNET_SYSERR if there was a problem
  */
 int
-GNUNET_MYSQL_statement_run (struct GNUNET_MYSQL_Context *mc,
-                           const char *sql)
+GNUNET_MYSQL_statement_run (struct GNUNET_MYSQL_Context *mc, const char *sql)
 {
   if ((NULL == mc->dbf) && (GNUNET_OK != iopen (mc)))
     return GNUNET_SYSERR;
@@ -401,7 +389,7 @@ GNUNET_MYSQL_statement_run (struct GNUNET_MYSQL_Context *mc,
   if (mysql_error (mc->dbf)[0])
   {
     LOG_MYSQL (GNUNET_ERROR_TYPE_ERROR, "mysql_query", mc);
-    iclose (mc);
+    GNUNET_MYSQL_statements_invalidate (mc);
     return GNUNET_SYSERR;
   }
   return GNUNET_OK;
@@ -426,7 +414,7 @@ prepare_statement (struct GNUNET_MYSQL_Context *mc,
   sh->statement = mysql_stmt_init (mc->dbf);
   if (NULL == sh->statement)
   {
-    iclose (mc);
+    GNUNET_MYSQL_statements_invalidate (mc);
     return GNUNET_SYSERR;
   }
   if (0 != mysql_stmt_prepare (sh->statement, sh->query, strlen (sh->query)))
@@ -434,7 +422,7 @@ prepare_statement (struct GNUNET_MYSQL_Context *mc,
     LOG_MYSQL (GNUNET_ERROR_TYPE_ERROR, "mysql_stmt_prepare", mc);
     mysql_stmt_close (sh->statement);
     sh->statement = NULL;
-    iclose (mc);
+    GNUNET_MYSQL_statements_invalidate (mc);
     return GNUNET_SYSERR;
   }
   sh->valid = GNUNET_YES;
@@ -442,6 +430,24 @@ prepare_statement (struct GNUNET_MYSQL_Context *mc,
 }
 
 
+/**
+ * Get internal handle for a prepared statement.  This function should rarely
+ * be used, and if, with caution!  On failures during the interaction with
+ * the handle, you must call 'GNUNET_MYSQL_statements_invalidate'!
+ *
+ * @param mc mysql context
+ * @param sh prepared statement to introspect
+ * @return MySQL statement handle, NULL on error
+ */
+MYSQL_STMT *
+GNUNET_MYSQL_statement_get_stmt (struct GNUNET_MYSQL_Context * mc,
+                                 struct GNUNET_MYSQL_StatementHandle * sh)
+{
+  (void) prepare_statement (mc, sh);
+  return sh->statement;
+}
+
+
 /**
  * Bind the parameters for the given MySQL statement
  * and run it.
@@ -452,9 +458,8 @@ prepare_statement (struct GNUNET_MYSQL_Context *mc,
  * @return GNUNET_SYSERR on error, GNUNET_OK on success
  */
 static int
-init_params (struct GNUNET_MYSQL_Context *mc, 
-            struct GNUNET_MYSQL_StatementHandle *sh,
-             va_list ap)
+init_params (struct GNUNET_MYSQL_Context *mc,
+             struct GNUNET_MYSQL_StatementHandle *sh, va_list ap)
 {
   MYSQL_BIND qbind[MAX_PARAM];
   unsigned int pc;
@@ -513,112 +518,145 @@ init_params (struct GNUNET_MYSQL_Context *mc,
   }
   if (mysql_stmt_bind_param (sh->statement, qbind))
   {
-    GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
-                    "mysql",
-                    _("`%s' failed at %s:%d with error: %s\n"),
-                    "mysql_stmt_bind_param", __FILE__, __LINE__,
-                    mysql_stmt_error (sh->statement));
-    iclose (mc);
+    GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "mysql",
+                     _("`%s' failed at %s:%d with error: %s\n"),
+                     "mysql_stmt_bind_param", __FILE__, __LINE__,
+                     mysql_stmt_error (sh->statement));
+    GNUNET_MYSQL_statements_invalidate (mc);
     return GNUNET_SYSERR;
   }
   if (mysql_stmt_execute (sh->statement))
   {
-    GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
-                    "mysql",
-                    _("`%s' failed at %s:%d with error: %s\n"),
-                    "mysql_stmt_execute", __FILE__, __LINE__,
-                    mysql_stmt_error (sh->statement));
-    iclose (mc);
+    GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "mysql",
+                     _("`%s' failed at %s:%d with error: %s\n"),
+                     "mysql_stmt_execute", __FILE__, __LINE__,
+                     mysql_stmt_error (sh->statement));
+    GNUNET_MYSQL_statements_invalidate (mc);
     return GNUNET_SYSERR;
   }
   return GNUNET_OK;
 }
 
 
+
 /**
  * Run a prepared SELECT statement.
  *
  * @param mc mysql context
- * @param sh handle to SELECT statment
+ * @param s statement to run
  * @param result_size number of elements in results array
  * @param results pointer to already initialized MYSQL_BIND
  *        array (of sufficient size) for passing results
  * @param processor function to call on each result
  * @param processor_cls extra argument to processor
- * @param ... pairs and triplets of "MYSQL_TYPE_XXX" keys and their respective
+ * @param ap pairs and triplets of "MYSQL_TYPE_XXX" keys and their respective
  *        values (size + buffer-reference for pointers); terminated
  *        with "-1"
  * @return GNUNET_SYSERR on error, otherwise
  *         the number of successfully affected (or queried) rows
  */
 int
-GNUNET_MYSQL_statement_run_prepared_select (struct GNUNET_MYSQL_Context *mc,
-                                           struct GNUNET_MYSQL_StatementHandle *sh,
-                                           unsigned int result_size, MYSQL_BIND * results,
-                                           GNUNET_MYSQL_DataProcessor processor,
-                                           void *processor_cls, ...)
+GNUNET_MYSQL_statement_run_prepared_select_va (struct GNUNET_MYSQL_Context *mc,
+                                               struct
+                                               GNUNET_MYSQL_StatementHandle *s,
+                                               unsigned int result_size,
+                                               MYSQL_BIND * results,
+                                               GNUNET_MYSQL_DataProcessor
+                                               processor, void *processor_cls,
+                                               va_list ap)
 {
-  va_list ap;
   int ret;
   unsigned int rsize;
   int total;
 
-  if (GNUNET_OK != prepare_statement (mc, sh))
+  if (GNUNET_OK != prepare_statement (mc, s))
   {
     GNUNET_break (0);
     return GNUNET_SYSERR;
   }
-  va_start (ap, processor_cls);
-  if (GNUNET_OK != init_params (mc, sh, ap))
+  if (GNUNET_OK != init_params (mc, s, ap))
   {
     GNUNET_break (0);
-    va_end (ap);
     return GNUNET_SYSERR;
   }
-  va_end (ap);
-  rsize = mysql_stmt_field_count (sh->statement);
+  rsize = mysql_stmt_field_count (s->statement);
   if (rsize > result_size)
   {
     GNUNET_break (0);
     return GNUNET_SYSERR;
   }
-  if (mysql_stmt_bind_result (sh->statement, results))
+  if (mysql_stmt_bind_result (s->statement, results))
   {
-    GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
-                    "mysql",
-                    _("`%s' failed at %s:%d with error: %s\n"),
-                    "mysql_stmt_bind_result", __FILE__, __LINE__,
-                    mysql_stmt_error (sh->statement));
-    iclose (mc);
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                _("`%s' failed at %s:%d with error: %s\n"),
+                "mysql_stmt_bind_result", __FILE__, __LINE__,
+                mysql_stmt_error (s->statement));
+    GNUNET_MYSQL_statements_invalidate (mc);
     return GNUNET_SYSERR;
   }
 
   total = 0;
   while (1)
   {
-    ret = mysql_stmt_fetch (sh->statement);
+    ret = mysql_stmt_fetch (s->statement);
     if (ret == MYSQL_NO_DATA)
       break;
     if (ret != 0)
     {
-      GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
-                      "mysql",
-                      _("`%s' failed at %s:%d with error: %s\n"),
-                      "mysql_stmt_fetch", __FILE__, __LINE__,
-                      mysql_stmt_error (sh->statement));
-      iclose (mc);
+      GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "mysql",
+                       _("`%s' failed at %s:%d with error: %s\n"),
+                       "mysql_stmt_fetch", __FILE__, __LINE__,
+                       mysql_stmt_error (s->statement));
+      GNUNET_MYSQL_statements_invalidate (mc);
       return GNUNET_SYSERR;
     }
-    if (processor != NULL)
-      if (GNUNET_OK != processor (processor_cls, rsize, results))
-        break;
     total++;
+    if ((NULL == processor) ||
+        (GNUNET_OK != processor (processor_cls, rsize, results)))
+      break;
   }
-  mysql_stmt_reset (sh->statement);
+  mysql_stmt_reset (s->statement);
   return total;
 }
 
 
+/**
+ * Run a prepared SELECT statement.
+ *
+ * @param mc mysql context
+ * @param sh handle to SELECT statment
+ * @param result_size number of elements in results array
+ * @param results pointer to already initialized MYSQL_BIND
+ *        array (of sufficient size) for passing results
+ * @param processor function to call on each result
+ * @param processor_cls extra argument to processor
+ * @param ... pairs and triplets of "MYSQL_TYPE_XXX" keys and their respective
+ *        values (size + buffer-reference for pointers); terminated
+ *        with "-1"
+ * @return GNUNET_SYSERR on error, otherwise
+ *         the number of successfully affected (or queried) rows
+ */
+int
+GNUNET_MYSQL_statement_run_prepared_select (struct GNUNET_MYSQL_Context *mc,
+                                            struct GNUNET_MYSQL_StatementHandle
+                                            *sh, unsigned int result_size,
+                                            MYSQL_BIND * results,
+                                            GNUNET_MYSQL_DataProcessor
+                                            processor, void *processor_cls, ...)
+{
+  va_list ap;
+  int ret;
+
+  va_start (ap, processor_cls);
+  ret =
+      GNUNET_MYSQL_statement_run_prepared_select_va (mc, sh, result_size,
+                                                     results, processor,
+                                                     processor_cls, ap);
+  va_end (ap);
+  return ret;
+}
+
+
 /**
  * Run a prepared statement that does NOT produce results.
  *
@@ -634,8 +672,8 @@ GNUNET_MYSQL_statement_run_prepared_select (struct GNUNET_MYSQL_Context *mc,
  */
 int
 GNUNET_MYSQL_statement_run_prepared (struct GNUNET_MYSQL_Context *mc,
-                                    struct GNUNET_MYSQL_StatementHandle *sh,
-                                    unsigned long long *insert_id, ...)
+                                     struct GNUNET_MYSQL_StatementHandle *sh,
+                                     unsigned long long *insert_id, ...)
 {
   va_list ap;
   int affected;
@@ -658,4 +696,3 @@ GNUNET_MYSQL_statement_run_prepared (struct GNUNET_MYSQL_Context *mc,
 
 
 /* end of mysql.c */
-