summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Sommerseth <dazo@users.sourceforge.net>2012-02-24 00:15:15 +0100
committerDavid Sommerseth <dazo@users.sourceforge.net>2013-06-13 01:06:19 +0200
commitd1a5511b9cb71b366f6f98b5da075a95373b47cd (patch)
tree4ad51b01b84c8b84f1f913b7f8a9ce666e01d274
parent1af49dea1e1819e5d7ca0692f0f4fb5e82252602 (diff)
downloadeurephia-d1a5511b9cb71b366f6f98b5da075a95373b47cd.tar.gz
eurephia-d1a5511b9cb71b366f6f98b5da075a95373b47cd.tar.xz
eurephia-d1a5511b9cb71b366f6f98b5da075a95373b47cd.zip
edb-pgsql: Reworked the prepared statement loading
Rewrote the loading of prepared statements to be able to switch which statements are loaded, based on the eurephia context type. This ensures that the database connection for the OpenVPN connection will not have any prepared statements related to the administration queries. With this change, it also made sense to replace the ePGprepStatementGetID() function with ePGprepGetStatement() which returns a pointer directly to related statement, instead of looking up the "slot ID" for the requested statement. Signed-off-by: David Sommerseth <dazo@users.sourceforge.net>
-rw-r--r--database/postgresql/prepared-sql.c154
-rw-r--r--database/postgresql/prepared-sql.h1
2 files changed, 106 insertions, 49 deletions
diff --git a/database/postgresql/prepared-sql.c b/database/postgresql/prepared-sql.c
index d969744..c33fe3a 100644
--- a/database/postgresql/prepared-sql.c
+++ b/database/postgresql/prepared-sql.c
@@ -48,7 +48,7 @@ typedef struct {
/* All prepared statements are declared here, including the SQL part */
-static const _ePGprepStatements_t _ePGprepStatements[] = {
+static const _ePGprepStatements_t _ePGprepStatementsPlugin[] = {
{.prepid = PREPSQL_TLS_AUTH,
.name = "eurephia_tls_auth", .numargs = 5,
.sql =
@@ -338,6 +338,11 @@ static const _ePGprepStatements_t _ePGprepStatements[] = {
};
+static const _ePGprepStatements_t _ePGprepStatementsAdmin[] = {
+ {.prepid = PREPSQL_NONE,
+ .name = NULL, .numargs = 0, .sql = ""}
+};
+
static int _ePGprepStatement(eurephiaCTX *ctx, const _ePGprepStatements_t *prepst)
{
PGresult *dbr = NULL;
@@ -355,35 +360,88 @@ static int _ePGprepStatement(eurephiaCTX *ctx, const _ePGprepStatements_t *preps
};
-int ePGprepStatementGetID(ePG_prepID prepid)
+/**
+ * Retrieves a particular prepared statement, based on the context type
+ *
+ * @param eurephiaCTX eurephia context which contains the context type
+ * @param ePG_prepID The prepared statement which is requested
+ *
+ * @return Returns a pointer to the statement record if it is found, otherwise NULL.
+ */
+const _ePGprepStatements_t * ePGprepGetStatement(eurephiaCTX *ctx, ePG_prepID prepid)
{
- int i;
- for( i = 0; _ePGprepStatements[i].prepid != PREPSQL_NONE; i++ ) {
- if( _ePGprepStatements[i].prepid == prepid ) {
- return i;
+ const _ePGprepStatements_t * prep = NULL;
+
+ switch( ctx->context_type ) {
+ case ECTX_PLUGIN_AUTH:
+ prep = &_ePGprepStatementsPlugin[0];
+ break;
+
+ case ECTX_ADMIN_CONSOLE:
+ case ECTX_ADMIN_WEB:
+ prep = &_ePGprepStatementsAdmin[0];
+ break;
+
+ default:
+ eurephia_log(ctx, LOG_FATAL, 0, "ePGprepLoadStatements: Invalid context type");
+ return NULL;
+ }
+
+ for( ; prep->prepid != PREPSQL_NONE; prep++ ) {
+ if( prep->prepid == prepid ) {
+ return prep;
}
}
- return -1;
+ return NULL;
}
const char const * ePGprepStatementGetName(eurephiaCTX *ctx, ePG_prepID prepid)
{
- if( prepid != PREPSQL_NONE ) {
- int id = ePGprepStatementGetID(prepid);
- if( id < 0 ) {
- eurephia_log(ctx, LOG_ERROR, 0,
- "Failed to map prepared statement ID %i to "
- "a valid statement", prepid);
- return NULL;
- }
- return _ePGprepStatements[id].name;
+ const _ePGprepStatements_t * prep = NULL;
+
+ if( prepid == PREPSQL_NONE ) {
+ return NULL;
}
- return NULL;
+
+ if( (prep = ePGprepGetStatement(ctx, prepid)) == NULL ) {
+ eurephia_log(ctx, LOG_ERROR, 0,
+ "Failed to map prepared statement ID %i to "
+ "a valid statement", prepid);
+ return NULL;
+ }
+ return prep->name;
+}
+
+
+/**
+ * Load the provided statements.
+ *
+ * @param eurephiaCTX Pointer to the eurephia context with the database connection
+ * @param _ePGprepStatements_t Pointer to the prepared statements to be loaded
+ *
+ * @return Returns 1 on success, otherwise 0.
+ */
+
+static int _ePGprepDoStatementLoad(eurephiaCTX *ctx, const _ePGprepStatements_t *prep) {
+ const _ePGprepStatements_t * ptr = NULL;
+
+ ptr = prep;
+ do {
+ eurephia_log(ctx, LOG_INFO, 3, "Preparing SQL query '%s'", ptr->name);
+ DEBUG(ctx, 22, "SQL Query: %s", ptr->sql);
+ if( !_ePGprepStatement(ctx, ptr) ) {
+ return 0;
+ }
+ ptr++;
+ } while (ptr->prepid != PREPSQL_NONE);
+ return 1;
}
+
/**
* Loads and registers all the prepared statements
+ * for the current eurephia context
*
* @param ctx eurephiaCTX
*
@@ -391,30 +449,31 @@ const char const * ePGprepStatementGetName(eurephiaCTX *ctx, ePG_prepID prepid)
*/
int ePGprepLoadStatements(eurephiaCTX *ctx)
{
- const _ePGprepStatements_t * prep = NULL;
- int i = 0;
+ int ret = 0;
- prep = &_ePGprepStatements[i];
- do {
- eurephia_log(ctx, LOG_INFO, 3, "Preparing SQL query '%s'", prep->name);
- DEBUG(ctx, 22, "SQL Query: %s", prep->sql);
- if( !_ePGprepStatement(ctx, prep) ) {
- return 0;
- }
- i++;
- prep = &_ePGprepStatements[i];
- } while (prep->prepid != PREPSQL_NONE);
- return 1;
+ switch( ctx->context_type ) {
+ case ECTX_PLUGIN_AUTH:
+ ret = _ePGprepDoStatementLoad(ctx, _ePGprepStatementsPlugin);
+ break;
+
+ case ECTX_ADMIN_CONSOLE:
+ case ECTX_ADMIN_WEB:
+ ret = _ePGprepDoStatementLoad(ctx, _ePGprepStatementsAdmin);
+
+ default:
+ eurephia_log(ctx, LOG_FATAL, 0, "ePGprepLoadStatements: Invalid context type");
+ ret = 0;
+ }
+ return ret;
}
ePGprepParams * ePGprepParamsAlloc(eurephiaCTX *ctx, ePG_prepID prepid)
{
- int pid = -1;
ePGprepParams *ret = NULL;
+ const _ePGprepStatements_t * prep = NULL;
- pid = ePGprepStatementGetID(prepid);
- if( pid < 0 ) {
+ if( (prep = ePGprepGetStatement(ctx, prepid)) == NULL ) {
eurephia_log(ctx, LOG_FATAL, 0,
"Invalid prepared statement ID %i", prepid);
return NULL;
@@ -427,12 +486,12 @@ ePGprepParams * ePGprepParamsAlloc(eurephiaCTX *ctx, ePG_prepID prepid)
ret->prepid = prepid;
ret->index = 0;
- if( _ePGprepStatements[pid].numargs > 0 ) {
- ret->params = calloc(_ePGprepStatements[pid].numargs, sizeof(char *));
+ if( prep->numargs > 0 ) {
+ ret->params = calloc(prep->numargs, sizeof(char *));
if( !ret->params ) {
eurephia_log(ctx, LOG_FATAL, 0,
"Failed to allocate memory for SQL parameters (%s, %i args)",
- _ePGprepStatements[pid].name, _ePGprepStatements[pid].numargs);
+ prep->name, prep->numargs);
free_nullsafe(ctx, ret);
}
}
@@ -442,7 +501,7 @@ ePGprepParams * ePGprepParamsAlloc(eurephiaCTX *ctx, ePG_prepID prepid)
int ePGprepParamsAddArgument(eurephiaCTX *ctx, ePGprepParams *prms, const char *arg)
{
- int pid = -1;
+ const _ePGprepStatements_t * prep = NULL;
if( !prms ) {
eurephia_log(ctx, LOG_CRITICAL, 0,
@@ -452,17 +511,16 @@ int ePGprepParamsAddArgument(eurephiaCTX *ctx, ePGprepParams *prms, const char *
// TODO: Should a separate error indicator be set in ePGprepParams, to block further invocations?
- pid = ePGprepStatementGetID(prms->prepid);
- if( pid < 0 ) {
+ if( (prep = ePGprepGetStatement(ctx, prms->prepid)) == NULL ) {
eurephia_log(ctx, LOG_FATAL, 0,
"Invalid prepared statement ID %i", prms->prepid);
return 0;
}
- if( prms->index+1 > _ePGprepStatements[pid].numargs ) {
+ if( prms->index+1 > prep->numargs ) {
eurephia_log(ctx, LOG_FATAL, 0,
"Too many arguments provided to %s",
- _ePGprepStatements[pid].name);
+ prep->name);
return 0;
}
prms->params[prms->index] = strdup_nullsafe(arg);
@@ -483,33 +541,33 @@ int ePGprepParamsAddArgumentInt(eurephiaCTX *ctx, ePGprepParams *prms, const int
PGresult * ePGprepExec(eurephiaCTX *ctx, ePGprepParams *qry_args)
{
- int i = 0, pid = -1;
+ int i = 0;
PGresult *res = NULL;
+ const _ePGprepStatements_t * prep = NULL;
if( !qry_args ) {
eurephia_log(ctx, LOG_FATAL, 0,
"Missing query arguments (cannot be NULL)");
}
- pid = ePGprepStatementGetID(qry_args->prepid);
- if( pid < 0 ) {
+ if( (prep = ePGprepGetStatement(ctx, qry_args->prepid)) == NULL ) {
eurephia_log(ctx, LOG_FATAL, 0,
"Invalid prepared statement ID %i", qry_args->prepid);
return NULL;
}
- if( qry_args->index != _ePGprepStatements[pid].numargs ) {
+ if( qry_args->index != prep->numargs ) {
eurephia_log(ctx, LOG_FATAL, 0,
"Invalid number of arguments registered to %s query",
- _ePGprepStatements[pid].name);
+ prep->name);
return NULL;
}
// TODO: Should a separate error indicator in ePGprepParams block further invocations?
res = PQexecPrepared(ctx->dbc->dbhandle,
- _ePGprepStatements[pid].name,
- _ePGprepStatements[pid].numargs,
+ prep->name,
+ prep->numargs,
((qry_args && (qry_args->index > 0)) ? (const char **) qry_args->params : NULL),
NULL, NULL, 0);
diff --git a/database/postgresql/prepared-sql.h b/database/postgresql/prepared-sql.h
index 0d09f20..c8664db 100644
--- a/database/postgresql/prepared-sql.h
+++ b/database/postgresql/prepared-sql.h
@@ -61,7 +61,6 @@ typedef struct _ePGprepParam_s {
char **params;
} ePGprepParams;
-int ePGprepStatementGetID(ePG_prepID prepid);
const char const * ePGprepStatementGetName(eurephiaCTX *ctx, ePG_prepID prepid);
int ePGprepLoadStatements(eurephiaCTX *ctx);
ePGprepParams * ePGprepParamsAlloc(eurephiaCTX *ctx, ePG_prepID prepid);