From ac38faf0bf01c52502c1536ca643f6b5e69322e4 Mon Sep 17 00:00:00 2001 From: scottmk Date: Wed, 19 May 2010 19:37:05 +0000 Subject: [PATCH] Implement open-ils.qstore.bind_param method, which applies actual values to bind variables (overriding default values, if any). M Open-ILS/src/c-apps/oils_qstore.c M Open-ILS/src/c-apps/buildSQL.c git-svn-id: svn://svn.open-ils.org/ILS/trunk@16454 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- Open-ILS/src/c-apps/buildSQL.c | 42 +++++++++++++++++++++++++++++++ Open-ILS/src/c-apps/oils_qstore.c | 38 +++++++++++++++++++++++++--- 2 files changed, 76 insertions(+), 4 deletions(-) diff --git a/Open-ILS/src/c-apps/buildSQL.c b/Open-ILS/src/c-apps/buildSQL.c index cc1c5b8010..aeb35eacaa 100644 --- a/Open-ILS/src/c-apps/buildSQL.c +++ b/Open-ILS/src/c-apps/buildSQL.c @@ -30,6 +30,48 @@ static void add_newline( BuildSQLState* state ); static inline void incr_indent( BuildSQLState* state ); static inline void decr_indent( BuildSQLState* state ); +/** + @brief Apply values to bind variables, overriding the defaults, if any. + @param state Pointer to the query-building context. + @param bindings A JSON_HASH of values. + @return 0 if successful, or 1 if not. + + The @a bindings parameter must be a JSON_HASH. The keys are the names of bind variables. + The values are the corresponding values for the variables. +*/ +int oilsApplyBindValues( BuildSQLState* state, jsonObject* bindings ) { + if( !state ) { + osrfLogError( OSRF_LOG_MARK, "NULL pointer to state" ); + return 1; + } else if( !bindings ) { + osrfLogError( OSRF_LOG_MARK, sqlAddMsg( state, + "Internal error: No pointer to bindings" )); + return 1; + } else if( bindings->type != JSON_HASH ) { + osrfLogError( OSRF_LOG_MARK, sqlAddMsg( state, + "Internal error: bindings parameter is not a JSON_HASH" )); + return 1; + } + + int rc = 0; + jsonObject* value = NULL; + jsonIterator* iter = jsonNewIterator( bindings ); + while(( value = jsonIteratorNext( iter ))) { + const char* var_name = iter->key; + BindVar* bind = osrfHashGet( state->bindvar_list, var_name ); + if( bind ) { + ; + } else { + osrfLogError( OSRF_LOG_MARK, sqlAddMsg( state, + "Can't assign value to bind variable \"%s\": no such variable", var_name )); + rc = 1; + } + } + jsonIteratorFree( iter ); + + return rc; +} + /** @brief Build an SQL query. @param state Pointer to the query-building context. diff --git a/Open-ILS/src/c-apps/oils_qstore.c b/Open-ILS/src/c-apps/oils_qstore.c index cf37a33a35..01ab891442 100644 --- a/Open-ILS/src/c-apps/oils_qstore.c +++ b/Open-ILS/src/c-apps/oils_qstore.c @@ -211,7 +211,7 @@ int doPrepare( osrfMethodContext* ctx ) { } /** - @brief Execute an SQL query and return a result set. + @brief Return a list of column names for the SELECT list. @param ctx Pointer to the current method context. @return Zero if successful, or -1 if not. @@ -275,14 +275,44 @@ int doBindParam( osrfMethodContext* ctx ) { CachedQuery* query = search_token( ctx, token ); if( !query ) { osrfAppSessionStatus( ctx->session, OSRF_STATUS_BADREQUEST, "osrfMethodException", - ctx->request, "Invalid query token" ); + ctx->request, "Invalid query token" ); return -1; } osrfLogInfo( OSRF_LOG_MARK, "Binding parameter(s) for token %s", token ); - osrfAppRespondComplete( ctx, jsonNewObject( "build method not yet implemented" )); - return 0; + jsonObject* bindings = jsonObjectGetIndex( ctx->params, 1 ); + if( !bindings ) { + osrfAppSessionStatus( ctx->session, OSRF_STATUS_BADREQUEST, "osrfMethodException", + ctx->request, "No parameter provided for bind variable values" ); + return -1; + } else if( bindings->type != JSON_HASH ) { + osrfAppSessionStatus( ctx->session, OSRF_STATUS_BADREQUEST, "osrfMethodException", + ctx->request, "Invalid parameter for bind variable values: not a hash" ); + return -1; + } + + if( 0 == bindings->size ) { + // No values to assign; we're done. + osrfAppRespondComplete( ctx, NULL ); + return 0; + } + + osrfHash* bindvar_list = query->state->bindvar_list; + if( !bindvar_list || osrfHashGetCount( bindvar_list ) == 0 ) { + osrfAppSessionStatus( ctx->session, OSRF_STATUS_BADREQUEST, "osrfMethodException", + ctx->request, "There are no bind variables to which to assign values" ); + return -1; + } + + if( oilsApplyBindValues( query->state, bindings )) { + osrfAppSessionStatus( ctx->session, OSRF_STATUS_BADREQUEST, "osrfMethodException", + ctx->request, "Unable to apply values to bind variables" ); + return -1; + } else { + osrfAppRespondComplete( ctx, NULL ); + return 0; + } } /** -- 2.43.2