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
>
>or
>
>(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
process.

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
FireBirdConnection::prepareStatement().

5. See below.

6. See below.

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

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

return statement;
}

void FireBirdStatement::prepareStatement(const char * sqlString)
{
clearResults();
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,
&statementHandle);

if (statusVector [1])
THROW_ISC_EXCEPTION (statusVector);

// 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])
THROW_ISC_EXCEPTION (statusVector);

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

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

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

--------------------------------------------------------------------


Jim Starkey