Subject Re: [Firebird-Architect] XSQLDA/XSQLVAR issues
Author Jim Starkey
Nando Dessena wrote:

>J> I favor throwing an exception object as an open ended solution. I've
>J> never liked the magic 20 words of status vector even though I was
>J> responsible for it. What's the right number? Simple, there isn't a
>J> right number.
>I have a hard time telling whether you are talking architecture or
>details. An exception is not the solution to the fact that the status
>vector has fixed length; a variable length status vector would be the
>solution to that problem. The problems solved by exceptions are known
>and I'm all for using them. Except that I don't fully understand how
>to do it. :-) Using a callback is a viable idea, but since exceptions
>are allocated at throw time and freed at catch time I wonder who's
>going to allocate and free your callback-based exception objects. This
>is not a new problem, though.
Throwing an exception (e.g. passing an exception object to a callback to
throw) is an escape from the fixed length status vector. The existing
API is stuck with the 20 longword status vector, but future user APIs
are not. The new exception object must have a method to produce a
legacy 20 longword status vector, but usage through the JDBC APIs (both
Java and C++) would throw a SQLException object with methods to return
the primary status code and the full interpreted string.

Exception object lifetime is very simple to handle. Exception objects
are allocated locally (i.e. on the stack) and disappear (after the
destructors are called) during unwind. This is the way virtually all
C++ exceptions are handled. Java requires an exception object to be
explicitly allocated for the garbage collector to clean up when it
becomes unloved and unwanted.

The new API should define a single exception pseudo-object as a simple C
structure with a virtual function vector and extern "C" methods plus a
C++ exception class wrapper. A typical callback function might look
like this:

static void exceptionCallback (FBException *exception)
throw SQLException (exception);

where FBException was the POD (plain old data) exception pseudo-object
and SQLException the C++ wrapper. As long as the function above is
compiled with the same compiler as the rest of the application code,
which could be different from whatever Firebird was compiled with,
exceptions will work as excepted in the application code.