[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r7818 - GNUnet/src/libs/mysql
From: |
gnunet |
Subject: |
[GNUnet-SVN] r7818 - GNUnet/src/libs/mysql |
Date: |
Sun, 2 Nov 2008 02:10:51 -0700 (MST) |
Author: grothoff
Date: 2008-11-02 02:10:51 -0700 (Sun, 02 Nov 2008)
New Revision: 7818
Modified:
GNUnet/src/libs/mysql/lmysql.c
Log:
more hacking on mysql lib
Modified: GNUnet/src/libs/mysql/lmysql.c
===================================================================
--- GNUnet/src/libs/mysql/lmysql.c 2008-11-02 01:29:20 UTC (rev 7817)
+++ GNUnet/src/libs/mysql/lmysql.c 2008-11-02 09:10:51 UTC (rev 7818)
@@ -107,6 +107,8 @@
#define DEBUG_TIME_MYSQL GNUNET_NO
+#define MAX_PARAM 16
+
/**
* Die with an error message that indicates
* a failure of the command 'cmd' with the message given
@@ -119,7 +121,7 @@
* a failure of the command 'cmd' on file 'filename'
* with the message given by strerror(errno).
*/
-#define LOG_MYSQL(level, cmd, dbh) do { GNUNET_GE_LOG(ectx, level, _("`%s'
failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__,
mysql_error((dbh)->dbf)); } while(0);
+#define LOG_MYSQL(level, cmd, dbh) do { GNUNET_GE_LOG((dbh)->ectx, level,
_("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__,
mysql_error((dbh)->dbf)); } while(0);
struct GNUNET_MysqlStatementHandle
{
@@ -254,41 +256,16 @@
return GNUNET_OK;
}
-/**
- * Open a connection with MySQL (the connection maybe
- * internally be shared between clients of this library).
- *
- * @return NULL on error
- */
-struct GNUNET_MysqlDatabaseHandle *
-GNUNET_MYSQL_database_open(struct GNUNET_GE_Context * ectx,
- struct GNUNET_GC_Configuration * cfg)
+static int
+iopen(struct GNUNET_MysqlDatabaseHandle * ret)
{
- struct GNUNET_MysqlDatabaseHandle * ret;
char *dbname;
my_bool reconnect = 0;
unsigned int timeout = 60; /* in seconds */
-
- GNUNET_mutex_lock(lock);
- ret = GNUNET_malloc(sizeof(struct GNUNET_MysqlDatabaseHandle));
- memset(ret, 0, sizeof(struct GNUNET_MysqlDatabaseHandle));
+
ret->dbf = mysql_init (NULL);
if (ret->dbf == NULL)
- {
- GNUNET_free(ret);
- GNUNET_mutex_unlock(lock);
- return NULL;
- }
- ret->ectx = ectx;
- ret->cfg = cfg;
- ret->cnffile = get_my_cnf_path(ectx, cfg);
- if (ret->cnffile == NULL)
- {
- mysql_close (ret->dbf);
- GNUNET_free(ret);
- GNUNET_mutex_unlock(lock);
- return NULL;
- }
+ return GNUNET_SYSERR;
mysql_options (ret->dbf, MYSQL_READ_DEFAULT_FILE, ret->cnffile);
mysql_options (ret->dbf, MYSQL_READ_DEFAULT_GROUP, "client");
mysql_options (ret->dbf, MYSQL_OPT_RECONNECT, &reconnect);
@@ -296,22 +273,51 @@
MYSQL_OPT_CONNECT_TIMEOUT, (const void *) &timeout);
mysql_options (ret->dbf, MYSQL_OPT_READ_TIMEOUT, (const void *) &timeout);
mysql_options (ret->dbf, MYSQL_OPT_WRITE_TIMEOUT, (const void *) &timeout);
-
dbname = NULL;
- GNUNET_GC_get_configuration_value_string (cfg,
+ GNUNET_GC_get_configuration_value_string (ret->cfg,
"MYSQL", "DATABASE", "gnunet",
&dbname);
- GNUNET_GE_ASSERT (ectx, dbname != NULL);
+ GNUNET_GE_ASSERT (ret->ectx, dbname != NULL);
mysql_real_connect (ret->dbf, NULL, NULL, NULL, dbname, 0, NULL, 0);
GNUNET_free (dbname);
if (mysql_error (ret->dbf)[0])
{
LOG_MYSQL (GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_BULK,
"mysql_real_connect", ret);
- mysql_close (ret->dbf);
- GNUNET_free(ret->cnffile);
- GNUNET_free(ret);
GNUNET_mutex_unlock(lock);
+ return GNUNET_SYSERR;
+ }
+ ret->valid = GNUNET_YES;
+ return GNUNET_OK;
+}
+
+/**
+ * Open a connection with MySQL (the connection maybe
+ * internally be shared between clients of this library).
+ *
+ * @return NULL on error
+ */
+struct GNUNET_MysqlDatabaseHandle *
+GNUNET_MYSQL_database_open(struct GNUNET_GE_Context * ectx,
+ struct GNUNET_GC_Configuration * cfg)
+{
+ struct GNUNET_MysqlDatabaseHandle * ret;
+
+ GNUNET_mutex_lock(lock);
+ ret = GNUNET_malloc(sizeof(struct GNUNET_MysqlDatabaseHandle));
+ memset(ret, 0, sizeof(struct GNUNET_MysqlDatabaseHandle));
+ ret->ectx = ectx;
+ ret->cfg = cfg;
+ ret->cnffile = get_my_cnf_path(ectx, cfg);
+ if ( (ret->cnffile == NULL) ||
+ (GNUNET_OK != iopen(ret)) )
+ {
+ if (ret->dbf != NULL)
+ mysql_close (ret->dbf);
+ GNUNET_free_non_null(ret->cnffile);
+ GNUNET_free(ret);
+ iclose();
+ GNUNET_mutex_unlock(lock);
return NULL;
}
ret->next = dbs;
@@ -344,8 +350,11 @@
}
else
dbs = dbh->next;
- mysql_close (dbh->dbf);
+ if (dbh->dbf != NULL)
+ mysql_close (dbh->dbf);
+ GNUNET_free (dbh->cnffile);
GNUNET_free (dbh);
+ GNUNET_mutex_unlock(lock);
}
/**
@@ -356,7 +365,25 @@
GNUNET_MYSQL_run_statement(struct GNUNET_MysqlDatabaseHandle * dbh,
const char * statement)
{
- return GNUNET_SYSERR;
+ GNUNET_mutex_lock(lock);
+ if ( (! dbh->valid) &&
+ (GNUNET_OK != iopen(dbh)) )
+ {
+ GNUNET_mutex_unlock(lock);
+ return GNUNET_SYSERR;
+ }
+ mysql_query (dbh->dbf,
+ statement);
+ if (mysql_error (dbh->dbf)[0])
+ {
+ LOG_MYSQL (GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_BULK,
+ "mysql_query", dbh);
+ iclose ();
+ GNUNET_mutex_unlock(lock);
+ return GNUNET_SYSERR;
+ }
+ GNUNET_mutex_unlock(lock);
+ return GNUNET_OK;
}
/**
@@ -368,17 +395,163 @@
GNUNET_MYSQL_prepared_statement_create(struct GNUNET_MysqlDatabaseHandle * dbh,
const char * statement)
{
- return NULL;
+ struct GNUNET_MysqlStatementHandle * ret;
+
+ GNUNET_mutex_lock(lock);
+ if ( (! dbh->valid) &&
+ (GNUNET_OK != iopen(dbh)) )
+ {
+ GNUNET_mutex_unlock(lock);
+ return NULL;
+ }
+ ret = GNUNET_malloc(sizeof(struct GNUNET_MysqlStatementHandle));
+ memset(ret, 0, sizeof(struct GNUNET_MysqlStatementHandle));
+ ret->db = dbh;
+ ret->query = GNUNET_strdup(statement);
+ ret->next = dbh->statements;
+ dbh->statements = ret;
+ GNUNET_mutex_unlock(lock);
+ return ret;
}
+static int
+prepare_statement(struct GNUNET_MysqlStatementHandle * ret)
+{
+ if (GNUNET_YES == ret->valid)
+ return GNUNET_OK;
+ if ( (! ret->db->valid) &&
+ (GNUNET_OK != iopen(ret->db)) )
+ return GNUNET_SYSERR;
+ ret->statement = mysql_stmt_init(ret->db->dbf);
+ if (ret->statement == NULL) {
+ iclose();
+ return GNUNET_SYSERR;
+ }
+ if (mysql_stmt_prepare (ret->statement,
+ ret->query,
+ strlen(ret->query)))
+ {
+ GNUNET_GE_LOG (ret->db->ectx,
+ GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
+ _("`%s' failed at %s:%d with error: %s"),
+ "mysql_stmt_prepare",
+ __FILE__, __LINE__,
+ mysql_stmt_error (ret->statement));
+ mysql_stmt_close(ret->statement);
+ ret->statement = NULL;
+ iclose();
+ return GNUNET_SYSERR;
+ }
+ ret->valid = GNUNET_YES;
+ return GNUNET_OK;
+}
+
/**
* Free a prepared statement.
*/
void
GNUNET_MYSQL_prepared_statement_destroy(struct GNUNET_MysqlStatementHandle * s)
{
+ struct GNUNET_MysqlStatementHandle * prev;
+
+ GNUNET_mutex_lock(lock);
+ prev = NULL;
+ if (s != s->db->statements)
+ {
+ prev = s->db->statements;
+ while ( (prev != NULL) &&
+ (prev->next != s) )
+ prev = prev->next;
+ GNUNET_GE_ASSERT(NULL, prev != NULL);
+ prev->next = s->next;
+ }
+ else
+ s->db->statements = s->next;
+ if (s->valid)
+ mysql_stmt_close(s->statement);
+ GNUNET_free(s->query);
+ GNUNET_free(s);
+ GNUNET_mutex_unlock(lock);
}
+static int
+init_params(struct GNUNET_MysqlStatementHandle * s,
+ va_list ap)
+{
+ MYSQL_BIND qbind[MAX_PARAM];
+ unsigned int pc;
+ unsigned int off;
+ enum enum_field_types ft;
+
+ pc = mysql_stmt_param_count (s->statement);
+ if (pc > MAX_PARAM)
+ {
+ /* increase internal constant! */
+ GNUNET_GE_BREAK(NULL, 0);
+ return GNUNET_SYSERR;
+ }
+ memset(qbind, 0, sizeof(qbind));
+ off = 0;
+ ft = 0;
+ while ( (pc > 0) &&
+ (-1 != (ft = va_arg (ap, enum enum_field_types))) )
+ {
+ qbind[off].buffer_type = ft;
+ switch (ft)
+ {
+ case MYSQL_TYPE_LONGLONG:
+ qbind[off].is_unsigned = 1;
+ qbind[off].buffer = va_arg(ap, unsigned long long*);
+ break;
+ case MYSQL_TYPE_LONG:
+ qbind[off].is_unsigned = 1;
+ qbind[off].buffer = va_arg(ap, unsigned int*);
+ break;
+ case MYSQL_TYPE_BLOB:
+ qbind[off].buffer = va_arg(ap, void*);
+ qbind[off].buffer_length = va_arg(ap, unsigned long);
+ qbind[off].length = va_arg(ap, unsigned long*);
+ break;
+ default:
+ /* unsupported type */
+ GNUNET_GE_BREAK(NULL, 0);
+ return GNUNET_SYSERR;
+ }
+ pc--;
+ off++;
+ }
+ if (! ((pc == 0) &&
+ (ft != -1) &&
+ (va_arg(ap, int) == -1)) )
+ {
+ GNUNET_GE_BREAK(NULL, 0);
+ return GNUNET_SYSERR;
+ }
+ if (mysql_stmt_bind_param (s->statement, qbind))
+ {
+ GNUNET_GE_LOG (s->db->ectx,
+ GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
+ _("`%s' failed at %s:%d with error: %s\n"),
+ "mysql_stmt_bind_param",
+ __FILE__, __LINE__,
+ mysql_stmt_error (s->statement));
+ iclose ();
+ return GNUNET_SYSERR;
+ }
+ if (mysql_stmt_execute (s->statement))
+ {
+ GNUNET_GE_LOG (s->db->ectx,
+ GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
+ _("`%s' failed at %s:%d with error: %s\n"),
+ "mysql_stmt_execute",
+ __FILE__, __LINE__,
+ mysql_stmt_error (s->statement));
+ iclose ();
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
+}
+
/**
* Run a prepared SELECT statement.
*
@@ -401,6 +574,25 @@
void * processor_cls,
...)
{
+ va_list ap;
+
+ GNUNET_mutex_lock(lock);
+ if (GNUNET_OK != prepare_statement(s))
+ {
+ GNUNET_mutex_unlock(lock);
+ return GNUNET_SYSERR;
+ }
+ va_start (ap, processor_cls);
+ if (GNUNET_OK != init_params(s, ap))
+ {
+ va_end (ap);
+ GNUNET_mutex_unlock(lock);
+ return GNUNET_SYSERR;
+ }
+ va_end (ap);
+ /* FIXME: get data!!! */
+ mysql_stmt_reset (s->statement);
+ GNUNET_mutex_unlock(lock);
return GNUNET_SYSERR;
}
@@ -418,39 +610,25 @@
GNUNET_MYSQL_prepared_statement_run(struct GNUNET_MysqlStatementHandle * s,
...)
{
- MYSQL_BIND qbind[42];
- unsigned long length = 42;
+ va_list ap;
- memset (qbind, 0, sizeof (qbind));
- qbind[0].buffer_type = MYSQL_TYPE_BLOB;
- qbind[0].buffer = (void *) NULL;
- qbind[0].buffer_length = 42;
- qbind[0].length = &length;
- GNUNET_GE_ASSERT (s->db->ectx, mysql_stmt_param_count (s->statement) == 1);
- if (mysql_stmt_bind_param (s->statement, qbind))
+ GNUNET_mutex_lock(lock);
+ if (GNUNET_OK != prepare_statement(s))
{
- GNUNET_GE_LOG (s->db->ectx,
- GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
- _("`%s' failed at %s:%d with error: %s\n"),
- "mysql_stmt_bind_param",
- __FILE__, __LINE__,
- mysql_stmt_error (s->statement));
- iclose ();
+ GNUNET_mutex_unlock(lock);
return GNUNET_SYSERR;
}
- if (mysql_stmt_execute (s->statement))
+ va_start (ap, s);
+ if (GNUNET_OK != init_params(s, ap))
{
- GNUNET_GE_LOG (s->db->ectx,
- GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
- _("`%s' failed at %s:%d with error: %s\n"),
- "mysql_stmt_execute",
- __FILE__, __LINE__,
- mysql_stmt_error (s->statement));
- iclose ();
- return GNUNET_SYSERR;
+ va_end (ap);
+ GNUNET_mutex_unlock(lock);
+ return GNUNET_SYSERR;
}
- // *vkey = (unsigned long long) mysql_stmt_insert_id (dbh->insert_value);
+ va_end (ap);
+ /* FIXME: get any data?? */
mysql_stmt_reset (s->statement);
+ GNUNET_mutex_unlock(lock);
return GNUNET_OK;
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r7818 - GNUnet/src/libs/mysql,
gnunet <=