Пример #1
0
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;*/
	   }
	}
}
Пример #2
0
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;
}
Пример #3
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;*/
	   }
	}
}
Пример #4
0
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;
}
Пример #5
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;
}
Пример #6
0
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;
}
Пример #7
0
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;*/
	   }
	}
}
Пример #8
0
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;
    }
Пример #9
0
/*
** 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;
}
Пример #10
0
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;
}
Пример #11
0
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;
}
Пример #12
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 */
    }
}
Пример #13
0
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)
            }
        }