Subject Re: [IB-Architect] Architecture of interclient
Author Jim Starkey
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