Subject RE: [IB-Architect] Architecture of interclient
Author Ken Richard
In other words - you have to have the firebird client "native" installed at
the workstation to use the JDBC driver. This is fine with me because I am
developing server applications and my server will be on the same box as the
firebird server. The thinner JDBC client is to my advantage.

Unfortunately, some people may like the zero-client-install of

Will there be a time that we can reuse the existing work-in-progress c++ api
as the foundation for a new JDBC driver?

-----Original Message-----
From: Jim Starkey [mailto:jas@...]
Sent: Tuesday, February 20, 2001 3:24 PM
Subject: Re: [IB-Architect] Architecture of interclient

At 02:59 PM 2/20/01 -0500, David Jencks wrote:
>As I understand it interclient is now
>(1) firebird || interserver | network | interclient/rest of java program
>It seems there is one too many process here.
>Are you proposing
>(2) firebird + C++ ODBC | network | thin JDBC + rest of java program
>(3) firebird | network | C++ ODBC / JNI-JDBC + rest of java program
>or something else?

Firebird || network | Firebird JDBC | thin JDBC | Java program

Everything up to the Firebird client library is in the same
process. The Firebird client library, obviously, connects
to a server somewhere. Or maybe runs classic in the same

Here is the order of battle for a Java JDBC call, say

PreparedStatement statement = connection.prepareStatement (
"select * from yachts");

1. Somebody calls the prepareStatement method in class
that implements the interface java.sql.Connection.

2. The Connection.prepareStatement method calls a native
method in the same class, supplying an handle styled
as an int.

3. The JVM passes the native call to C++ function in
an external dynamically loaded library.

4. The C++ function decodes the Java string, casts
the "handle" to C++ connection object, and invokes
the "prepareStatement" method. The C++ object pointer
is defined as a virtual class, analogous to a Java
interface; the function isn't doesn't know who it's
calling. In this case, it's calling

5. See below.

6. See below.

PreparedStatement* FireBirdConnection::prepareStatement(const char *
FireBirdPreparedStatement *statement = NULL;

statement = new FireBirdPreparedStatement (this);
statement->prepare (sqlString);
catch (...)
if (statement)
delete statement;

return statement;

void FireBirdStatement::prepareStatement(const char * sqlString)
sql = sqlString;

// Make sure we have a transaction started. Allocate a statement.

void *transHandle = connection->startTransaction();
ISC_STATUS statusVector [20];
isc_dsql_allocate_statement (statusVector, &connection->databaseHandle,

if (statusVector [1])

// Prepare dynamic SQL statement. Make first attempt to get parameters

int dialect = connection->getDialect();
isc_dsql_prepare (statusVector, &transHandle, &statementHandle,
0, (char*) sqlString, dialect, outputSqlda);

if (statusVector [1])

// If we didn't allocate a large enough SQLDA, try again.

if (outputSqlda.checkOverflow())
isc_dsql_describe (statusVector, &statementHandle, 1, outputSqlda);
if (statusVector [1])

numberColumns = outputSqlda.getColumnCount();
XSQLVAR *var = outputSqlda.sqlda->sqlvar;
insertCount = deleteCount = updateCount = 0;


Jim Starkey

To unsubscribe from this group, send an email to: