void MET_set_capabilities(ISC_STATUS* user_status, tdr* trans) { AliceGlobals* tdgbl = AliceGlobals::getSpecific(); if (!(DB = trans->tdr_db_handle)) return; /*START_TRANSACTION*/ { { isc_start_transaction (isc_status, (FB_API_HANDLE*) &gds_trans, (short) 1, &DB, (short) 0, (char*) 0); }; /*ON_ERROR*/ if (isc_status [1]) { return_error(user_status); /*END_ERROR;*/ } } trans->tdr_db_caps = get_capabilities(user_status); /*ROLLBACK*/ { isc_rollback_transaction (isc_status, (FB_API_HANDLE*) &gds_trans);; /*ON_ERROR*/ if (isc_status [1]) { return_error(user_status); /*END_ERROR;*/ } } }
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; }
void MET_disable_wal(ISC_STATUS* user_status, isc_db_handle handle) { struct isc_23_struct { short isc_24; /* isc_utility */ } isc_23; struct isc_21_struct { short isc_22; /* isc_utility */ } isc_21; struct isc_19_struct { short isc_20; /* isc_utility */ } isc_19; FB_API_HANDLE request = 0; AliceGlobals* tdgbl = AliceGlobals::getSpecific(); if (!(DB = handle)) return; /*START_TRANSACTION*/ { { isc_start_transaction (isc_status, (FB_API_HANDLE*) &gds_trans, (short) 1, &DB, (short) 0, (char*) 0); }; /*ON_ERROR*/ if (isc_status [1]) { return_error(user_status); /*END_ERROR;*/ } } /*FOR(REQUEST_HANDLE request) X IN RDB$LOG_FILES*/ { if (!request) isc_compile_request (NULL, (FB_API_HANDLE*) &DB, (FB_API_HANDLE*) &request, (short) sizeof(isc_18), (char*) isc_18); isc_start_request (NULL, (FB_API_HANDLE*) &request, (FB_API_HANDLE*) &gds_trans, (short) 0); while (1) { isc_receive (NULL, (FB_API_HANDLE*) &request, (short) 0, (short) 2, &isc_19, (short) 0); if (!isc_19.isc_20) break; /*ERASE X;*/ isc_send (NULL, (FB_API_HANDLE*) &request, (short) 1, (short) 2, &isc_21, (short) 0); /*END_FOR*/ isc_send (NULL, (FB_API_HANDLE*) &request, (short) 2, (short) 2, &isc_23, (short) 0); } } /*COMMIT*/ { isc_commit_transaction (isc_status, (FB_API_HANDLE*) &gds_trans);; /*ON_ERROR*/ if (isc_status [1]) { return_error(user_status); /*END_ERROR;*/ } } }
int main(int argc, char** argv) { if (argc != 2) { printf("Usage: %s <new db name>\n", argv[0]); return -1; } ISC_STATUS_ARRAY sv; isc_db_handle db = 0; isc_tr_handle tr = 0; isc_create_database(sv, 0, argv[1], &db, 0, 0, 0); if (sv[0] == 1 && sv[1] > 0) { isc_print_status(sv); return -2; } isc_start_transaction(sv, &tr, 1, &db, 0, 0); if (sv[0] == 1 && sv[1] > 0) { isc_print_status(sv); return -3; } isc_commit_transaction(sv, &tr); if (sv[0] == 1 && sv[1] > 0) { isc_print_status(sv); return -3; } isc_detach_database(sv, &db); if (sv[0] == 1 && sv[1] > 0) { isc_print_status(sv); return -3; } Firebird::ClumpletWriter dpb(Firebird::ClumpletReader::Tagged, MAX_DPB_SIZE, isc_dpb_version1); dpb.insertByte(isc_dpb_set_db_readonly, TRUE); isc_attach_database(sv, 0, argv[1], &db, dpb.getBufferLength(), reinterpret_cast<const char*>(dpb.getBuffer())); if (sv[0] == 1 && sv[1] > 0) { isc_print_status(sv); return -4; } isc_detach_database(sv, &db); if (sv[0] == 1 && sv[1] > 0) { isc_print_status(sv); return -5; } return 0; }
int execute( char * exec_str ) { isc_tr_handle trans = NULL; long status[ 20 ]; if( isc_start_transaction( status, &trans, 1, &db, 0, NULL ) ) ERREXIT( status, 1 ); if( isc_dsql_execute_immediate( status, &db, &trans, 0, exec_str, dialect, NULL ) ) ERREXIT( status, 1 ); if( isc_commit_transaction( status, &trans ) ) ERREXIT( status, 1 ); return 1; }
tdr* MET_get_transaction(ISC_STATUS* user_status, isc_db_handle handle, SLONG id) { struct isc_9_struct { ISC_QUAD isc_10; /* RDB$TRANSACTION_DESCRIPTION */ short isc_11; /* isc_utility */ } isc_9; struct isc_7_struct { ISC_LONG isc_8; /* RDB$TRANSACTION_ID */ } isc_7; FB_API_HANDLE request = 0; tdr* trans = NULL; AliceGlobals* tdgbl = AliceGlobals::getSpecific(); if (!(DB = handle)) return 0; /*START_TRANSACTION*/ { { isc_start_transaction (isc_status, (FB_API_HANDLE*) &gds_trans, (short) 1, &DB, (short) 0, (char*) 0); }; /*ON_ERROR*/ if (isc_status [1]) { return_error(user_status); /*END_ERROR;*/ } } const USHORT capabilities = get_capabilities(user_status); if (capabilities & CAP_transactions) { /*FOR(REQUEST_HANDLE request) TRA IN RDB$TRANSACTIONS WITH TRA.RDB$TRANSACTION_ID = id AND TRA.RDB$TRANSACTION_DESCRIPTION NOT MISSING*/ { if (!request) isc_compile_request (isc_status, (FB_API_HANDLE*) &DB, (FB_API_HANDLE*) &request, (short) sizeof(isc_6), (char*) isc_6); isc_7.isc_8 = id; if (request) isc_start_and_send (isc_status, (FB_API_HANDLE*) &request, (FB_API_HANDLE*) &gds_trans, (short) 0, (short) 4, &isc_7, (short) 0); if (!isc_status [1]) { while (1) { isc_receive (isc_status, (FB_API_HANDLE*) &request, (short) 1, (short) 10, &isc_9, (short) 0); if (!isc_9.isc_11 || isc_status [1]) break; trans = get_description(&/*TRA.RDB$TRANSACTION_DESCRIPTION*/ isc_9.isc_10); /*END_FOR*/ } }; /*ON_ERROR*/ if (isc_status [1]) { return_error(user_status); /*END_ERROR;*/ } } isc_release_request(gds_status, &request); if (gds_status[1]) { return_error(user_status); } } /*ROLLBACK*/ { isc_rollback_transaction (isc_status, (FB_API_HANDLE*) &gds_trans);; /*ON_ERROR*/ if (isc_status [1]) { return_error(user_status); /*END_ERROR;*/ } } if (trans) trans->tdr_db_caps = capabilities; return trans; }
void MET_get_state(ISC_STATUS* user_status, tdr* trans) { struct isc_15_struct { short isc_16; /* isc_utility */ short isc_17; /* RDB$TRANSACTION_STATE */ } isc_15; struct isc_13_struct { ISC_LONG isc_14; /* RDB$TRANSACTION_ID */ } isc_13; FB_API_HANDLE request = 0; AliceGlobals* tdgbl = AliceGlobals::getSpecific(); if (!(DB = trans->tdr_db_handle) || !(trans->tdr_db_caps & CAP_transactions)) { trans->tdr_state = TRA_unknown; return; } /*START_TRANSACTION*/ { { isc_start_transaction (isc_status, (FB_API_HANDLE*) &gds_trans, (short) 1, &DB, (short) 0, (char*) 0); }; /*ON_ERROR*/ if (isc_status [1]) { return_error(user_status); /*END_ERROR;*/ } } /*FOR(REQUEST_HANDLE request) TRA IN RDB$TRANSACTIONS WITH TRA.RDB$TRANSACTION_ID = trans->tdr_id*/ { if (!request) isc_compile_request (isc_status, (FB_API_HANDLE*) &DB, (FB_API_HANDLE*) &request, (short) sizeof(isc_12), (char*) isc_12); isc_13.isc_14 = trans->tdr_id; if (request) isc_start_and_send (isc_status, (FB_API_HANDLE*) &request, (FB_API_HANDLE*) &gds_trans, (short) 0, (short) 4, &isc_13, (short) 0); if (!isc_status [1]) { while (1) { isc_receive (isc_status, (FB_API_HANDLE*) &request, (short) 1, (short) 4, &isc_15, (short) 0); if (!isc_15.isc_16 || isc_status [1]) break; trans->tdr_state = /*TRA.RDB$TRANSACTION_STATE*/ isc_15.isc_17; /*END_FOR*/ } }; /*ON_ERROR*/ if (isc_status [1]) { return_error(user_status); /*END_ERROR;*/ } } isc_release_request(gds_status, &request); if (gds_status[1]) { return_error(user_status); } /*ROLLBACK*/ { isc_rollback_transaction (isc_status, (FB_API_HANDLE*) &gds_trans);; /*ON_ERROR*/ if (isc_status [1]) { return_error(user_status); /*END_ERROR;*/ } } }
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; }
/* ** Creates and returns a connection object ** Lua Input: source, user, pass ** source: data source ** user, pass: data source authentication information ** Lua Returns: ** connection object if successfull ** nil and error message otherwise. */ static int env_connect (lua_State *L) { char *dpb; int i; static char isc_tpb[] = { isc_tpb_version3, isc_tpb_write }; conn_data conn; conn_data* res_conn; env_data *env = (env_data *) getenvironment (L, 1); const char *sourcename = luaL_checkstring (L, 2); const char *username = luaL_optstring (L, 3, ""); const char *password = luaL_optstring (L, 4, ""); conn.env = env; conn.db = 0L; conn.transaction = 0L; conn.lock = 0; conn.autocommit = 0; /* Construct a database parameter buffer. */ dpb = conn.dpb_buffer; *dpb++ = isc_dpb_version1; *dpb++ = isc_dpb_num_buffers; *dpb++ = 1; *dpb++ = 90; /* add the user name and password */ *dpb++ = isc_dpb_user_name; *dpb++ = (char)strlen(username); for(i=0; i<(int)strlen(username); i++) *dpb++ = username[i]; *dpb++ = isc_dpb_password; *dpb++ = (char)strlen(password); for(i=0; i<(int)strlen(password); i++) *dpb++ = password[i]; /* the length of the dpb */ conn.dpb_length = (short)(dpb - conn.dpb_buffer); /* do the job */ isc_attach_database(env->status_vector, (short)strlen(sourcename), (char*)sourcename, &conn.db, conn.dpb_length, conn.dpb_buffer); /* an error? */ if ( CHECK_DB_ERROR(conn.env->status_vector) ) return return_db_error(L, conn.env->status_vector); /* open up the transaction handle */ isc_start_transaction( env->status_vector, &conn.transaction, 1, &conn.db, (unsigned short)sizeof(isc_tpb), isc_tpb ); /* return NULL on error */ if ( CHECK_DB_ERROR(conn.env->status_vector) ) return return_db_error(L, conn.env->status_vector); /* create the lua object and add the connection to the lock */ res_conn = (conn_data*)lua_newuserdata(L, sizeof(conn_data)); luasql_setmeta (L, LUASQL_CONNECTION_FIREBIRD); memcpy(res_conn, &conn, sizeof(conn_data)); res_conn->closed = 0; /* connect now officially open */ /* register the connection */ lua_registerobj(L, 1, env); ++env->lock; 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; }
int _dbd_real_connect(dbi_conn_t *conn, char *enc) { char dpb_buffer[256], *dpb, *p, *fb_encoding; char dbase[256]; short dpb_length; char db_fullpath[PATH_MAX]; isc_db_handle db = 0L; /* database handle */ isc_tr_handle trans = 0L; /* transaction handle */ ibase_conn_t *iconn = (ibase_conn_t * ) malloc(sizeof(ibase_conn_t)); ISC_STATUS status_vector[ISC_STATUS_LENGTH]; const char *dbname = dbi_conn_get_option(conn, "dbname"); const char *host = dbi_conn_get_option(conn, "host"); const char *username = dbi_conn_get_option(conn, "username"); const char *password = dbi_conn_get_option(conn, "password"); const char *encoding = dbi_conn_get_option(conn, "encoding"); if(encoding == NULL || *encoding == '\0') encoding = "NONE"; dpb = dpb_buffer; *dpb++ = isc_dpb_version1; *dpb++ = isc_dpb_num_buffers; *dpb++ = 1; *dpb++ = 90; *dpb++ = isc_dpb_user_name; *dpb++ = strlen(username); for (p = (char*)username; *p; *dpb++ = *p++); *dpb++ = isc_dpb_password; *dpb++ = strlen(password); for (p = (char*)password; *p; *dpb++ = *p++); *dpb++ = isc_dpb_lc_ctype; fb_encoding = (char*)dbd_encoding_from_iana(encoding); *dpb++ = strlen(fb_encoding); for (p = fb_encoding; *p; *dpb++ = *p++); dpb_length = dpb - dpb_buffer; dpb = dpb_buffer; /* could be used here, but is tagged deprecated */ /* isc_expand_dpb(&dpb, &dpb_length, */ /* isc_dpb_user_name, username, */ /* isc_dpb_password, password, */ /* isc_dpb_lc_ctype, dbd_encoding_from_iana(encoding), */ /* NULL); */ if (!dbname) { _dbd_internal_error_handler(conn, "no database specified", DBI_ERROR_DBD); return -1; } _firebird_populate_db_string( conn, dbname, db_fullpath ); if (host == NULL || !*host) { snprintf(dbase, 256, "%s", db_fullpath); } else { snprintf(dbase, 256, "%s:%s", host, db_fullpath); } /* printf("dbase went to: %s<<; host: %s, username: %s, passwd: %s, encoding: %s; dbp:%s<<\n", dbase, host, username, password, encoding, dpb); */ /* fflush(stdout); */ isc_attach_database(status_vector, strlen(dbase), dbase, &db, dpb_length, dpb); if (status_vector[0] == 1 && status_vector[1]) { char msg[512]; long* pvector = status_vector; dealocate_iconn( iconn ); isc_interprete(msg, &pvector); _dbd_internal_error_handler(conn, msg, DBI_ERROR_DBD); return -1; } else { isc_start_transaction(status_vector, &trans, 1, &db, 0, NULL); } iconn->trans = trans; iconn->db = db; iconn->charset = strdup(encoding); conn->connection = (void *)iconn; if (dbase) conn->current_db = strdup(dbase); return 0; }
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) } }