void IB_Statement::describeInput (const IB_SSHORT16 suggestedInputCols) { // If sqldaIn_ is already allocated, reuse it. // Otherwise, allocate space for a suggestedInputCols parameter list. // If more space is needed, allocate more later. if (!sqldaIn_) sqldaIn_ = (XSQLDA *) malloc (XSQLDA_LENGTH (suggestedInputCols)); if (!sqldaIn_) throw new IB_SQLException (IB_SQLException::outOfMemory__, IB_SQLException::outOfMemoryException__); sqldaIn_->sqln = suggestedInputCols; sqldaIn_->version = sqldaVersion__; dsqlDescribeBind (); IB_SSHORT16 actualInputCols = sqldaIn_->sqld; if (actualInputCols > sqldaIn_->sqln) { sqldaIn_ = (XSQLDA *) realloc (sqldaIn_, XSQLDA_LENGTH (actualInputCols)); sqldaIn_->version = sqldaVersion__; sqldaIn_->sqln = actualInputCols; dsqlDescribeBind (); } // Its harmless to delete a NULL pointer. // !!! future enhancement - make this a realloc delete inputBuffer_; inputBuffer_ = new IB_InputBuffer (this); // !!! do we really need to call clearParameters() here? clearParameters (); }
static int fb_prepare(rlm_sql_firebird_conn_t *conn, char const *query) { static char stmt_info[] = { isc_info_sql_stmt_type }; char info_buffer[128]; short l; if (!conn->trh) { isc_start_transaction(conn->status, &conn->trh, 1, &conn->dbh, conn->tpb_len, conn->tpb); if (!conn->trh) { return -4; } } fb_free_statement(conn); if (!conn->stmt) { isc_dsql_allocate_statement(conn->status, &conn->dbh, &conn->stmt); if (!conn->stmt) { return -1; } } fb_free_sqlda(conn->sqlda_out); isc_dsql_prepare(conn->status, &conn->trh, &conn->stmt, 0, query, conn->sql_dialect, conn->sqlda_out); if (IS_ISC_ERROR(conn->status)) { return -2; } if (conn->sqlda_out->sqln<conn->sqlda_out->sqld) { conn->sqlda_out->sqln = conn->sqlda_out->sqld; conn->sqlda_out = (XSQLDA ISC_FAR *) realloc(conn->sqlda_out, XSQLDA_LENGTH(conn->sqlda_out->sqld)); isc_dsql_describe(conn->status, &conn->stmt, SQL_DIALECT_V6, conn->sqlda_out); if (IS_ISC_ERROR(conn->status)) { return -3; } } /* * Get statement type */ isc_dsql_sql_info(conn->status, &conn->stmt, sizeof(stmt_info), stmt_info, sizeof(info_buffer), info_buffer); if (IS_ISC_ERROR(conn->status)) return -4; l = (short) isc_vax_integer((char ISC_FAR *) info_buffer + 1, 2); conn->statement_type = isc_vax_integer((char ISC_FAR *) info_buffer + 3, l); if (conn->sqlda_out->sqld) { fb_set_sqlda(conn->sqlda_out); //set out sqlda } return 0; }
int fb_init_socket(rlm_sql_firebird_conn_t *conn) { memset(conn, 0, sizeof(*conn)); conn->sqlda_out = (XSQLDA ISC_FAR *) calloc(XSQLDA_LENGTH (5), 1); conn->sqlda_out->sqln = 5; conn->sqlda_out->version = SQLDA_VERSION1; conn->sql_dialect = 3; pthread_mutex_init (&conn->mut, NULL); DEBUG("Init mutex %p\n", &conn->mut); /* * Set tpb to read_committed/wait/no_rec_version */ fb_set_tpb(conn, 5, isc_tpb_version3, isc_tpb_wait, isc_tpb_write, isc_tpb_read_committed, isc_tpb_no_rec_version); if (!conn->tpb) { return -1; } return 0; }
bool FirebirdStmt::setCommand(const QString& cmd) { clear(); _command = cmd; ISC_STATUS status[20]; _conn->startTransaction(); _procs->isc_dsql_allocate_statement(status, &_conn->_db, &_stmt); if (status[0] == 1 && status[1]) { qWarning("Error in: " + cmd); _procs->isc_print_status(status); return error("isc_dsql_allocate_statement failed"); } char* cmdString = strdup(_command); _procs->isc_dsql_prepare(status, &_conn->_tr, &_stmt, 0, cmdString, SQL_DIALECT_V6, _outputDA); free(cmdString); if (status[0] == 1 && status[1]) { qWarning("Error in: " + cmd); _procs->isc_print_status(status); return error("isc_dsql_prepare failed"); } int count = _outputDA->sqld; if (count > _outputDA->sqln) { _outputDA = (XSQLDA*)malloc(XSQLDA_LENGTH(count)); _outputDA->version = SQLDA_VERSION1; _outputDA->sqln = count; _procs->isc_dsql_describe(status, &_stmt, SQL_DIALECT_V6, _outputDA); if (status[0] == 1 && status[1]) { qWarning("Error in: " + cmd); _procs->isc_print_status(status); return error("isc_dsql_describe failed"); } } _procs->isc_dsql_describe_bind(status, &_stmt, SQL_DIALECT_V6, _inputDA); if (status[0] == 1 && status[1]) { qWarning("Error in: " + cmd); _procs->isc_print_status(status); return error("isc_dsql_describe_bind failed"); } count = _inputDA->sqld; if (count > _inputDA->sqln) { _inputDA = (XSQLDA*)malloc(XSQLDA_LENGTH(count)); _inputDA->version = SQLDA_VERSION1; _inputDA->sqln = count; _procs->isc_dsql_describe_bind(status, &_stmt,SQL_DIALECT_V6,_inputDA); if (status[0] == 1 && status[1]) { qWarning("Error in: " + cmd); _procs->isc_print_status(status); return error("isc_dsql_describe_bind failed"); } } // Create the params for (int pnum = 0; pnum < _inputDA->sqld; ++pnum) { FirebirdParam* param = new FirebirdParam(this, pnum); _params.push_back(param); } // Create the columns for (int cnum = 0; cnum < _outputDA->sqld; ++cnum) { FirebirdColumn* column = new FirebirdColumn(this, cnum); _columns.push_back(column); } _nextParam = 0; return true; }
int main (int argc, char** argv) { int num_cols, i; isc_stmt_handle stmt = NULL; XSQLDA *sqlda; char empdb[128]; if (argc > 1) strcpy(empdb, argv[1]); else strcpy(empdb, "employee.fdb"); if (isc_attach_database(status, 0, empdb, &DB, 0, NULL)) { ERREXIT(status, 1) } /* Allocate SQLDA of an arbitrary size. */ sqlda = (XSQLDA *) malloc(XSQLDA_LENGTH(3)); sqlda->sqln = 3; sqlda->version = 1; if (isc_start_transaction(status, &trans, 1, &DB, 0, NULL)) { ERREXIT(status, 1) } /* Allocate a statement. */ if (isc_dsql_allocate_statement(status, &DB, &stmt)) { ERREXIT(status, 1) } /* Prepare the statement. */ if (isc_dsql_prepare(status, &trans, &stmt, 0, sel_str, 1, sqlda)) { ERREXIT(status, 1) } /* Describe the statement. */ if (isc_dsql_describe(status, &stmt, 1, sqlda)) { ERREXIT(status, 1) } /* This is a select statement, print more information about it. */ printf("Query Type: SELECT\n\n"); num_cols = sqlda->sqld; printf("Number of columns selected: %d\n", num_cols); /* Reallocate SQLDA if necessary. */ if (sqlda->sqln < sqlda->sqld) { sqlda = (XSQLDA *) malloc(XSQLDA_LENGTH(num_cols)); sqlda->sqln = num_cols; sqlda->version = 1; /* Re-describe the statement. */ if (isc_dsql_describe(status, &stmt, 1, sqlda)) { ERREXIT(status, 1) } num_cols = sqlda->sqld; }
/* ** Executes a SQL statement. ** Returns ** cursor object: if there are results or ** row count: number of rows affected by statement if no results */ static int conn_execute (lua_State *L) { conn_data *conn = getconnection(L,1); const char *statement = luaL_checkstring(L, 2); int dialect = (int)luaL_optnumber(L, 3, 3); XSQLVAR *var; long dtype; int i, n, count, stmt_type; cur_data cur; cur.closed = 0; cur.env = conn->env; cur.conn = conn; cur.stmt = NULL; cur.out_sqlda = (XSQLDA *)malloc(XSQLDA_LENGTH(CURSOR_PREALLOC)); cur.out_sqlda->version = SQLDA_VERSION1; cur.out_sqlda->sqln = CURSOR_PREALLOC; /* create a statement to handle the query */ isc_dsql_allocate_statement(conn->env->status_vector, &conn->db, &cur.stmt); if ( CHECK_DB_ERROR(conn->env->status_vector) ) { free(cur.out_sqlda); return return_db_error(L, conn->env->status_vector); } /* process the SQL ready to run the query */ isc_dsql_prepare(conn->env->status_vector, &conn->transaction, &cur.stmt, 0, (char*)statement, dialect, cur.out_sqlda); if ( CHECK_DB_ERROR(conn->env->status_vector) ) { free(cur.out_sqlda); return return_db_error(L, conn->env->status_vector); } /* what type of SQL statement is it? */ stmt_type = get_statement_type(&cur); if(stmt_type < 0) { free(cur.out_sqlda); return return_db_error(L, conn->env->status_vector); } /* an unsupported SQL statement (something like COMMIT) */ if(stmt_type > 5) { free(cur.out_sqlda); return luasql_faildirect(L, "unsupported SQL statement"); } /* resize the result set if needed */ if (cur.out_sqlda->sqld > cur.out_sqlda->sqln) { n = cur.out_sqlda->sqld; free(cur.out_sqlda); cur.out_sqlda = (XSQLDA *)malloc(XSQLDA_LENGTH(n)); cur.out_sqlda->sqln = n; cur.out_sqlda->version = SQLDA_VERSION1; isc_dsql_describe(conn->env->status_vector, &cur.stmt, 1, cur.out_sqlda); if ( CHECK_DB_ERROR(conn->env->status_vector) ) { free(cur.out_sqlda); return return_db_error(L, conn->env->status_vector); } } /* prep the result set ready to handle the data */ for (i=0, var = cur.out_sqlda->sqlvar; i < cur.out_sqlda->sqld; i++, var++) { dtype = (var->sqltype & ~1); /* drop flag bit for now */ switch(dtype) { case SQL_VARYING: var->sqldata = (char *)malloc(sizeof(char)*var->sqllen + 2); break; case SQL_TEXT: var->sqldata = (char *)malloc(sizeof(char)*var->sqllen); break; case SQL_SHORT: var->sqldata = (char *)malloc(sizeof(short)); break; case SQL_LONG: var->sqldata = (char *)malloc(sizeof(long)); break; case SQL_INT64: var->sqldata = (char *)malloc(sizeof(ISC_INT64)); break; case SQL_FLOAT: var->sqldata = (char *)malloc(sizeof(float)); break; case SQL_DOUBLE: var->sqldata = (char *)malloc(sizeof(double)); break; case SQL_TYPE_TIME: var->sqldata = (char *)malloc(sizeof(ISC_TIME)); break; case SQL_TYPE_DATE: var->sqldata = (char *)malloc(sizeof(ISC_DATE)); break; case SQL_TIMESTAMP: var->sqldata = (char *)malloc(sizeof(ISC_TIMESTAMP)); break; case SQL_BLOB: var->sqldata = (char *)malloc(sizeof(ISC_QUAD)); break; /* TODO : add extra data type handles here */ } if (var->sqltype & 1) { /* allocate variable to hold NULL status */ var->sqlind = (short *)malloc(sizeof(short)); } else { var->sqlind = NULL; } } /* run the query */ isc_dsql_execute(conn->env->status_vector, &conn->transaction, &cur.stmt, 1, NULL); if ( CHECK_DB_ERROR(conn->env->status_vector) ) { free_cur(&cur); return return_db_error(L, conn->env->status_vector); } /* if autocommit is set and it's a non SELECT query, commit change */ if(conn->autocommit != 0 && stmt_type > 1) { isc_commit_retaining(conn->env->status_vector, &conn->transaction); if ( CHECK_DB_ERROR(conn->env->status_vector) ) { free_cur(&cur); return return_db_error(L, conn->env->status_vector); } } /* what do we return? a cursor or a count */ if(cur.out_sqlda->sqld > 0) { /* a cursor */ cur_data* user_cur; /* open the cursor ready for fetch cycles */ isc_dsql_set_cursor_name(cur.env->status_vector, &cur.stmt, "dyn_cursor", (unsigned short)NULL); if ( CHECK_DB_ERROR(conn->env->status_vector) ) { free_cur(&cur); return return_db_error(L, conn->env->status_vector); } /* copy the cursor into a new lua userdata object */ user_cur = (cur_data*)lua_newuserdata(L, sizeof(cur_data)); luasql_setmeta (L, LUASQL_CURSOR_FIREBIRD); memcpy((void*)user_cur, (void*)&cur, sizeof(cur_data)); /* add cursor to the lock count */ lua_registerobj(L, 1, conn); ++conn->lock; } else { /* a count */ if( (count = count_rows_affected(&cur)) < 0 ) { free(cur.out_sqlda); return return_db_error(L, conn->env->status_vector); } lua_pushnumber(L, count); /* totaly finnished with the cursor */ isc_dsql_free_statement(conn->env->status_vector, &cur.stmt, DSQL_drop); free(cur.out_sqlda); } return 1; }
int query( char * sel_str ) { ISC_STATUS status[ 20 ]; XSQLVAR * var; int n, i, dtype; if( isc_start_transaction( status, &trans, 1, &db, 0, NULL ) ) ERREXIT( status, 1 ); /* Allocate an output SQLDA. Just to check number of columns */ sqlda = ( XSQLDA * ) malloc( XSQLDA_LENGTH( 1 ) ); sqlda->sqln = 1; sqlda->version = 1; /* Allocate a statement */ if( isc_dsql_allocate_statement( status, &db, &stmt ) ) ERREXIT( status, 1 ); /* Prepare the statement. */ if( isc_dsql_prepare( status, &trans, &stmt, 0, sel_str, dialect, sqlda ) ) ERREXIT( status, 1 ); /* Describe sql contents */ if( isc_dsql_describe( status, &stmt, dialect, sqlda ) ) ERREXIT( status, 1 ); /* Relocate necessary number of columns */ if( sqlda->sqld > sqlda->sqln ) { free( sqlda ); n = sqlda->sqld; sqlda = ( XSQLDA * ) malloc( XSQLDA_LENGTH( n ) ); sqlda->sqln = n; sqlda->version = 1; if( isc_dsql_describe( status, &stmt, dialect, sqlda ) ) ERREXIT( status, 1 ); } for( i = 0, var = sqlda->sqlvar; i < sqlda->sqld; i++, var++ ) { dtype = ( var->sqltype & ~1 ); switch( dtype ) { case SQL_VARYING: var->sqltype = SQL_TEXT; var->sqldata = ( char * ) malloc( sizeof( char ) * var->sqllen + 2 ); break; case SQL_TEXT: var->sqldata = ( char * ) malloc( sizeof( char ) * var->sqllen + 2 ); break; case SQL_LONG: var->sqltype = SQL_LONG; var->sqldata = ( char * ) malloc( sizeof( long ) ); break; default: var->sqldata = ( char * ) malloc( sizeof( char ) * var->sqllen ); break; } if( var->sqltype & 1 ) { var->sqlind = ( short * ) malloc( sizeof( short ) ); } } if( ! sqlda->sqld ) { /* Execute and commit non-select querys */ if( isc_dsql_execute( status, &trans, &stmt, dialect, NULL ) ) ERREXIT( status, 1 ); if( isc_commit_transaction( status, &trans ) ) ERREXIT( status, 1 ); trans = NULL; } else { if( isc_dsql_execute( status, &trans, &stmt, dialect, sqlda ) ) ERREXIT( status, 1 ); } return 1; }
IB_ResultSet* IB_Statement::prepareNoInput (const IB_STRING sqlString, const IB_SSHORT16 suggestedResultCols, const IB_SSHORT16 maxFieldSize) { //david jencks 2-4-2001 sqlLog(sqlString); // logg all sql statements if (!stmtHandle_) open (); // If sqldaOut_ is already allocated, reuse it. // Otherwise, allocate space for a suggestedResultCols item select list. // If more space is needed, allocate more later. if (!sqldaOut_) sqldaOut_ = (XSQLDA *) malloc (XSQLDA_LENGTH(suggestedResultCols)); if (!sqldaOut_) throw new IB_SQLException (IB_SQLException::outOfMemory__, IB_SQLException::outOfMemoryException__); sqldaOut_->version = sqldaVersion__; sqldaOut_->sqln = suggestedResultCols; if (isc_dsql_prepare (status_->vector(), transaction_->trHandleP(), &stmtHandle_, 0, sqlString, // CJL-IB6 add SQLDialect support, and obsolete sqldaVersion connection_->attachmentSQLDialect_, // sqldaVersion__, // CJL-IB6 end sqldaOut_)) throw new IB_SQLException (IB_SQLException::engine__default_0__, status_); prepared_ = IB_TRUE; IB_SSHORT16 actualResultCols = sqldaOut_->sqld; stmtType_ = statementType (); // If its a non-select, just return. if (!actualResultCols) { return NULL; } // Check that actual number of result cols is not greater than allocated suggestedInputCols. // Realloc if necessary. if (sqldaOut_->sqln < actualResultCols) { sqldaOut_ = (XSQLDA *) realloc (sqldaOut_, XSQLDA_LENGTH (actualResultCols)); sqldaOut_->version = sqldaVersion__; sqldaOut_->sqln = actualResultCols; } // !!! MOVE THIS UP INSIDE IF STATEMENT // Describe the output sqlvars if (isc_dsql_describe (status_->vector(), &stmtHandle_, // CJL-IB6 add SQLDialect support, and obsolete sqldaVersion connection_->attachmentSQLDialect_, // sqldaVersion__, // CJL-IB6 end sqldaOut_)) throw new IB_SQLException (IB_SQLException::engine__default_0__, status_); // Its harmless to delete a NULL pointer. delete resultSet_; // Must always realloc since record size may change. // !!! future enhancement - make this a realloc resultSet_ = new IB_ResultSet (this, maxFieldSize); return resultSet_; }
static int perform_ibase_search(uschar * query, uschar * server, uschar ** resultptr, uschar ** errmsg, BOOL * defer_break) { isc_stmt_handle stmth = NULL; XSQLDA *out_sqlda; XSQLVAR *var; char buffer[256]; ISC_STATUS status[20], *statusp = status; int i; int ssize = 0; int offset = 0; int yield = DEFER; uschar *result = NULL; ibase_connection *cn; uschar *server_copy = NULL; uschar *sdata[3]; /* Disaggregate the parameters from the server argument. The order is host, database, user, password. We can write to the string, since it is in a nextinlist temporary buffer. The copy of the string that is used for caching has the password removed. This copy is also used for debugging output. */ for (i = 2; i > 0; i--) { uschar *pp = Ustrrchr(server, '|'); if (pp == NULL) { *errmsg = string_sprintf("incomplete Interbase server data: %s", (i == 3) ? server : server_copy); *defer_break = TRUE; return DEFER; } *pp++ = 0; sdata[i] = pp; if (i == 2) server_copy = string_copy(server); /* sans password */ } sdata[0] = server; /* What's left at the start */ /* See if we have a cached connection to the server */ for (cn = ibase_connections; cn != NULL; cn = cn->next) { if (Ustrcmp(cn->server, server_copy) == 0) { break; } } /* Use a previously cached connection ? */ if (cn != NULL) { static char db_info_options[] = { isc_info_base_level }; /* test if the connection is alive */ if (isc_database_info (status, &cn->dbh, sizeof(db_info_options), db_info_options, sizeof(buffer), buffer)) { /* error occurred: assume connection is down */ DEBUG(D_lookup) debug_printf ("Interbase cleaning up cached connection: %s\n", cn->server); isc_detach_database(status, &cn->dbh); } else { DEBUG(D_lookup) debug_printf("Interbase using cached connection for %s\n", server_copy); } } else { cn = store_get(sizeof(ibase_connection)); cn->server = server_copy; cn->dbh = NULL; cn->transh = NULL; cn->next = ibase_connections; ibase_connections = cn; } /* If no cached connection, we must set one up. */ if (cn->dbh == NULL || cn->transh == NULL) { char *dpb, *p; short dpb_length; static char trans_options[] = { isc_tpb_version3, isc_tpb_read, isc_tpb_read_committed, isc_tpb_rec_version }; /* Construct the database parameter buffer. */ dpb = buffer; *dpb++ = isc_dpb_version1; *dpb++ = isc_dpb_user_name; *dpb++ = strlen(sdata[1]); for (p = sdata[1]; *p;) *dpb++ = *p++; *dpb++ = isc_dpb_password; *dpb++ = strlen(sdata[2]); for (p = sdata[2]; *p;) *dpb++ = *p++; dpb_length = dpb - buffer; DEBUG(D_lookup) debug_printf("new Interbase connection: database=%s user=%s\n", sdata[0], sdata[1]); /* Connect to the database */ if (isc_attach_database (status, 0, sdata[0], &cn->dbh, dpb_length, buffer)) { isc_interprete(buffer, &statusp); *errmsg = string_sprintf("Interbase attach() failed: %s", buffer); *defer_break = FALSE; goto IBASE_EXIT; } /* Now start a read-only read-committed transaction */ if (isc_start_transaction (status, &cn->transh, 1, &cn->dbh, sizeof(trans_options), trans_options)) { isc_interprete(buffer, &statusp); isc_detach_database(status, &cn->dbh); *errmsg = string_sprintf("Interbase start_transaction() failed: %s", buffer); *defer_break = FALSE; goto IBASE_EXIT; } } /* Run the query */ if (isc_dsql_allocate_statement(status, &cn->dbh, &stmth)) { isc_interprete(buffer, &statusp); *errmsg = string_sprintf("Interbase alloc_statement() failed: %s", buffer); *defer_break = FALSE; goto IBASE_EXIT; } out_sqlda = store_get(XSQLDA_LENGTH(1)); out_sqlda->version = SQLDA_VERSION1; out_sqlda->sqln = 1; if (isc_dsql_prepare (status, &cn->transh, &stmth, 0, query, 1, out_sqlda)) { isc_interprete(buffer, &statusp); store_reset(out_sqlda); out_sqlda = NULL; *errmsg = string_sprintf("Interbase prepare_statement() failed: %s", buffer); *defer_break = FALSE; goto IBASE_EXIT; } /* re-allocate the output structure if there's more than one field */ if (out_sqlda->sqln < out_sqlda->sqld) { XSQLDA *new_sqlda = store_get(XSQLDA_LENGTH(out_sqlda->sqld)); if (isc_dsql_describe (status, &stmth, out_sqlda->version, new_sqlda)) { isc_interprete(buffer, &statusp); isc_dsql_free_statement(status, &stmth, DSQL_drop); store_reset(out_sqlda); out_sqlda = NULL; *errmsg = string_sprintf("Interbase describe_statement() failed: %s", buffer); *defer_break = FALSE; goto IBASE_EXIT; } out_sqlda = new_sqlda; } /* allocate storage for every returned field */ for (i = 0, var = out_sqlda->sqlvar; i < out_sqlda->sqld; i++, var++) { switch (var->sqltype & ~1) { case SQL_VARYING: var->sqldata = (char *) store_get(sizeof(char) * var->sqllen + 2); break; case SQL_TEXT: var->sqldata = (char *) store_get(sizeof(char) * var->sqllen); break; case SQL_SHORT: var->sqldata = (char *) store_get(sizeof(short)); break; case SQL_LONG: var->sqldata = (char *) store_get(sizeof(ISC_LONG)); break; #ifdef SQL_INT64 case SQL_INT64: var->sqldata = (char *) store_get(sizeof(ISC_INT64)); break; #endif case SQL_FLOAT: var->sqldata = (char *) store_get(sizeof(float)); break; case SQL_DOUBLE: var->sqldata = (char *) store_get(sizeof(double)); break; #ifdef SQL_TIMESTAMP case SQL_DATE: var->sqldata = (char *) store_get(sizeof(ISC_QUAD)); break; #else case SQL_TIMESTAMP: var->sqldata = (char *) store_get(sizeof(ISC_TIMESTAMP)); break; case SQL_TYPE_DATE: var->sqldata = (char *) store_get(sizeof(ISC_DATE)); break; case SQL_TYPE_TIME: var->sqldata = (char *) store_get(sizeof(ISC_TIME)); break; #endif } if (var->sqltype & 1) { var->sqlind = (short *) store_get(sizeof(short)); } } /* finally, we're ready to execute the statement */ if (isc_dsql_execute (status, &cn->transh, &stmth, out_sqlda->version, NULL)) { isc_interprete(buffer, &statusp); *errmsg = string_sprintf("Interbase describe_statement() failed: %s", buffer); isc_dsql_free_statement(status, &stmth, DSQL_drop); *defer_break = FALSE; goto IBASE_EXIT; } while (isc_dsql_fetch(status, &stmth, out_sqlda->version, out_sqlda) != 100L) { /* check if an error occurred */ if (status[0] & status[1]) { isc_interprete(buffer, &statusp); *errmsg = string_sprintf("Interbase fetch() failed: %s", buffer); isc_dsql_free_statement(status, &stmth, DSQL_drop); *defer_break = FALSE; goto IBASE_EXIT; } if (result != NULL) result = string_catn(result, &ssize, &offset, US "\n", 1); /* Find the number of fields returned. If this is one, we don't add field names to the data. Otherwise we do. */ if (out_sqlda->sqld == 1) { if (out_sqlda->sqlvar[0].sqlind == NULL || *out_sqlda->sqlvar[0].sqlind != -1) /* NULL value yields nothing */ result = string_catn(result, &ssize, &offset, US buffer, fetch_field(buffer, sizeof(buffer), &out_sqlda->sqlvar[0])); } else for (i = 0; i < out_sqlda->sqld; i++) { int len = fetch_field(buffer, sizeof(buffer), &out_sqlda->sqlvar[i]); result = string_cat(result, &ssize, &offset, US out_sqlda->sqlvar[i].aliasname, out_sqlda->sqlvar[i].aliasname_length); result = string_catn(result, &ssize, &offset, US "=", 1); /* Quote the value if it contains spaces or is empty */ if (*out_sqlda->sqlvar[i].sqlind == -1) { /* NULL value */ result = string_catn(result, &ssize, &offset, US "\"\"", 2); } else if (buffer[0] == 0 || Ustrchr(buffer, ' ') != NULL) { int j; result = string_catn(result, &ssize, &offset, US "\"", 1); for (j = 0; j < len; j++) { if (buffer[j] == '\"' || buffer[j] == '\\') result = string_cat(result, &ssize, &offset, US "\\", 1); result = string_cat(result, &ssize, &offset, US buffer + j, 1); } result = string_catn(result, &ssize, &offset, US "\"", 1); } else { result = string_catn(result, &ssize, &offset, US buffer, len); } result = string_catn(result, &ssize, &offset, US " ", 1); } } /* If result is NULL then no data has been found and so we return FAIL. Otherwise, we must terminate the string which has been built; string_cat() always leaves enough room for a terminating zero. */ if (result == NULL) { yield = FAIL; *errmsg = US "Interbase: no data found"; } else { result[offset] = 0; store_reset(result + offset + 1); } /* Get here by goto from various error checks. */ IBASE_EXIT: if (stmth != NULL) isc_dsql_free_statement(status, &stmth, DSQL_drop); /* Non-NULL result indicates a successful result */ if (result != NULL) { *resultptr = result; return OK; } else { DEBUG(D_lookup) debug_printf("%s\n", *errmsg); return yield; /* FAIL or DEFER */ } }
int main (int argc, char** argv) { char dept_no[4]; double percent_inc; short flag0 = 0, flag1 = 0; XSQLDA *sqlda; long sqlcode; char empdb[128]; if (argc > 1) strcpy(empdb, argv[1]); else strcpy(empdb, "employee.fdb"); if (isc_attach_database(status, 0, empdb, &DB, 0, NULL)) { ERREXIT(status, 1) } /* Allocate an input SQLDA. There are two unknown parameters. */ sqlda = (XSQLDA *) malloc(XSQLDA_LENGTH(2)); sqlda->sqln = 2; sqlda->sqld = 2; sqlda->version = 1; sqlda->sqlvar[0].sqldata = (char *) &percent_inc; sqlda->sqlvar[0].sqltype = SQL_DOUBLE + 1; sqlda->sqlvar[0].sqllen = sizeof(percent_inc); sqlda->sqlvar[0].sqlind = &flag0; flag0 = 0; sqlda->sqlvar[1].sqldata = dept_no; sqlda->sqlvar[1].sqltype = SQL_TEXT + 1; sqlda->sqlvar[1].sqllen = 3; sqlda->sqlvar[1].sqlind = &flag1; flag1 = 0; /* * Get the next department-percent increase input pair. */ while (get_input(dept_no, &percent_inc)) { printf("\nIncreasing budget for department: %s by %5.2lf percent.\n", dept_no, percent_inc); if (isc_start_transaction(status, &trans, 1, &DB, 0, NULL)) { ERREXIT(status, 1) } /* Update the budget. */ isc_dsql_execute_immediate(status, &DB, &trans, 0, updstr, 1, sqlda); sqlcode = isc_sqlcode(status); if (sqlcode) { /* Don't save the update, if the new budget exceeds the limit. */ if (sqlcode == -625) { printf("\tExceeded budget limit -- not updated.\n"); if (isc_rollback_transaction(status, &trans)) { ERREXIT(status, 1) } continue; } /* Undo all changes, in case of an error. */ else { isc_print_status(status); printf("SQLCODE=%d\n", sqlcode); isc_rollback_transaction(status, &trans); ERREXIT(status, 1) } }
DatabaseResultSet* FirebirdDatabaseLayer::RunQueryWithResults(const wxString& strQuery) { ResetErrorCodes(); if (m_pDatabase != NULL) { wxCharBuffer sqlDebugBuffer = ConvertToUnicodeStream(strQuery); //wxLogDebug(_("Running query: \"%s\""), (const char*)sqlDebugBuffer); wxArrayString QueryArray = ParseQueries(strQuery); if (QueryArray.size() > 0) { bool bQuickieTransaction = false; if (m_pTransaction == NULL) { // If there's no transaction is progress, run this as a quick one-timer transaction bQuickieTransaction = true; } if (QueryArray.size() > 1) { if (bQuickieTransaction) { BeginTransaction(); if (GetErrorCode() != DATABASE_LAYER_OK) { wxLogError(_("Unable to start transaction")); ThrowDatabaseException(); return NULL; } } // Assume that only the last statement in the array returns the result set for (unsigned int i=0; i<QueryArray.size()-1; i++) { RunQuery(QueryArray[i], false); if (GetErrorCode() != DATABASE_LAYER_OK) { ThrowDatabaseException(); return NULL; } } // Now commit all the previous queries before calling the query that returns a result set if (bQuickieTransaction) { Commit(); if (GetErrorCode() != DATABASE_LAYER_OK) { ThrowDatabaseException(); return NULL; } } } // End check if there are more than one query in the array isc_tr_handle pQueryTransaction = NULL; bool bManageTransaction = false; if (bQuickieTransaction) { bManageTransaction = true; isc_db_handle pDatabase = (isc_db_handle)m_pDatabase; int nReturn = m_pInterface->GetIscStartTransaction()(*(ISC_STATUS_ARRAY*)m_pStatus, &pQueryTransaction, 1, &pDatabase, 0 /*tpb_length*/, NULL/*tpb*/); m_pDatabase = pDatabase; if (nReturn != 0) { InterpretErrorCodes(); ThrowDatabaseException(); } } else { pQueryTransaction = m_pTransaction; } isc_stmt_handle pStatement = NULL; isc_db_handle pDatabase = (isc_db_handle)m_pDatabase; int nReturn = m_pInterface->GetIscDsqlAllocateStatement()(*(ISC_STATUS_ARRAY*)m_pStatus, &pDatabase, &pStatement); m_pDatabase = pDatabase; if (nReturn != 0) { InterpretErrorCodes(); // Manually try to rollback the transaction rather than calling the member RollBack function // so that we can ignore the error messages m_pInterface->GetIscRollbackTransaction()(*(ISC_STATUS_ARRAY*)m_pStatus, &pQueryTransaction); ThrowDatabaseException(); return NULL; } wxCharBuffer sqlBuffer = ConvertToUnicodeStream(QueryArray[QueryArray.size()-1]); nReturn = m_pInterface->GetIscDsqlPrepare()(*(ISC_STATUS_ARRAY*)m_pStatus, &pQueryTransaction, &pStatement, 0, (char*)(const char*)sqlBuffer, SQL_DIALECT_CURRENT, NULL); if (nReturn != 0) { InterpretErrorCodes(); // Manually try to rollback the transaction rather than calling the member RollBack function // so that we can ignore the error messages m_pInterface->GetIscRollbackTransaction()(*(ISC_STATUS_ARRAY*)m_pStatus, &pQueryTransaction); ThrowDatabaseException(); return NULL; } //-------------------------------------------------------------- XSQLDA* pOutputSqlda = (XSQLDA*)malloc(XSQLDA_LENGTH(1)); pOutputSqlda->sqln = 1; pOutputSqlda->version = SQLDA_VERSION1; // Make sure that we have enough space allocated for the result set nReturn = m_pInterface->GetIscDsqlDescribe()(*(ISC_STATUS_ARRAY*)m_pStatus, &pStatement, SQL_DIALECT_CURRENT, pOutputSqlda); if (nReturn != 0) { free(pOutputSqlda); InterpretErrorCodes(); // Manually try to rollback the transaction rather than calling the member RollBack function // so that we can ignore the error messages m_pInterface->GetIscRollbackTransaction()(*(ISC_STATUS_ARRAY*)m_pStatus, &pQueryTransaction); ThrowDatabaseException(); return NULL; } if (pOutputSqlda->sqld > pOutputSqlda->sqln) { int nColumns = pOutputSqlda->sqld; free(pOutputSqlda); pOutputSqlda = (XSQLDA*)malloc(XSQLDA_LENGTH(nColumns)); pOutputSqlda->sqln = nColumns; pOutputSqlda->version = SQLDA_VERSION1; nReturn = m_pInterface->GetIscDsqlDescribe()(*(ISC_STATUS_ARRAY*)m_pStatus, &pStatement, SQL_DIALECT_CURRENT, pOutputSqlda); if (nReturn != 0) { free(pOutputSqlda); InterpretErrorCodes(); // Manually try to rollback the transaction rather than calling the member RollBack function // so that we can ignore the error messages m_pInterface->GetIscRollbackTransaction()(*(ISC_STATUS_ARRAY*)m_pStatus, &pQueryTransaction); ThrowDatabaseException(); return NULL; } } // Create the result set object FirebirdResultSet* pResultSet = new FirebirdResultSet(m_pInterface, m_pDatabase, pQueryTransaction, pStatement, pOutputSqlda, true, bManageTransaction); pResultSet->SetEncoding(GetEncoding()); if (pResultSet->GetErrorCode() != DATABASE_LAYER_OK) { SetErrorCode(pResultSet->GetErrorCode()); SetErrorMessage(pResultSet->GetErrorMessage()); // Manually try to rollback the transaction rather than calling the member RollBack function // so that we can ignore the error messages m_pInterface->GetIscRollbackTransaction()(*(ISC_STATUS_ARRAY*)m_pStatus, &pQueryTransaction); // Wrap the result set deletion in try/catch block if using exceptions. //We want to make sure the original error gets to the user #ifndef DONT_USE_DATABASE_LAYER_EXCEPTIONS try { #endif delete pResultSet; #ifndef DONT_USE_DATABASE_LAYER_EXCEPTIONS } catch (DatabaseLayerException& e) { } #endif ThrowDatabaseException(); } // Now execute the SQL nReturn = m_pInterface->GetIscDsqlExecute()(*(ISC_STATUS_ARRAY*)m_pStatus, &pQueryTransaction, &pStatement, SQL_DIALECT_CURRENT, NULL); if (nReturn != 0) { InterpretErrorCodes(); // Manually try to rollback the transaction rather than calling the member RollBack function // so that we can ignore the error messages m_pInterface->GetIscRollbackTransaction()(*(ISC_STATUS_ARRAY*)m_pStatus, &pQueryTransaction); // Wrap the result set deletion in try/catch block if using exceptions. // We want to make sure the isc_dsql_execute error gets to the user #ifndef DONT_USE_DATABASE_LAYER_EXCEPTIONS try { #endif delete pResultSet; #ifndef DONT_USE_DATABASE_LAYER_EXCEPTIONS } catch (DatabaseLayerException& e) { } #endif ThrowDatabaseException(); return NULL; } //-------------------------------------------------------------- LogResultSetForCleanup(pResultSet); return pResultSet; } else return NULL; } else { wxLogError(_("Database handle is NULL")); return NULL; } }