Subject | Re: [IB-Architect] Architecture of interclient |
---|---|
Author | Jim Starkey |
Post date | 2001-02-20T20:23:47Z |
At 02:59 PM 2/20/01 -0500, David Jencks wrote:
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
>Firebird || network | Firebird JDBC | thin JDBC | Java program
>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?
>
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