diff options
Diffstat (limited to 'database')
-rw-r--r-- | database/postgresql/prepared-sql.c | 154 | ||||
-rw-r--r-- | database/postgresql/prepared-sql.h | 1 |
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); |