aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2010-06-22 11:45:34 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2010-06-22 11:45:34 +0300
commitee18ef999d5cc87cc23455147924f96e7a91d3fa (patch)
tree91a255f8cf6e799f71d59f6ef5795f4f4a5282a2
parentb20b5cf9d52808f6f84971f2851046fb5248bd14 (diff)
downloadsmap-ee18ef999d5cc87cc23455147924f96e7a91d3fa.tar.gz
smap-ee18ef999d5cc87cc23455147924f96e7a91d3fa.tar.bz2
Provide a default MySQL database.
* modules/mysql/mysql.c (mysql_db): Rename to mod_mysql_db. New fields: flags, refcnt. (def_db): New static. (moddb_handle, moddb_positive_reply) (moddb_negative_reply, opendb, closedb) (freedb): New functions. (mod_init): More options. (mod_init_db): New option defaultdb. (mod_free_db): Use freedb (mod_open): Use opendb. (mod_close): Use closedb. (do_query, do_positive_reply, flush_result) (mod_query): Use moddb_* accessors to get pointers to MYSQL structure, positive and negative replies.
-rw-r--r--modules/mysql/mysql.c258
1 files changed, 177 insertions, 81 deletions
diff --git a/modules/mysql/mysql.c b/modules/mysql/mysql.c
index 49331ad..6215872 100644
--- a/modules/mysql/mysql.c
+++ b/modules/mysql/mysql.c
@@ -31,13 +31,13 @@
#include <smap/stream.h>
#include <smap/wordsplit.h>
-static size_t dbgid;
-
-static char *def_positive_reply = "OK";
-static char *def_negative_reply = "NOTFOUND";
-static char *def_onerror_reply = NULL;
+#define MDB_INIT 0x01
+#define MDB_OPEN 0x02
+#define MDB_DEFDB 0x04
-struct mysql_db {
+struct mod_mysql_db {
+ int flags;
+ unsigned refcnt;
MYSQL mysql;
const char *name;
char *config_file;
@@ -55,29 +55,160 @@ struct mysql_db {
char *onerror_reply;
};
-int
+static size_t dbgid;
+static struct mod_mysql_db def_db;
+
+static MYSQL *
+moddb_handle(struct mod_mysql_db *db)
+{
+ if (db->flags & MDB_DEFDB)
+ return &def_db.mysql;
+ return &db->mysql;
+}
+
+static const char *
+moddb_positive_reply(struct mod_mysql_db *db)
+{
+ return db->positive_reply ?
+ db->positive_reply :
+ (def_db.positive_reply ? def_db.positive_reply : "OK");
+}
+
+static const char *
+moddb_negative_reply(struct mod_mysql_db *db)
+{
+ return db->negative_reply ?
+ db->negative_reply :
+ (def_db.negative_reply ? def_db.negative_reply : "NOTFOUND");
+}
+
+static int
+opendb(struct mod_mysql_db *db)
+{
+ if (db->flags & MDB_OPEN) {
+ db->refcnt++;
+ return 0;
+ }
+
+ if (!(db->flags & MDB_INIT)) {
+ smap_error("%s: module settings do not include opendb flag",
+ db->name);
+ return 1;
+ }
+
+ if (!mysql_init(&db->mysql)) {
+ smap_error("%s: not enough memory", db->name);
+ return 1;
+ }
+
+ if (db->config_file)
+ mysql_options(&db->mysql, MYSQL_READ_DEFAULT_FILE,
+ db->config_file);
+ if (db->config_group)
+ mysql_options (&db->mysql, MYSQL_READ_DEFAULT_GROUP,
+ db->config_group);
+
+ if (db->ssl_ca)
+ mysql_ssl_set (&db->mysql, NULL, NULL, db->ssl_ca,
+ NULL, NULL);
+
+ if (!mysql_real_connect(&db->mysql,
+ db->host,
+ db->user,
+ db->password,
+ db->database,
+ db->port,
+ db->socket, CLIENT_MULTI_RESULTS)) {
+ smap_error("%s: failed to connect to database, error: %s",
+ db->name, mysql_error(&db->mysql));
+ mysql_close(&db->mysql);
+ return 1;
+ }
+ db->refcnt++;
+ db->flags |= MDB_OPEN;
+ return 0;
+}
+
+static void
+closedb(struct mod_mysql_db *db)
+{
+ if ((db->flags & MDB_OPEN) && --db->refcnt == 0) {
+ mysql_close(&db->mysql);
+ db->flags &= ~MDB_OPEN;
+ }
+}
+
+static void
+freedb(struct mod_mysql_db *db)
+{
+ free(db->config_file);
+ free(db->config_group);
+ free(db->ssl_ca);
+ free(db->host);
+ free(db->user);
+ free(db->password);
+ free(db->database);
+ free(db->socket);
+ free(db->template);
+ free(db->positive_reply);
+ free(db->negative_reply);
+ free(db->onerror_reply);
+}
+
+static int
mod_init(int argc, char **argv)
{
+ int rc;
+ int opendb = 0;
+
dbgid = smap_debug_alloc("mysql");
- static struct smap_option init_option[] = {
+ struct smap_option init_option[] = {
+ { SMAP_OPTSTR(open), smap_opt_bool,
+ &opendb },
+ { SMAP_OPTSTR(config-file), smap_opt_string,
+ &def_db.config_file },
+ { SMAP_OPTSTR(config-group), smap_opt_string,
+ &def_db.config_group },
+ { SMAP_OPTSTR(ssl-ca), smap_opt_string,
+ &def_db.ssl_ca },
+ { SMAP_OPTSTR(host), smap_opt_string,
+ &def_db.host },
+ { SMAP_OPTSTR(user), smap_opt_string,
+ &def_db.user },
+ { SMAP_OPTSTR(password), smap_opt_string,
+ &def_db.password },
+ { SMAP_OPTSTR(database), smap_opt_string,
+ &def_db.database },
+ { SMAP_OPTSTR(port), smap_opt_long,
+ &def_db.port },
+ { SMAP_OPTSTR(socket), smap_opt_string,
+ &def_db.socket },
+
+ { SMAP_OPTSTR(query), smap_opt_string,
+ &def_db.template },
{ SMAP_OPTSTR(positive-reply), smap_opt_string,
- &def_positive_reply },
+ &def_db.positive_reply },
{ SMAP_OPTSTR(negative-reply), smap_opt_string,
- &def_negative_reply },
+ &def_db.negative_reply },
{ SMAP_OPTSTR(onerror-reply), smap_opt_string,
- &def_onerror_reply },
+ &def_db.onerror_reply },
{ NULL }
};
- return smap_parseopt(init_option, argc, argv, 0, NULL);
+ rc = smap_parseopt(init_option, argc, argv, 0, NULL);
+ if (rc)
+ return rc;
+ if (opendb)
+ def_db.flags = MDB_INIT;
+ return 0;
}
static smap_database_t
mod_init_db(const char *dbid, int argc, char **argv)
{
- struct mysql_db *db;
- char *positive_reply = def_positive_reply;
- char *negative_reply = def_negative_reply;
- char *onerror_reply = def_onerror_reply;
+ struct mod_mysql_db *db;
+ char *positive_reply = NULL;
+ char *negative_reply = NULL;
+ char *onerror_reply = NULL;
char *query = NULL;
char *config_file = NULL;
char *config_group = NULL;
@@ -88,7 +219,10 @@ mod_init_db(const char *dbid, int argc, char **argv)
char *database = NULL;
long port = 0;
char *socket = NULL;
+ int flags = 0;
struct smap_option init_option[] = {
+ { SMAP_OPTSTR(defaultdb), smap_opt_bitmask,
+ &flags, { MDB_DEFDB } },
{ SMAP_OPTSTR(config-file), smap_opt_string,
&config_file },
{ SMAP_OPTSTR(config-group), smap_opt_string,
@@ -122,16 +256,13 @@ mod_init_db(const char *dbid, int argc, char **argv)
if (smap_parseopt(init_option, argc, argv, 0, NULL))
return NULL;
- if (!query) {
- smap_error("%s: query must be specified", dbid);
- return NULL;
- }
-
db = calloc(1, sizeof(*db));
if (!db) {
smap_error("%s: not enough memory", dbid);
return NULL;
}
+
+ db->flags = MDB_INIT | flags;
db->name = dbid;
db->config_file = config_file;
db->config_group = config_group;
@@ -153,21 +284,8 @@ mod_init_db(const char *dbid, int argc, char **argv)
static int
mod_free_db(smap_database_t dbp)
{
- struct mysql_db *db = (struct mysql_db *)dbp;
- free(db->config_file);
- free(db->config_group);
- free(db->ssl_ca);
- free(db->host);
- free(db->user);
- free(db->password);
- free(db->database);
- free(db->socket);
- free(db->template);
- /* FIXME:
- free(db->positive_replyy);
- free(db->negative_reply);
- free(db->onerror_reply);
- */
+ struct mod_mysql_db *db = (struct mod_mysql_db *)dbp;
+ freedb(db);
free(db);
return 0;
}
@@ -175,44 +293,19 @@ mod_free_db(smap_database_t dbp)
static int
mod_open(smap_database_t dbp)
{
- struct mysql_db *db = (struct mysql_db *)dbp;
-
- if (!mysql_init(&db->mysql)) {
- smap_error("%s: not enough memory", db->name);
- return 1;
- }
-
- if (db->config_file)
- mysql_options(&db->mysql, MYSQL_READ_DEFAULT_FILE,
- db->config_file);
- if (db->config_group)
- mysql_options (&db->mysql, MYSQL_READ_DEFAULT_GROUP,
- db->config_group);
-
- if (db->ssl_ca)
- mysql_ssl_set (&db->mysql, NULL, NULL, db->ssl_ca,
- NULL, NULL);
-
- if (!mysql_real_connect(&db->mysql,
- db->host,
- db->user,
- db->password,
- db->database,
- db->port,
- db->socket, CLIENT_MULTI_RESULTS)) {
- smap_error("%s: failed to connect to database, error: %s",
- db->name, mysql_error(&db->mysql));
- mysql_close(&db->mysql);
- return 1;
- }
- return 0;
+ struct mod_mysql_db *db = (struct mod_mysql_db *)dbp;
+ if (db->flags & MDB_DEFDB)
+ return opendb(&def_db);
+ return opendb(db);
}
static int
mod_close(smap_database_t dbp)
{
- struct mysql_db *db = (struct mysql_db *)dbp;
- mysql_close(&db->mysql);
+ struct mod_mysql_db *db = (struct mod_mysql_db *)dbp;
+ if (db->flags & MDB_DEFDB)
+ closedb(&def_db);
+ closedb(db);
return 0;
}
@@ -280,10 +373,11 @@ create_query_env(const char *map, const char *key,
}
int
-do_query(struct mysql_db *db, char **env, MYSQL_RES **pres)
+do_query(struct mod_mysql_db *db, char **env, MYSQL_RES **pres)
{
struct wordsplit ws;
int rc;
+ MYSQL *mysql = moddb_handle(db);
MYSQL_RES *result;
ws.ws_env = (const char **) env;
@@ -300,7 +394,7 @@ do_query(struct mysql_db *db, char **env, MYSQL_RES **pres)
smap_debug(dbgid, 1,
("running query: %s", ws.ws_wordv[0]));
- rc = mysql_query(&db->mysql, ws.ws_wordv[0]);
+ rc = mysql_query(mysql, ws.ws_wordv[0]);
if (rc) {
smap_error("%s: query failed: %s",
@@ -312,7 +406,7 @@ do_query(struct mysql_db *db, char **env, MYSQL_RES **pres)
if (rc)
return 1;
- *pres = mysql_store_result(&db->mysql);
+ *pres = mysql_store_result(mysql);
return 0;
}
@@ -343,7 +437,7 @@ send_reply(smap_stream_t ostr, const char *template, char **env)
}
static int
-do_positive_reply(struct mysql_db *db,
+do_positive_reply(struct mod_mysql_db *db,
smap_stream_t ostr,
char ***penv,
MYSQL_RES *result)
@@ -378,18 +472,19 @@ do_positive_reply(struct mysql_db *db,
}
env[i + j] = NULL;
- return send_reply(ostr, db->positive_reply, env);
+ return send_reply(ostr, moddb_positive_reply(db), env);
}
/* Consume additional result sets */
static void
-flush_result(struct mysql_db *db)
+flush_result(struct mod_mysql_db *db)
{
- while (mysql_next_result(&db->mysql) == 0) {
- MYSQL_RES *result = mysql_store_result(&db->mysql);
+ MYSQL *mysql = moddb_handle(db);
+ while (mysql_next_result(mysql) == 0) {
+ MYSQL_RES *result = mysql_store_result(mysql);
if (!result)
break;
- if (mysql_field_count(&db->mysql))
+ if (mysql_field_count(mysql))
while (mysql_fetch_row(result))
;
mysql_free_result(result);
@@ -402,7 +497,7 @@ mod_query(smap_database_t dbp,
const char *map, const char *key,
struct smap_conninfo const *conninfo)
{
- struct mysql_db *db = (struct mysql_db *)dbp;
+ struct mod_mysql_db *db = (struct mod_mysql_db *)dbp;
MYSQL_RES *res;
int rc;
char **env;
@@ -425,11 +520,12 @@ mod_query(smap_database_t dbp,
if (nrow > 0)
rc = do_positive_reply(db, ostr, &env, res);
else
- rc = send_reply(ostr, db->negative_reply, env);
+ rc = send_reply(ostr, moddb_negative_reply(db),
+ env);
mysql_free_result(res);
flush_result(db);
} else
- rc = send_reply(ostr, db->negative_reply, env);
+ rc = send_reply(ostr, moddb_negative_reply(db), env);
free_env(env);
return rc;
}

Return to:

Send suggestions and report system problems to the System administrator.