8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-02-02 10:00:38 +01:00

Unifying the external engines API with the new ones.

This commit is contained in:
asfernandes 2013-02-15 02:48:54 +00:00
parent d88daeb645
commit 491fdd82b2
11 changed files with 346 additions and 684 deletions

View File

@ -589,10 +589,10 @@ FB_UDR_BEGIN_FUNCTION(wait_event)
isc_db_handle dbHandle = getIscDbHandle(context);
ISC_ULONG counter = 0;
ThrowError::check(isc_wait_for_event(statusVector, &dbHandle, eveLen, eveBuffer, eveResult),
StatusException::check(isc_wait_for_event(statusVector, &dbHandle, eveLen, eveBuffer, eveResult),
statusVector);
isc_event_counts(&counter, eveLen, eveBuffer, eveResult);
ThrowError::check(isc_wait_for_event(statusVector, &dbHandle, eveLen, eveBuffer, eveResult),
StatusException::check(isc_wait_for_event(statusVector, &dbHandle, eveLen, eveBuffer, eveResult),
statusVector);
isc_event_counts(&counter, eveLen, eveBuffer, eveResult);
@ -616,13 +616,13 @@ create function sum_args (
FB_UDR_BEGIN_FUNCTION(sum_args)
FB_UDR_EXECUTE_DYNAMIC_FUNCTION
{
AutoDispose<IStatus> status(master->getStatus());
///AutoDispose<IStatus> status(master->getStatus());
const IParametersMetadata* params = metadata->getInputParameters(status);
ThrowError::check(status->get());
StatusException::check(status->get());
unsigned count = params->getCount(status);
ThrowError::check(status->get());
StatusException::check(status->get());
MessageImpl inMessage(count, in);
@ -859,13 +859,13 @@ FB_UDR_BEGIN_TRIGGER(replicate)
FB_UDR_EXECUTE_DYNAMIC_TRIGGER
{
AutoDispose<IStatus> status(master->getStatus());
///AutoDispose<IStatus> status(master->getStatus());
const IParametersMetadata* fields = metadata->getTriggerFields(status);
ThrowError::check(status->get());
StatusException::check(status->get());
unsigned fieldsCount = fields->getCount(status);
ThrowError::check(status->get());
StatusException::check(status->get());
MessageImpl message(fieldsCount, newFields);
@ -888,7 +888,7 @@ FB_UDR_BEGIN_TRIGGER(replicate)
}
}
ThrowError::check(isc_dsql_execute(statusVector, &trHandle, &stmtHandle, SQL_DIALECT_CURRENT,
StatusException::check(isc_dsql_execute(statusVector, &trHandle, &stmtHandle, SQL_DIALECT_CURRENT,
inSqlDa), statusVector);
}
@ -899,19 +899,19 @@ FB_UDR_BEGIN_TRIGGER(replicate)
isc_tr_handle trHandle = getIscTrHandle(context);
stmtHandle = 0;
ThrowError::check(isc_dsql_allocate_statement(statusVector, &dbHandle, &stmtHandle), statusVector);
ThrowError::check(isc_dsql_prepare(statusVector, &trHandle, &stmtHandle, 0,
StatusException::check(isc_dsql_allocate_statement(statusVector, &dbHandle, &stmtHandle), statusVector);
StatusException::check(isc_dsql_prepare(statusVector, &trHandle, &stmtHandle, 0,
"select data_source from replicate_config where name = ?",
SQL_DIALECT_CURRENT, NULL), statusVector);
AutoDispose<IStatus> status(master->getStatus());
///AutoDispose<IStatus> status(master->getStatus());
const char* table = metadata->getTriggerTable(status);
ThrowError::check(status->get());
StatusException::check(status->get());
// Skip the first exclamation point, separating the module name and entry point.
const char* info = strchr(metadata->getEntryPoint(status), '!');
ThrowError::check(status->get());
StatusException::check(status->get());
// Skip the second exclamation point, separating the entry point and the misc info (config).
if (info)
@ -925,7 +925,7 @@ FB_UDR_BEGIN_TRIGGER(replicate)
inSqlDa = reinterpret_cast<XSQLDA*>(new char[(XSQLDA_LENGTH(1))]);
inSqlDa->version = SQLDA_VERSION1;
inSqlDa->sqln = 1;
ThrowError::check(isc_dsql_describe_bind(statusVector, &stmtHandle, SQL_DIALECT_CURRENT, inSqlDa),
StatusException::check(isc_dsql_describe_bind(statusVector, &stmtHandle, SQL_DIALECT_CURRENT, inSqlDa),
statusVector);
inSqlDa->sqlvar[0].sqldata = new char[sizeof(short) + inSqlDa->sqlvar[0].sqllen];
strncpy(inSqlDa->sqlvar[0].sqldata + sizeof(short), info, inSqlDa->sqlvar[0].sqllen);
@ -934,24 +934,24 @@ FB_UDR_BEGIN_TRIGGER(replicate)
XSQLDA* outSqlDa = reinterpret_cast<XSQLDA*>(new char[(XSQLDA_LENGTH(1))]);
outSqlDa->version = SQLDA_VERSION1;
outSqlDa->sqln = 1;
ThrowError::check(isc_dsql_describe(statusVector, &stmtHandle, SQL_DIALECT_CURRENT, outSqlDa),
StatusException::check(isc_dsql_describe(statusVector, &stmtHandle, SQL_DIALECT_CURRENT, outSqlDa),
statusVector);
outSqlDa->sqlvar[0].sqldata = new char[sizeof(short) + outSqlDa->sqlvar[0].sqllen + 1];
outSqlDa->sqlvar[0].sqldata[sizeof(short) + outSqlDa->sqlvar[0].sqllen] = '\0';
ThrowError::check(isc_dsql_execute2(statusVector, &trHandle, &stmtHandle, SQL_DIALECT_CURRENT,
StatusException::check(isc_dsql_execute2(statusVector, &trHandle, &stmtHandle, SQL_DIALECT_CURRENT,
inSqlDa, outSqlDa), statusVector);
ThrowError::check(isc_dsql_free_statement(statusVector, &stmtHandle, DSQL_unprepare), statusVector);
StatusException::check(isc_dsql_free_statement(statusVector, &stmtHandle, DSQL_unprepare), statusVector);
delete [] inSqlDa->sqlvar[0].sqldata;
delete [] reinterpret_cast<char*>(inSqlDa);
inSqlDa = NULL;
const IParametersMetadata* fields = metadata->getTriggerFields(status);
ThrowError::check(status->get());
StatusException::check(status->get());
unsigned count = fields->getCount(status);
ThrowError::check(status->get());
StatusException::check(status->get());
char buffer[65536];
strcpy(buffer, "execute block (\n");
@ -962,7 +962,7 @@ FB_UDR_BEGIN_TRIGGER(replicate)
strcat(buffer, ",\n");
const char* name = fields->getField(status, i);
ThrowError::check(status->get());
StatusException::check(status->get());
strcat(buffer, " p");
sprintf(buffer + strlen(buffer), "%d type of column \"%s\".\"%s\" = ?", i, table, name);
@ -983,7 +983,7 @@ FB_UDR_BEGIN_TRIGGER(replicate)
strcat(buffer, ", ");
const char* name = fields->getField(status, i);
ThrowError::check(status->get());
StatusException::check(status->get());
strcat(buffer, "\"");
strcat(buffer, name);
@ -1013,13 +1013,13 @@ FB_UDR_BEGIN_TRIGGER(replicate)
strcat(buffer, outSqlDa->sqlvar[0].sqldata + sizeof(short));
strcat(buffer, "';\nend");
ThrowError::check(isc_dsql_prepare(statusVector, &trHandle, &stmtHandle, 0, buffer,
StatusException::check(isc_dsql_prepare(statusVector, &trHandle, &stmtHandle, 0, buffer,
SQL_DIALECT_CURRENT, NULL), statusVector);
inSqlDa = reinterpret_cast<XSQLDA*>(new char[(XSQLDA_LENGTH(count))]);
inSqlDa->version = SQLDA_VERSION1;
inSqlDa->sqln = count;
ThrowError::check(isc_dsql_describe_bind(statusVector, &stmtHandle, SQL_DIALECT_CURRENT, inSqlDa),
StatusException::check(isc_dsql_describe_bind(statusVector, &stmtHandle, SQL_DIALECT_CURRENT, inSqlDa),
statusVector);
for (unsigned i = 0; i < count; ++i)
@ -1128,7 +1128,7 @@ FB_UDR_BEGIN_TRIGGER(replicate_persons)
isc_db_handle dbHandle = getIscDbHandle(context);
isc_tr_handle trHandle = getIscTrHandle(context);
ThrowError::check(isc_dsql_execute(statusVector, &trHandle, &stmtHandle, SQL_DIALECT_CURRENT,
StatusException::check(isc_dsql_execute(statusVector, &trHandle, &stmtHandle, SQL_DIALECT_CURRENT,
inSqlDa), statusVector);
}
@ -1139,19 +1139,19 @@ FB_UDR_BEGIN_TRIGGER(replicate_persons)
isc_tr_handle trHandle = getIscTrHandle(context);
stmtHandle = 0;
ThrowError::check(isc_dsql_allocate_statement(statusVector, &dbHandle, &stmtHandle), statusVector);
ThrowError::check(isc_dsql_prepare(statusVector, &trHandle, &stmtHandle, 0,
StatusException::check(isc_dsql_allocate_statement(statusVector, &dbHandle, &stmtHandle), statusVector);
StatusException::check(isc_dsql_prepare(statusVector, &trHandle, &stmtHandle, 0,
"select data_source from replicate_config where name = ?",
SQL_DIALECT_CURRENT, NULL), statusVector);
AutoDispose<IStatus> status(master->getStatus());
///AutoDispose<IStatus> status(master->getStatus());
const char* table = metadata->getTriggerTable(status);
ThrowError::check(status->get());
StatusException::check(status->get());
// Skip the first exclamation point, separating the module name and entry point.
const char* info = strchr(metadata->getEntryPoint(status), '!');
ThrowError::check(status->get());
StatusException::check(status->get());
// Skip the second exclamation point, separating the entry point and the misc info (config).
if (info)
@ -1165,7 +1165,7 @@ FB_UDR_BEGIN_TRIGGER(replicate_persons)
inSqlDa = reinterpret_cast<XSQLDA*>(new char[(XSQLDA_LENGTH(1))]);
inSqlDa->version = SQLDA_VERSION1;
inSqlDa->sqln = 1;
ThrowError::check(isc_dsql_describe_bind(statusVector, &stmtHandle, SQL_DIALECT_CURRENT, inSqlDa),
StatusException::check(isc_dsql_describe_bind(statusVector, &stmtHandle, SQL_DIALECT_CURRENT, inSqlDa),
statusVector);
inSqlDa->sqlvar[0].sqldata = new char[sizeof(short) + inSqlDa->sqlvar[0].sqllen];
strncpy(inSqlDa->sqlvar[0].sqldata + sizeof(short), info, inSqlDa->sqlvar[0].sqllen);
@ -1174,24 +1174,24 @@ FB_UDR_BEGIN_TRIGGER(replicate_persons)
XSQLDA* outSqlDa = reinterpret_cast<XSQLDA*>(new char[(XSQLDA_LENGTH(1))]);
outSqlDa->version = SQLDA_VERSION1;
outSqlDa->sqln = 1;
ThrowError::check(isc_dsql_describe(statusVector, &stmtHandle, SQL_DIALECT_CURRENT, outSqlDa),
StatusException::check(isc_dsql_describe(statusVector, &stmtHandle, SQL_DIALECT_CURRENT, outSqlDa),
statusVector);
outSqlDa->sqlvar[0].sqldata = new char[sizeof(short) + outSqlDa->sqlvar[0].sqllen + 1];
outSqlDa->sqlvar[0].sqldata[sizeof(short) + outSqlDa->sqlvar[0].sqllen] = '\0';
ThrowError::check(isc_dsql_execute2(statusVector, &trHandle, &stmtHandle, SQL_DIALECT_CURRENT,
StatusException::check(isc_dsql_execute2(statusVector, &trHandle, &stmtHandle, SQL_DIALECT_CURRENT,
inSqlDa, outSqlDa), statusVector);
ThrowError::check(isc_dsql_free_statement(statusVector, &stmtHandle, DSQL_unprepare), statusVector);
StatusException::check(isc_dsql_free_statement(statusVector, &stmtHandle, DSQL_unprepare), statusVector);
delete [] inSqlDa->sqlvar[0].sqldata;
delete [] reinterpret_cast<char*>(inSqlDa);
inSqlDa = NULL;
const IParametersMetadata* fields = metadata->getTriggerFields(status);
ThrowError::check(status->get());
StatusException::check(status->get());
unsigned count = fields->getCount(status);
ThrowError::check(status->get());
StatusException::check(status->get());
char buffer[65536];
strcpy(buffer,
@ -1209,13 +1209,13 @@ FB_UDR_BEGIN_TRIGGER(replicate_persons)
strcat(buffer, outSqlDa->sqlvar[0].sqldata + sizeof(short));
strcat(buffer, "';\nend");
ThrowError::check(isc_dsql_prepare(statusVector, &trHandle, &stmtHandle, 0, buffer,
StatusException::check(isc_dsql_prepare(statusVector, &trHandle, &stmtHandle, 0, buffer,
SQL_DIALECT_CURRENT, NULL), statusVector);
inSqlDa = reinterpret_cast<XSQLDA*>(new char[(XSQLDA_LENGTH(4))]);
inSqlDa->version = SQLDA_VERSION1;
inSqlDa->sqln = 4;
ThrowError::check(isc_dsql_describe_bind(statusVector, &stmtHandle, SQL_DIALECT_CURRENT, inSqlDa),
StatusException::check(isc_dsql_describe_bind(statusVector, &stmtHandle, SQL_DIALECT_CURRENT, inSqlDa),
statusVector);
for (unsigned i = 0; i < 4; ++i)

View File

@ -61,20 +61,12 @@ typedef void* Handle;
#endif
class Error
{
public:
virtual bool FB_CALL addCode(int32 code) = 0;
virtual bool FB_CALL addString(const char* str, uint strLength) = 0;
};
// Interface used in cases which an instance is created by one layer and released by another one.
class Disposable
{
public:
// Disposes the object.
virtual void FB_CALL dispose(Error* error) = 0;
virtual void FB_CALL dispose() = 0;
};

View File

@ -64,15 +64,18 @@ public:
class ExternalContext
{
public:
// Gets the IMaster associated with this context.
virtual IMaster* FB_CALL getMaster() = 0;
// Gets the ExternalEngine associated with this context.
virtual ExternalEngine* FB_CALL getEngine(Error* error) = 0;
virtual ExternalEngine* FB_CALL getEngine(IStatus* status) = 0;
// Gets the Attachment associated with this context.
virtual IAttachment* FB_CALL getAttachment(Error* error) = 0;
virtual IAttachment* FB_CALL getAttachment(IStatus* status) = 0;
// Obtained transaction is valid only before control is returned to the engine
// or in ExternalResultSet::fetch calls of correspondent ExternalProcedure::open.
virtual ITransaction* FB_CALL getTransaction(Error* error) = 0;
virtual ITransaction* FB_CALL getTransaction(IStatus* status) = 0;
virtual const char* FB_CALL getUserName() = 0;
virtual const char* FB_CALL getDatabaseName() = 0;
@ -95,7 +98,7 @@ public:
class ExternalResultSet : public Disposable
{
public:
virtual bool FB_CALL fetch(Error* error) = 0;
virtual bool FB_CALL fetch(IStatus* status) = 0;
};
@ -105,10 +108,10 @@ public:
// This method is called just before execute and informs the engine our requested character
// set for data exchange inside that method.
// During this call, the context uses the character set obtained from ExternalEngine::getCharSet.
virtual void FB_CALL getCharSet(Error* error, ExternalContext* context,
virtual void FB_CALL getCharSet(IStatus* status, ExternalContext* context,
Utf8* name, uint nameSize) = 0;
virtual void FB_CALL execute(Error* error, ExternalContext* context,
virtual void FB_CALL execute(IStatus* status, ExternalContext* context,
void* inMsg, void* outMsg) = 0;
};
@ -119,13 +122,13 @@ public:
// This method is called just before open and informs the engine our requested character
// set for data exchange inside that method and ExternalResultSet::fetch.
// During this call, the context uses the character set obtained from ExternalEngine::getCharSet.
virtual void FB_CALL getCharSet(Error* error, ExternalContext* context,
virtual void FB_CALL getCharSet(IStatus* status, ExternalContext* context,
Utf8* name, uint nameSize) = 0;
// Returns a ExternalResultSet for selectable procedures.
// Returning NULL results in a result set of one record.
// Procedures without output parameters should return NULL.
virtual ExternalResultSet* FB_CALL open(Error* error, ExternalContext* context,
virtual ExternalResultSet* FB_CALL open(IStatus* status, ExternalContext* context,
void* inMsg, void* outMsg) = 0;
};
@ -157,10 +160,10 @@ public:
// This method is called just before execute and informs the engine our requested character
// set for data exchange inside that method.
// During this call, the context uses the character set obtained from ExternalEngine::getCharSet.
virtual void FB_CALL getCharSet(Error* error, ExternalContext* context,
virtual void FB_CALL getCharSet(IStatus* status, ExternalContext* context,
Utf8* name, uint nameSize) = 0;
virtual void FB_CALL execute(Error* error, ExternalContext* context,
virtual void FB_CALL execute(IStatus* status, ExternalContext* context,
Action action, void* oldMsg, void* newMsg) = 0;
};
@ -190,22 +193,22 @@ public:
// The requested character set for data exchange inside methods of this interface should
// be copied to charSet parameter.
// During this call, the context uses the UTF-8 character set.
virtual void FB_CALL open(Error* error, ExternalContext* context,
virtual void FB_CALL open(IStatus* status, ExternalContext* context,
Utf8* charSet, uint charSetSize) = 0;
// Attachment is being opened.
virtual void FB_CALL openAttachment(Error* error, ExternalContext* context) = 0;
virtual void FB_CALL openAttachment(IStatus* status, ExternalContext* context) = 0;
// Attachment is being closed.
virtual void FB_CALL closeAttachment(Error* error, ExternalContext* context) = 0;
virtual void FB_CALL closeAttachment(IStatus* status, ExternalContext* context) = 0;
// Called when engine wants to load object in the cache. Objects are disposed when
// going out of the cache.
virtual ExternalFunction* FB_CALL makeFunction(Error* error, ExternalContext* context,
virtual ExternalFunction* FB_CALL makeFunction(IStatus* status, ExternalContext* context,
const IRoutineMetadata* metadata, IRoutineMessage* inMsg, IRoutineMessage* outMsg) = 0;
virtual ExternalProcedure* FB_CALL makeProcedure(Error* error, ExternalContext* context,
virtual ExternalProcedure* FB_CALL makeProcedure(IStatus* status, ExternalContext* context,
const IRoutineMetadata* metadata, IRoutineMessage* inMsg, IRoutineMessage* outMsg) = 0;
virtual ExternalTrigger* FB_CALL makeTrigger(Error* error, ExternalContext* context,
virtual ExternalTrigger* FB_CALL makeTrigger(IStatus* status, ExternalContext* context,
const IRoutineMetadata* metadata, ITriggerMessage* triggerMsg) = 0;
};
#define FB_EXTERNAL_ENGINE_VERSION (FB_PLUGIN_VERSION + 6)

View File

@ -53,7 +53,7 @@ namespace Firebird
class FB_UDR_FUNCTION(name) : public ::Firebird::Udr::Function<FB_UDR_FUNCTION(name)> \
{ \
public: \
void initialize(::Firebird::Error* error, void*) \
void initialize(::Firebird::IStatus* /*status*/, void*) \
{ \
}
@ -85,17 +85,17 @@ namespace Firebird
FB_UDR_EXECUTE__FUNCTION
#define FB_UDR_EXECUTE__FUNCTION \
virtual void FB_CALL execute(::Firebird::Error* error, ::Firebird::ExternalContext* context, \
virtual void FB_CALL execute(::Firebird::IStatus* status, ::Firebird::ExternalContext* context, \
void* in, void* out) \
{ \
try \
{ \
internalExecute(error, context, (InMessage*) in, (OutMessage*) out); \
internalExecute(status, context, (InMessage*) in, (OutMessage*) out); \
} \
FB_UDR__CATCH \
} \
\
void internalExecute(::Firebird::Error* error, ::Firebird::ExternalContext* context, \
void internalExecute(::Firebird::IStatus* status, ::Firebird::ExternalContext* context, \
InMessage* in, OutMessage* out)
@ -109,7 +109,7 @@ namespace Firebird
public: \
typedef FB_UDR_PROCEDURE(name) This; \
\
void initialize(::Firebird::Error* error, void*) \
void initialize(::Firebird::IStatus* /*status*/, void*) \
{ \
}
@ -150,12 +150,12 @@ namespace Firebird
FB_UDR_EXECUTE__PROCEDURE
#define FB_UDR_EXECUTE__PROCEDURE \
virtual ::Firebird::ExternalResultSet* FB_CALL open(::Firebird::Error* error, \
virtual ::Firebird::ExternalResultSet* FB_CALL open(::Firebird::IStatus* status, \
::Firebird::ExternalContext* context, void* in, void* out) \
{ \
try \
{ \
return new ResultSet(error, context, this, (InMessage*) in, (OutMessage*) out); \
return new ResultSet(status, context, this, (InMessage*) in, (OutMessage*) out); \
} \
FB_UDR__CATCH \
\
@ -165,24 +165,24 @@ namespace Firebird
class ResultSet : public ::Firebird::Udr::ResultSet<ResultSet, This, InMessage, OutMessage> \
{ \
public: \
ResultSet(::Firebird::Error* error, ::Firebird::ExternalContext* context, \
ResultSet(::Firebird::IStatus* status, ::Firebird::ExternalContext* context, \
This* const procedure, InMessage* const in, OutMessage* const out) \
: ::Firebird::Udr::ResultSet<ResultSet, This, InMessage, OutMessage>( \
context, procedure, in, out)
#define FB_UDR_FETCH_PROCEDURE \
virtual bool FB_CALL fetch(::Firebird::Error* error) \
virtual bool FB_CALL fetch(::Firebird::IStatus* status) \
{ \
try \
{ \
return internalFetch(error); \
return internalFetch(status); \
} \
FB_UDR__CATCH \
\
return 0; \
} \
\
bool internalFetch(::Firebird::Error* error)
bool internalFetch(::Firebird::IStatus* status)
#define FB_UDR_BEGIN_TRIGGER(name) \
@ -194,7 +194,7 @@ namespace Firebird
{ \
public: \
\
void initialize(::Firebird::Error* error, void*) \
void initialize(::Firebird::IStatus* /*status*/, void*) \
{ \
}
@ -214,161 +214,53 @@ namespace Firebird
FB_UDR_EXECUTE__TRIGGER
#define FB_UDR_EXECUTE__TRIGGER \
virtual void FB_CALL execute(::Firebird::Error* error, ::Firebird::ExternalContext* context, \
virtual void FB_CALL execute(::Firebird::IStatus* status, ::Firebird::ExternalContext* context, \
::Firebird::ExternalTrigger::Action action, void* oldFields, void* newFields) \
{ \
try \
{ \
internalExecute(error, context, action, (FieldsMessage*) oldFields, (FieldsMessage*) newFields); \
internalExecute(status, context, action, (FieldsMessage*) oldFields, (FieldsMessage*) newFields); \
} \
FB_UDR__CATCH \
} \
\
void internalExecute(::Firebird::Error* error, ::Firebird::ExternalContext* context, \
void internalExecute(::Firebird::IStatus* status, ::Firebird::ExternalContext* context, \
::Firebird::ExternalTrigger::Action action, FieldsMessage* oldFields, FieldsMessage* newFields)
#define FB_UDR_INITIALIZE \
void initialize(::Firebird::Error* error, ExternalContext* context) \
void initialize(::Firebird::IStatus* status, ExternalContext* context) \
{ \
try \
{ \
internalInitialize(error, context); \
internalInitialize(status, context); \
} \
FB_UDR__CATCH \
} \
\
void internalInitialize(::Firebird::Error* error, ::Firebird::ExternalContext* context)
void internalInitialize(::Firebird::IStatus* status, ::Firebird::ExternalContext* context)
#define FB_UDR__CATCH \
catch (const ::Firebird::Udr::ThrowError::Exception& e) \
catch (const ::Firebird::Udr::StatusException& e) \
{ \
e.stuff(error); \
e.stuff(status); \
} \
catch (...) \
{ \
const char exceptionText[] = "Unrecognized C++ exception"; \
\
error->addCode(isc_arg_gds); \
error->addCode(isc_random); \
error->addString(exceptionText, sizeof(exceptionText) - 1); \
ISC_STATUS statusVector[] = { \
isc_arg_gds, isc_random, isc_arg_string, (ISC_STATUS) "Unrecognized C++ exception", \
isc_arg_end}; \
status->set(statusVector); \
}
class ThrowError : public Error
class StatusException
{
private:
struct Info
{
Info()
: next(FB_NULL),
str(FB_NULL)
{
}
~Info()
{
if (str)
delete [] str;
}
static void free(Info* info)
{
while (info)
{
Info* p = info;
info = info->next;
delete p;
}
}
enum { TYPE_CODE, TYPE_STR } type;
Info* next;
int32 code;
char* str;
int strLength;
};
public:
class Exception
StatusException(const ISC_STATUS* vector)
{
public:
explicit Exception(Info* aInfo)
: info(aInfo)
{
}
Exception(const Exception& e)
: info(FB_NULL)
{
Info* end = FB_NULL;
for (const Info* p = e.info; p; p = p->next)
{
Info* newInfo = new Info;
newInfo->type = p->type;
newInfo->code = p->code;
if (p->str)
{
newInfo->str = new char[p->strLength];
memcpy(newInfo->str, p->str, p->strLength);
newInfo->strLength = p->strLength;
}
if (end)
end->next = newInfo;
end = newInfo;
if (!info)
info = newInfo;
}
}
~Exception()
{
Info::free(info);
}
public:
void stuff(Error* error) const
{
for (const Info* p = info; p; p = p->next)
{
if (p->type == Info::TYPE_CODE)
error->addCode(p->code);
else if (p->type == Info::TYPE_STR)
error->addString(p->str, p->strLength);
}
}
private:
Info* info;
};
public:
ThrowError()
: start(FB_NULL),
end(FB_NULL)
{
}
virtual ~ThrowError()
{
raise();
Info::free(start);
}
public:
static void check(ISC_STATUS status, const ISC_STATUS* vector)
{
if (status == 0)
return;
ThrowError error;
ISC_STATUS* p = statusVector;
while (*vector != isc_arg_end)
{
@ -381,84 +273,122 @@ public:
case isc_arg_vms:
case isc_arg_unix:
case isc_arg_win32:
error.addCode(*vector++);
error.addCode(*vector++);
*p++ = *vector++;
*p++ = *vector++;
break;
case isc_arg_string:
error.addString((const char*) vector[1], strlen((const char*) vector[1]));
vector += 2;
*p++ = *vector++;
*p++ = *vector++;
break;
case isc_arg_cstring:
error.addString((const char*) vector[2], vector[1]);
vector += 3;
*p++ = *vector++;
*p++ = *vector++;
*p++ = *vector++;
break;
default:
return;
}
}
*p = isc_arg_end;
}
public:
static void check(const ISC_STATUS* vector)
{
check(vector[1], vector);
if (vector[1])
throw StatusException(vector);
}
static void check(ISC_STATUS status, const ISC_STATUS* vector)
{
if (status == 0)
return;
check(vector);
}
public:
inline operator Firebird::Error* ()
const ISC_STATUS* getStatusVector() const
{
return this;
return statusVector;
}
public:
virtual bool FB_CALL addCode(Firebird::int32 code)
void stuff(IStatus* status) const
{
Info* info = new Info;
info->type = Info::TYPE_CODE;
info->code = code;
if (end)
end->next = info;
end = info;
if (!start)
start = info;
return true;
}
virtual bool FB_CALL addString(const char* str, uint strLength)
{
Info* info = new Info;
info->type = Info::TYPE_STR;
info->str = new char[strLength];
memcpy(info->str, str, strLength);
info->strLength = strLength;
if (end)
end->next = info;
end = info;
if (!start)
start = info;
return true;
status->set(statusVector);
}
private:
void raise()
ISC_STATUS_ARRAY statusVector;
};
class StatusImpl : public IStatus
{
public:
StatusImpl(IMaster* master)
: delegate(master->getStatus()),
success(true)
{
if (start)
throw Exception(start);
}
protected:
Info* start;
Info* end;
virtual int FB_CARG getVersion()
{
return FB_STATUS_VERSION;
}
virtual IPluginModule* FB_CARG getModule()
{
return NULL;
}
virtual void FB_CARG dispose()
{
delegate->dispose();
delete this;
}
virtual void FB_CARG set(unsigned int length, const ISC_STATUS* value)
{
delegate->set(length, value);
success = delegate->isSuccess();
}
virtual void FB_CARG set(const ISC_STATUS* value)
{
delegate->set(value);
success = delegate->isSuccess();
}
virtual void FB_CARG init()
{
delegate->init();
success = true;
}
virtual const ISC_STATUS* FB_CARG get() const
{
return delegate->get();
}
virtual int FB_CARG isSuccess() const
{
return success;
}
public:
void check()
{
if (!success)
StatusException::check(delegate->get());
}
private:
IStatus* delegate;
bool success;
};
@ -470,19 +400,33 @@ class Helper
public:
static isc_db_handle getIscDbHandle(ExternalContext* context)
{
ISC_STATUS_ARRAY status = {0};
StatusImpl status(context->getMaster());
IAttachment* attachment = context->getAttachment(&status);
status.check();
ISC_STATUS_ARRAY statusVector = {0};
isc_db_handle handle = 0;
fb_get_database_handle(status, &handle, context->getAttachment(ThrowError()));
ThrowError::check(status);
fb_get_database_handle(statusVector, &handle, attachment);
StatusException::check(statusVector);
return handle;
}
static isc_tr_handle getIscTrHandle(ExternalContext* context)
{
ISC_STATUS_ARRAY status = {0};
StatusImpl status(context->getMaster());
ITransaction* transaction = context->getTransaction(&status);
status.check();
ISC_STATUS_ARRAY statusVector = {0};
isc_tr_handle handle = 0;
fb_get_transaction_handle(status, &handle, context->getTransaction(ThrowError()));
ThrowError::check(status);
fb_get_transaction_handle(statusVector, &handle, transaction);
StatusException::check(statusVector);
return handle;
}
};
@ -492,7 +436,7 @@ template <typename This, typename Procedure, typename InMessage, typename OutMes
class ResultSet : public ExternalResultSet, public Helper
{
public:
ResultSet(Firebird::ExternalContext* aContext, Procedure* aProcedure,
ResultSet(ExternalContext* aContext, Procedure* aProcedure,
InMessage* aIn, OutMessage* aOut)
: context(aContext),
procedure(aProcedure),
@ -502,13 +446,13 @@ public:
}
public:
virtual void FB_CALL dispose(Firebird::Error* /*error*/)
virtual void FB_CALL dispose()
{
delete static_cast<This*>(this);
}
protected:
Firebird::ExternalContext* const context;
ExternalContext* const context;
Procedure* const procedure;
InMessage* const in;
OutMessage* const out;
@ -531,12 +475,12 @@ template <typename This>
class Function : public ExternalFunction, public Helper
{
public:
virtual void FB_CALL dispose(Error* /*error*/)
virtual void FB_CALL dispose()
{
delete static_cast<This*>(this);
}
virtual void FB_CALL getCharSet(Error* /*error*/, ExternalContext* /*context*/,
virtual void FB_CALL getCharSet(IStatus* /*status*/, ExternalContext* /*context*/,
Utf8* /*name*/, uint /*nameSize*/)
{
}
@ -562,12 +506,12 @@ template <typename This>
class Procedure : public ExternalProcedure, public Helper
{
public:
virtual void FB_CALL dispose(Error* /*error*/)
virtual void FB_CALL dispose()
{
delete static_cast<This*>(this);
}
virtual void FB_CALL getCharSet(Error* /*error*/, ExternalContext* /*context*/,
virtual void FB_CALL getCharSet(IStatus* /*status*/, ExternalContext* /*context*/,
Utf8* /*name*/, uint /*nameSize*/)
{
}
@ -593,12 +537,12 @@ template <typename This>
class Trigger : public ExternalTrigger, public Helper
{
public:
virtual void FB_CALL dispose(Error* /*error*/)
virtual void FB_CALL dispose()
{
delete static_cast<This*>(this);
}
virtual void FB_CALL getCharSet(Error* /*error*/, ExternalContext* /*context*/,
virtual void FB_CALL getCharSet(IStatus* /*status*/, ExternalContext* /*context*/,
Utf8* /*name*/, uint /*nameSize*/)
{
}
@ -628,18 +572,18 @@ public:
fbUdrRegFunction(name, this);
}
virtual void setup(Error* /*error*/, ExternalContext* /*context*/,
virtual void setup(IStatus* /*status*/, ExternalContext* /*context*/,
const IRoutineMetadata* /*metadata*/, IRoutineMessage* in, IRoutineMessage* out)
{
setBlr(in, (typename T::InMessage*) 0);
setBlr(out, (typename T::OutMessage*) 0);
}
virtual ExternalFunction* FB_CALL newItem(Error* error, ExternalContext* context,
virtual ExternalFunction* FB_CALL newItem(IStatus* status, ExternalContext* context,
const IRoutineMetadata* metadata)
{
T* obj = new(metadata) Routine<T>;
obj->initialize(error, context);
obj->initialize(status, context);
return obj;
}
@ -665,18 +609,18 @@ public:
fbUdrRegProcedure(name, this);
}
virtual void setup(Error* /*error*/, ExternalContext* /*context*/,
virtual void setup(IStatus* /*status*/, ExternalContext* /*context*/,
const IRoutineMetadata* /*metadata*/, IRoutineMessage* in, IRoutineMessage* out)
{
setBlr(in, (typename T::InMessage*) 0);
setBlr(out, (typename T::OutMessage*) 0);
}
virtual ExternalProcedure* FB_CALL newItem(Error* error, ExternalContext* context,
virtual ExternalProcedure* FB_CALL newItem(IStatus* status, ExternalContext* context,
const IRoutineMetadata* metadata)
{
T* obj = new(metadata) Routine<T>;
obj->initialize(error, context);
obj->initialize(status, context);
return obj;
}
@ -702,17 +646,17 @@ public:
fbUdrRegTrigger(name, this);
}
virtual void setup(Error* /*error*/, ExternalContext* /*context*/,
virtual void setup(IStatus* /*status*/, ExternalContext* /*context*/,
const IRoutineMetadata* /*metadata*/, ITriggerMessage* fields)
{
setBlr(fields, (typename T::FieldsMessage*) 0);
}
virtual ExternalTrigger* FB_CALL newItem(Error* error, ExternalContext* context,
virtual ExternalTrigger* FB_CALL newItem(IStatus* status, ExternalContext* context,
const IRoutineMetadata* metadata)
{
T* obj = new(metadata) Routine<T>;
obj->initialize(error, context);
obj->initialize(status, context);
return obj;
}

View File

@ -39,27 +39,27 @@ namespace Firebird
class FunctionFactory
{
public:
virtual void setup(Error* error, ExternalContext* context, const IRoutineMetadata* metadata,
virtual void setup(IStatus* status, ExternalContext* context, const IRoutineMetadata* metadata,
IRoutineMessage* in, IRoutineMessage* out) = 0;
virtual ExternalFunction* FB_CALL newItem(Error* error, ExternalContext* context,
virtual ExternalFunction* FB_CALL newItem(IStatus* status, ExternalContext* context,
const IRoutineMetadata* metadata) = 0;
};
class ProcedureFactory
{
public:
virtual void setup(Error* error, ExternalContext* context, const IRoutineMetadata* metadata,
virtual void setup(IStatus* status, ExternalContext* context, const IRoutineMetadata* metadata,
IRoutineMessage* in, IRoutineMessage* out) = 0;
virtual ExternalProcedure* FB_CALL newItem(Error* error, ExternalContext* context,
virtual ExternalProcedure* FB_CALL newItem(IStatus* status, ExternalContext* context,
const IRoutineMetadata* metadata) = 0;
};
class TriggerFactory
{
public:
virtual void setup(Error* error, ExternalContext* context, const IRoutineMetadata* metadata,
virtual void setup(IStatus* status, ExternalContext* context, const IRoutineMetadata* metadata,
ITriggerMessage* fields) = 0;
virtual ExternalTrigger* FB_CALL newItem(Error* error, ExternalContext* context,
virtual ExternalTrigger* FB_CALL newItem(IStatus* status, ExternalContext* context,
const IRoutineMetadata* metadata) = 0;
};

View File

@ -1,167 +0,0 @@
/*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
*
* Software distributed under the License is distributed AS IS,
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the License for the specific language governing rights
* and limitations under the License.
*
* The Original Code was created by Adriano dos Santos Fernandes
* for the Firebird Open Source RDBMS project, based on previous work done
* by Eugeney Putilin <evgeneyputilin at mail.ru>,
* Vlad Khorsun <hvlad at users.sourceforge.net> and
* Roman Rokytskyy <roman at rokytskyy.de>.
*
* Copyright (c) 2008 Adriano dos Santos Fernandes <adrianosf@uol.com.br>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
* Eugeney Putilin <evgeneyputilin at mail.ru>
* Vlad Khorsun <hvlad at users.sourceforge.net>
* Roman Rokytskyy <roman at rokytskyy.de>
*/
#include "firebird.h"
#include "../jrd/ErrorImpl.h"
#include "../jrd/err_proto.h"
#include "../common/classes/alloc.h"
using namespace Firebird;
using Firebird::uint;
namespace Jrd {
ErrorImpl::~ErrorImpl()
{
for (ISC_STATUS* p = status; p <= next; p++)
{
if (*p == isc_arg_cstring)
{
++p;
char* s = (char*) (*++p);
delete[] s;
}
}
}
void ErrorImpl::statusVectorToError(const ISC_STATUS* vector, Error* error)
{
while (*vector != isc_arg_end)
{
switch (*vector)
{
case isc_arg_warning:
case isc_arg_gds:
case isc_arg_number:
case isc_arg_interpreted:
case isc_arg_vms:
case isc_arg_unix:
case isc_arg_win32:
error->addCode(*vector++);
error->addCode(*vector++);
break;
case isc_arg_string:
error->addString((const char*) vector[1], strlen((const char*) vector[1]));
vector += 2;
break;
case isc_arg_cstring:
error->addString((const char*) vector[2], vector[1]);
vector += 3;
break;
default:
fb_assert(false);
return;
}
}
}
void ErrorImpl::exceptionToError(const Firebird::Exception& ex, Error* error)
{
ISC_STATUS_ARRAY statusVector;
ex.stuff_exception(statusVector);
statusVectorToError(statusVector, error);
}
bool FB_CALL ErrorImpl::addCode(int32 code)
{
if (next - status >= ISC_STATUS_LENGTH - 1)
return false;
*next++ = code;
*next = isc_arg_end;
return true;
}
bool FB_CALL ErrorImpl::addString(const char* str, uint strLength)
{
//// TODO: transliteration
if (next - status < ISC_STATUS_LENGTH - 3)
{
*next++ = isc_arg_cstring;
MemoryPool* pool = getDefaultMemoryPool();
char* s = FB_NEW(*pool) char[strLength + 1];
memcpy(s, str, strLength);
s[strLength] = 0;
*next++ = (ISC_STATUS) strLength;
*next++ = (ISC_STATUS)(IPTR) s;
*next = isc_arg_end;
}
return true;
}
//---------------------
RaiseError::~RaiseError()
{
if (next == status)
return;
Arg::StatusVector newStatusVector;
if (*status != isc_arg_gds)
newStatusVector << Arg::Gds(isc_random);
newStatusVector.append(Arg::StatusVector(status));
Firebird::status_exception::raise(newStatusVector);
}
//---------------------
LogError::~LogError()
{
if (next == status)
return;
char msg[1024];
const ISC_STATUS* p = status;
if (fb_interpret(msg, sizeof(msg), &p) != 0)
gds__log("%s", msg);
}
} // namespace Jrd

View File

@ -1,120 +0,0 @@
/*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
*
* Software distributed under the License is distributed AS IS,
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the License for the specific language governing rights
* and limitations under the License.
*
* The Original Code was created by Adriano dos Santos Fernandes
* for the Firebird Open Source RDBMS project, based on previous work done
* by Eugeney Putilin <evgeneyputilin at mail.ru>,
* Vlad Khorsun <hvlad at users.sourceforge.net> and
* Roman Rokytskyy <roman at rokytskyy.de>.
*
* Copyright (c) 2008 Adriano dos Santos Fernandes <adrianosf@uol.com.br>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
* Eugeney Putilin <evgeneyputilin at mail.ru>
* Vlad Khorsun <hvlad at users.sourceforge.net>
* Roman Rokytskyy <roman at rokytskyy.de>
*/
#ifndef JRD_ERROR_IMPL_H
#define JRD_ERROR_IMPL_H
#include "FirebirdApi.h"
#include "firebird/ExternalEngine.h"
#include "iberror.h"
namespace Jrd {
class ErrorImpl : public Firebird::Error
{
public:
inline ErrorImpl()
: next(status)
{
*next = isc_arg_end;
}
virtual ~ErrorImpl();
static void statusVectorToError(const ISC_STATUS* vector, Error* error);
static void exceptionToError(const Firebird::Exception& ex, Error* error);
bool errorOccurred() const
{
return next != status;
}
inline operator Error* ()
{
return this;
}
virtual bool FB_CALL addCode(Firebird::int32 code);
virtual bool FB_CALL addString(const char* str, Firebird::uint strLength);
protected:
ISC_STATUS_ARRAY status;
ISC_STATUS* next;
};
class RaiseError : public ErrorImpl
{
public:
virtual ~RaiseError();
};
class LogError : public ErrorImpl
{
public:
virtual ~LogError();
};
class DelegateError : public Firebird::Error
{
public:
explicit DelegateError(Firebird::Error* aError)
: error(aError),
raised(false)
{
}
virtual bool FB_CALL addCode(Firebird::int32 code)
{
raised = true;
return error->addCode(code);
}
virtual bool FB_CALL addString(const char* str, Firebird::uint strLength)
{
raised = true;
return error->addString(str, strLength);
}
bool isRaised() const
{
return raised;
}
private:
Firebird::Error* error;
bool raised;
};
} // namespace Jrd
#endif // JRD_ERROR_IMPL_H

View File

@ -25,7 +25,6 @@
#include "iberror.h"
#include "inf_pub.h"
#include "../jrd/ExtEngineManager.h"
#include "../jrd/ErrorImpl.h"
#include "../dsql/sqlda_pub.h"
#include "../common/dsc.h"
#include "../jrd/align.h"
@ -140,7 +139,9 @@ private:
{ // scope
Attachment::Checkout attCout(attachment, FB_FUNCTION);
obj->getCharSet(RaiseError(), attInfo->context, charSetName, MAX_SQL_IDENTIFIER_LEN);
LocalStatus status;
obj->getCharSet(&status, attInfo->context, charSetName, MAX_SQL_IDENTIFIER_LEN);
status.check();
charSetName[MAX_SQL_IDENTIFIER_LEN] = '\0';
}
@ -235,17 +236,23 @@ void ExtEngineManager::ExternalContextImpl::setTransaction(thread_db* tdbb)
}
}
ExternalEngine* ExtEngineManager::ExternalContextImpl::getEngine(Error* /*error*/)
IMaster* ExtEngineManager::ExternalContextImpl::getMaster()
{
MasterInterfacePtr master;
return master;
}
ExternalEngine* ExtEngineManager::ExternalContextImpl::getEngine(IStatus* /*status*/)
{
return engine;
}
Firebird::IAttachment* FB_CALL ExtEngineManager::ExternalContextImpl::getAttachment(Error* /*error*/)
Firebird::IAttachment* FB_CALL ExtEngineManager::ExternalContextImpl::getAttachment(IStatus* /*status*/)
{
return externalAttachment;
}
Firebird::ITransaction* FB_CALL ExtEngineManager::ExternalContextImpl::getTransaction(Error* /*error*/)
Firebird::ITransaction* FB_CALL ExtEngineManager::ExternalContextImpl::getTransaction(IStatus* /*status*/)
{
return externalTransaction;
}
@ -305,7 +312,7 @@ ExtEngineManager::Function::Function(thread_db* tdbb, ExtEngineManager* aExtMana
ExtEngineManager::Function::~Function()
{
//Database::Checkout dcoHolder(database);
function->dispose(LogError());
function->dispose();
}
@ -319,7 +326,9 @@ void ExtEngineManager::Function::execute(thread_db* tdbb, UCHAR* inMsg, UCHAR* o
Attachment::Checkout attCout(tdbb->getAttachment(), FB_FUNCTION);
function->execute(RaiseError(), attInfo->context, inMsg, outMsg);
LocalStatus status;
function->execute(&status, attInfo->context, inMsg, outMsg);
status.check();
}
@ -342,7 +351,7 @@ ExtEngineManager::Procedure::Procedure(thread_db* tdbb, ExtEngineManager* aExtMa
ExtEngineManager::Procedure::~Procedure()
{
//Database::Checkout dcoHolder(database);
procedure->dispose(LogError());
procedure->dispose();
}
@ -372,7 +381,9 @@ ExtEngineManager::ResultSet::ResultSet(thread_db* tdbb, UCHAR* inMsg, UCHAR* out
Attachment::Checkout attCout(attachment, FB_FUNCTION);
resultSet = procedure->procedure->open(RaiseError(), attInfo->context, inMsg, outMsg);
LocalStatus status;
resultSet = procedure->procedure->open(&status, attInfo->context, inMsg, outMsg);
status.check();
}
@ -382,7 +393,7 @@ ExtEngineManager::ResultSet::~ResultSet()
{
fb_assert(attachment == JRD_get_thread_data()->getAttachment());
Attachment::Checkout attCout(attachment, FB_FUNCTION);
resultSet->dispose(LogError());
resultSet->dispose();
}
}
@ -402,7 +413,12 @@ bool ExtEngineManager::ResultSet::fetch(thread_db* tdbb)
fb_assert(attachment == tdbb->getAttachment());
Attachment::Checkout attCout(attachment, FB_FUNCTION);
return resultSet->fetch(RaiseError());
LocalStatus status;
bool ret = resultSet->fetch(&status);
status.check();
return ret;
}
@ -572,8 +588,10 @@ void ExtEngineManager::Trigger::execute(thread_db* tdbb, ExternalTrigger::Action
{ // scope
Attachment::Checkout attCout(tdbb->getAttachment(), FB_FUNCTION);
trigger->execute(RaiseError(), attInfo->context, action,
LocalStatus status;
trigger->execute(&status, attInfo->context, action,
(oldRpb ? oldMsg.begin() : NULL), (newRpb ? newMsg.begin() : NULL));
status.check();
}
if (newRpb)
@ -700,7 +718,8 @@ void ExtEngineManager::closeAttachment(thread_db* tdbb, Attachment* attachment)
{
{ // scope
ContextManager<ExternalFunction> ctxManager(tdbb, attInfo, attInfo->adminCharSet);
engine->closeAttachment(LogError(), attInfo->context);
LocalStatus status;
engine->closeAttachment(&status, attInfo->context); //// FIXME: log status
}
delete attInfo;
@ -769,14 +788,15 @@ ExtEngineManager::Function* ExtEngineManager::makeFunction(thread_db* tdbb, cons
{ // scope
Attachment::Checkout attCout(tdbb->getAttachment(), FB_FUNCTION);
externalFunction = attInfo->engine->makeFunction(RaiseError(), attInfo->context, metadata,
LocalStatus status;
externalFunction = attInfo->engine->makeFunction(&status, attInfo->context, metadata,
inMsg, outMsg);
status.check();
if (!externalFunction)
{
status_exception::raise(
Arg::Gds(isc_eem_func_not_returned) <<
udf->getName().toString() << engine);
Arg::Gds(isc_eem_func_not_returned) << udf->getName().toString() << engine);
}
}
@ -788,7 +808,7 @@ ExtEngineManager::Function* ExtEngineManager::makeFunction(thread_db* tdbb, cons
catch (...)
{
Attachment::Checkout attCout(tdbb->getAttachment(), FB_FUNCTION);
externalFunction->dispose(LogError());
externalFunction->dispose();
throw;
}
}
@ -848,8 +868,10 @@ ExtEngineManager::Procedure* ExtEngineManager::makeProcedure(thread_db* tdbb, co
{ // scope
Attachment::Checkout attCout(tdbb->getAttachment(), FB_FUNCTION);
externalProcedure = attInfo->engine->makeProcedure(RaiseError(), attInfo->context, metadata,
LocalStatus status;
externalProcedure = attInfo->engine->makeProcedure(&status, attInfo->context, metadata,
inMsg, outMsg);
status.check();
if (!externalProcedure)
{
@ -867,7 +889,7 @@ ExtEngineManager::Procedure* ExtEngineManager::makeProcedure(thread_db* tdbb, co
catch (...)
{
Attachment::Checkout attCout(tdbb->getAttachment(), FB_FUNCTION);
externalProcedure->dispose(LogError());
externalProcedure->dispose();
throw;
}
}
@ -927,8 +949,10 @@ ExtEngineManager::Trigger* ExtEngineManager::makeTrigger(thread_db* tdbb, const
{ // scope
Attachment::Checkout attCout(tdbb->getAttachment(), FB_FUNCTION);
externalTrigger = attInfo->engine->makeTrigger(RaiseError(), attInfo->context, metadata,
LocalStatus status;
externalTrigger = attInfo->engine->makeTrigger(&status, attInfo->context, metadata,
&fieldsMsg);
status.check();
if (!externalTrigger)
{
@ -945,7 +969,7 @@ ExtEngineManager::Trigger* ExtEngineManager::makeTrigger(thread_db* tdbb, const
catch (...)
{
Attachment::Checkout attCout(tdbb->getAttachment(), FB_FUNCTION);
externalTrigger->dispose(LogError());
externalTrigger->dispose();
throw;
}
}
@ -988,7 +1012,8 @@ ExternalEngine* ExtEngineManager::getEngine(thread_db* tdbb, const MetaName& nam
setupAdminCharSet(tdbb, engine, attInfo);
ContextManager<ExternalFunction> ctxManager(tdbb, attInfo, attInfo->adminCharSet);
engine->openAttachment(LogError(), attInfo->context);
LocalStatus status;
engine->openAttachment(&status, attInfo->context); //// FIXME: log status
}
}
catch (...)
@ -1054,7 +1079,8 @@ ExtEngineManager::EngineAttachmentInfo* ExtEngineManager::getEngineAttachment(
ContextManager<ExternalFunction> ctxManager(tdbb, attInfo, attInfo->adminCharSet);
Attachment::Checkout attCout(tdbb->getAttachment(), FB_FUNCTION);
engine->openAttachment(LogError(), attInfo->context);
LocalStatus status;
engine->openAttachment(&status, attInfo->context); //// FIXME: log status
}
return attInfo;
@ -1077,8 +1103,11 @@ void ExtEngineManager::setupAdminCharSet(thread_db* tdbb, ExternalEngine* engine
ContextManager<ExternalFunction> ctxManager(tdbb, attInfo, CS_UTF8);
Utf8 charSetName[MAX_SQL_IDENTIFIER_SIZE] = "NONE";
engine->open(RaiseError(), attInfo->context, charSetName,
MAX_SQL_IDENTIFIER_LEN);
LocalStatus status;
engine->open(&status, attInfo->context, charSetName, MAX_SQL_IDENTIFIER_LEN);
status.check();
charSetName[MAX_SQL_IDENTIFIER_LEN] = '\0';
if (!MET_get_char_coll_subtype(tdbb, &attInfo->adminCharSet,

View File

@ -198,9 +198,10 @@ private:
void releaseTransaction();
void setTransaction(thread_db* tdbb);
virtual Firebird::ExternalEngine* FB_CALL getEngine(Firebird::Error* error);
virtual Firebird::IAttachment* FB_CALL getAttachment(Firebird::Error* error);
virtual Firebird::ITransaction* FB_CALL getTransaction(Firebird::Error* error);
virtual Firebird::IMaster* FB_CALL getMaster();
virtual Firebird::ExternalEngine* FB_CALL getEngine(Firebird::IStatus* status);
virtual Firebird::IAttachment* FB_CALL getAttachment(Firebird::IStatus* status);
virtual Firebird::ITransaction* FB_CALL getTransaction(Firebird::IStatus* status);
virtual const char* FB_CALL getUserName();
virtual const char* FB_CALL getDatabaseName();
virtual const Firebird::Utf8* FB_CALL getClientCharSet();

View File

@ -134,7 +134,7 @@ public:
public:
void loadModule(const IRoutineMetadata* metadata, PathName* moduleName, string* entryPoint);
template <typename NodeType, typename ObjType, typename SharedObjType> ObjType* getChild(
Error* error, GenericMap<Pair<NonPooled<ExternalContext*, ObjType*> > >& children,
IStatus* status, GenericMap<Pair<NonPooled<ExternalContext*, ObjType*> > >& children,
SharedObjType* sharedObj, ExternalContext* context, NodeType* nodes,
SortedArray<SharedObjType*>& sharedObjs, const PathName& moduleName);
template <typename ObjType> void deleteChildren(
@ -144,23 +144,23 @@ public:
const string& entryPoint);
private:
template <typename T, typename T2> T2* getNode(Error* error, T* nodes,
template <typename T, typename T2> T2* getNode(IStatus* status, T* nodes,
const PathName& moduleName, ExternalContext* context, const IRoutineMetadata* metadata,
const string& entryPoint);
public:
virtual void FB_CALL open(Error* error, ExternalContext* context, Utf8* name, uint nameSize);
virtual void FB_CALL openAttachment(Error* error, ExternalContext* context);
virtual void FB_CALL closeAttachment(Error* error, ExternalContext* context);
virtual ExternalFunction* FB_CALL makeFunction(Error* error, ExternalContext* context,
virtual void FB_CALL open(IStatus* status, ExternalContext* context, Utf8* name, uint nameSize);
virtual void FB_CALL openAttachment(IStatus* status, ExternalContext* context);
virtual void FB_CALL closeAttachment(IStatus* status, ExternalContext* context);
virtual ExternalFunction* FB_CALL makeFunction(IStatus* status, ExternalContext* context,
const IRoutineMetadata* metadata, IRoutineMessage* inMsg, IRoutineMessage* outMsg);
virtual ExternalProcedure* FB_CALL makeProcedure(Error* error, ExternalContext* context,
virtual ExternalProcedure* FB_CALL makeProcedure(IStatus* status, ExternalContext* context,
const IRoutineMetadata* metadata, IRoutineMessage* inMsg, IRoutineMessage* outMsg);
virtual ExternalTrigger* FB_CALL makeTrigger(Error* error, ExternalContext* context,
virtual ExternalTrigger* FB_CALL makeTrigger(IStatus* status, ExternalContext* context,
const IRoutineMetadata* metadata, ITriggerMessage* fieldsMsg);
public:
virtual void FB_CALL dispose(Error* error);
virtual void FB_CALL dispose();
private:
Mutex childrenMutex;
@ -206,7 +206,7 @@ static TriggerNode* registeredTriggers = NULL;
class SharedFunction : public ExternalFunction
{
public:
SharedFunction(Error* error, Engine* aEngine, ExternalContext* context,
SharedFunction(IStatus* status, Engine* aEngine, ExternalContext* context,
const IRoutineMetadata* aMetadata, IRoutineMessage* inMsg, IRoutineMessage* outMsg)
: engine(aEngine),
metadata(aMetadata),
@ -217,7 +217,7 @@ public:
{
engine->loadModule(metadata, &moduleName, &entryPoint);
FunctionNode* node = engine->findNode<FunctionNode>(registeredFunctions, moduleName, entryPoint);
node->factory->setup(error, context, metadata, inMsg, outMsg);
node->factory->setup(status, context, metadata, inMsg, outMsg);
}
virtual ~SharedFunction()
@ -226,36 +226,36 @@ public:
}
public:
virtual void FB_CALL dispose(Firebird::Error* /*error*/)
virtual void FB_CALL dispose()
{
delete this;
}
public:
virtual void FB_CALL getCharSet(Error* error, ExternalContext* context,
virtual void FB_CALL getCharSet(IStatus* status, ExternalContext* context,
Utf8* name, uint nameSize)
{
strncpy(name, context->getClientCharSet(), nameSize);
try
{
ExternalFunction* function = engine->getChild<FunctionNode, ExternalFunction>(error,
ExternalFunction* function = engine->getChild<FunctionNode, ExternalFunction>(status,
children, this, context, registeredFunctions, engine->functions, moduleName);
if (function)
function->getCharSet(error, context, name, nameSize);
function->getCharSet(status, context, name, nameSize);
}
catch (const ThrowError::Exception& e)
catch (const StatusException& e)
{
e.stuff(error);
e.stuff(status);
}
}
virtual void FB_CALL execute(Error* error, ExternalContext* context, void* inMsg, void* outMsg)
virtual void FB_CALL execute(IStatus* status, ExternalContext* context, void* inMsg, void* outMsg)
{
ExternalFunction* function = engine->getChild<FunctionNode, ExternalFunction>(error,
ExternalFunction* function = engine->getChild<FunctionNode, ExternalFunction>(status,
children, this, context, registeredFunctions, engine->functions, moduleName);
if (function)
function->execute(error, context, inMsg, outMsg);
function->execute(status, context, inMsg, outMsg);
}
public:
@ -274,7 +274,7 @@ public:
class SharedProcedure : public ExternalProcedure
{
public:
SharedProcedure(Error* error, Engine* aEngine, ExternalContext* context,
SharedProcedure(IStatus* status, Engine* aEngine, ExternalContext* context,
const IRoutineMetadata* aMetadata, IRoutineMessage* inMsg, IRoutineMessage* outMsg)
: engine(aEngine),
metadata(aMetadata),
@ -285,7 +285,7 @@ public:
{
engine->loadModule(metadata, &moduleName, &entryPoint);
ProcedureNode* node = engine->findNode<ProcedureNode>(registeredProcedures, moduleName, entryPoint);
node->factory->setup(error, context, metadata, inMsg, outMsg);
node->factory->setup(status, context, metadata, inMsg, outMsg);
}
virtual ~SharedProcedure()
@ -294,42 +294,42 @@ public:
}
public:
virtual void FB_CALL dispose(Firebird::Error* /*error*/)
virtual void FB_CALL dispose()
{
delete this;
}
public:
virtual void FB_CALL getCharSet(Error* error, ExternalContext* context,
virtual void FB_CALL getCharSet(IStatus* status, ExternalContext* context,
Utf8* name, uint nameSize)
{
strncpy(name, context->getClientCharSet(), nameSize);
try
{
ExternalProcedure* procedure = engine->getChild<ProcedureNode, ExternalProcedure>(error,
ExternalProcedure* procedure = engine->getChild<ProcedureNode, ExternalProcedure>(status,
children, this, context, registeredProcedures, engine->procedures, moduleName);
if (procedure)
procedure->getCharSet(error, context, name, nameSize);
procedure->getCharSet(status, context, name, nameSize);
}
catch (const ThrowError::Exception& e)
catch (const StatusException& e)
{
e.stuff(error);
e.stuff(status);
}
}
virtual ExternalResultSet* FB_CALL open(Error* error, ExternalContext* context,
virtual ExternalResultSet* FB_CALL open(IStatus* status, ExternalContext* context,
void* inMsg, void* outMsg)
{
try
{
ExternalProcedure* procedure = engine->getChild<ProcedureNode, ExternalProcedure>(error,
ExternalProcedure* procedure = engine->getChild<ProcedureNode, ExternalProcedure>(status,
children, this, context, registeredProcedures, engine->procedures, moduleName);
return procedure ? procedure->open(error, context, inMsg, outMsg) : NULL;
return procedure ? procedure->open(status, context, inMsg, outMsg) : NULL;
}
catch (const ThrowError::Exception& e)
catch (const StatusException& e)
{
e.stuff(error);
e.stuff(status);
return NULL;
}
}
@ -350,7 +350,7 @@ public:
class SharedTrigger : public ExternalTrigger
{
public:
SharedTrigger(Error* error, Engine* aEngine, ExternalContext* context,
SharedTrigger(IStatus* status, Engine* aEngine, ExternalContext* context,
const IRoutineMetadata* aMetadata, ITriggerMessage* fieldsMsg)
: engine(aEngine),
metadata(aMetadata),
@ -361,7 +361,7 @@ public:
{
engine->loadModule(metadata, &moduleName, &entryPoint);
TriggerNode* node = engine->findNode<TriggerNode>(registeredTriggers, moduleName, entryPoint);
node->factory->setup(error, context, metadata, fieldsMsg);
node->factory->setup(status, context, metadata, fieldsMsg);
}
virtual ~SharedTrigger()
@ -370,37 +370,37 @@ public:
}
public:
virtual void FB_CALL dispose(Firebird::Error* /*error*/)
virtual void FB_CALL dispose()
{
delete this;
}
public:
virtual void FB_CALL getCharSet(Error* error, ExternalContext* context,
virtual void FB_CALL getCharSet(IStatus* status, ExternalContext* context,
Utf8* name, uint nameSize)
{
strncpy(name, context->getClientCharSet(), nameSize);
try
{
ExternalTrigger* trigger = engine->getChild<TriggerNode, ExternalTrigger>(error,
ExternalTrigger* trigger = engine->getChild<TriggerNode, ExternalTrigger>(status,
children, this, context, registeredTriggers, engine->triggers, moduleName);
if (trigger)
trigger->getCharSet(error, context, name, nameSize);
trigger->getCharSet(status, context, name, nameSize);
}
catch (const ThrowError::Exception& e)
catch (const StatusException& e)
{
e.stuff(error);
e.stuff(status);
}
}
virtual void FB_CALL execute(Error* error, ExternalContext* context,
virtual void FB_CALL execute(IStatus* status, ExternalContext* context,
ExternalTrigger::Action action, void* oldMsg, void* newMsg)
{
ExternalTrigger* trigger = engine->getChild<TriggerNode, ExternalTrigger>(error,
ExternalTrigger* trigger = engine->getChild<TriggerNode, ExternalTrigger>(status,
children, this, context, registeredTriggers, engine->triggers, moduleName);
if (trigger)
trigger->execute(error, context, action, oldMsg, newMsg);
trigger->execute(status, context, action, oldMsg, newMsg);
}
public:
@ -497,7 +497,7 @@ void Engine::loadModule(const IRoutineMetadata* metadata, PathName* moduleName,
{
LocalStatus status;
const string str(metadata->getEntryPoint(&status));
ThrowError::check(status.get());
StatusException::check(status.get());
const size_t pos = str.find('!');
if (pos == string::npos)
@ -509,7 +509,7 @@ void Engine::loadModule(const IRoutineMetadata* metadata, PathName* moduleName,
isc_arg_end
};
ThrowError::check(statusVector);
StatusException::check(statusVector);
}
*moduleName = PathName(str.substr(0, pos).c_str());
@ -523,7 +523,7 @@ void Engine::loadModule(const IRoutineMetadata* metadata, PathName* moduleName,
isc_arg_end
};
ThrowError::check(statusVector);
StatusException::check(statusVector);
}
*entryPoint = str.substr(pos + 1);
@ -559,14 +559,14 @@ void Engine::loadModule(const IRoutineMetadata* metadata, PathName* moduleName,
isc_arg_end
};
ThrowError::check(statusVector);
StatusException::check(statusVector);
}
}
}
template <typename NodeType, typename ObjType, typename SharedObjType> ObjType* Engine::getChild(
Error* error, GenericMap<Pair<NonPooled<ExternalContext*, ObjType*> > >& children,
IStatus* status, GenericMap<Pair<NonPooled<ExternalContext*, ObjType*> > >& children,
SharedObjType* sharedObj, ExternalContext* context, NodeType* nodes,
SortedArray<SharedObjType*>& sharedObjs, const PathName& moduleName)
{
@ -578,7 +578,7 @@ template <typename NodeType, typename ObjType, typename SharedObjType> ObjType*
ObjType* obj;
if (!children.get(context, obj))
{
obj = getNode<NodeType, ObjType>(error, nodes, moduleName, context, sharedObj->metadata,
obj = getNode<NodeType, ObjType>(status, nodes, moduleName, context, sharedObj->metadata,
sharedObj->entryPoint);
if (obj)
@ -618,33 +618,33 @@ template <typename T> T* Engine::findNode(T* nodes, const PathName& moduleName,
isc_arg_end
};
ThrowError::check(statusVector);
StatusException::check(statusVector);
return NULL;
}
template <typename T, typename T2> T2* Engine::getNode(Error* error, T* nodes,
template <typename T, typename T2> T2* Engine::getNode(IStatus* status, T* nodes,
const PathName& moduleName, ExternalContext* context, const IRoutineMetadata* metadata,
const string& entryPoint)
{
T* node = findNode<T>(nodes, moduleName, entryPoint);
return node->factory->newItem(error, context, metadata);
return node->factory->newItem(status, context, metadata);
}
void FB_CALL Engine::open(Error* /*error*/, ExternalContext* /*context*/, Utf8* name, uint nameSize)
void FB_CALL Engine::open(IStatus* /*status*/, ExternalContext* /*context*/, Utf8* name, uint nameSize)
{
strncpy(name, "UTF-8", nameSize);
}
void FB_CALL Engine::openAttachment(Error* /*error*/, ExternalContext* /*context*/)
void FB_CALL Engine::openAttachment(IStatus* /*status*/, ExternalContext* /*context*/)
{
}
void FB_CALL Engine::closeAttachment(Error* error, ExternalContext* context)
void FB_CALL Engine::closeAttachment(IStatus* status, ExternalContext* context)
{
MutexLockGuard guard(childrenMutex, FB_FUNCTION);
@ -653,7 +653,7 @@ void FB_CALL Engine::closeAttachment(Error* error, ExternalContext* context)
ExternalFunction* function;
if ((*i)->children.get(context, function))
{
function->dispose(error);
function->dispose();
(*i)->children.remove(context);
}
}
@ -663,7 +663,7 @@ void FB_CALL Engine::closeAttachment(Error* error, ExternalContext* context)
ExternalProcedure* procedure;
if ((*i)->children.get(context, procedure))
{
procedure->dispose(error);
procedure->dispose();
(*i)->children.remove(context);
}
}
@ -673,59 +673,59 @@ void FB_CALL Engine::closeAttachment(Error* error, ExternalContext* context)
ExternalTrigger* trigger;
if ((*i)->children.get(context, trigger))
{
trigger->dispose(error);
trigger->dispose();
(*i)->children.remove(context);
}
}
}
ExternalFunction* FB_CALL Engine::makeFunction(Error* error, ExternalContext* context,
ExternalFunction* FB_CALL Engine::makeFunction(IStatus* status, ExternalContext* context,
const IRoutineMetadata* metadata, IRoutineMessage* inMsg, IRoutineMessage* outMsg)
{
try
{
return new SharedFunction(error, this, context, metadata, inMsg, outMsg);
return new SharedFunction(status, this, context, metadata, inMsg, outMsg);
}
catch (const ThrowError::Exception& e)
catch (const StatusException& e)
{
e.stuff(error);
e.stuff(status);
return NULL;
}
}
ExternalProcedure* FB_CALL Engine::makeProcedure(Error* error, ExternalContext* context,
ExternalProcedure* FB_CALL Engine::makeProcedure(IStatus* status, ExternalContext* context,
const IRoutineMetadata* metadata, IRoutineMessage* inMsg, IRoutineMessage* outMsg)
{
try
{
return new SharedProcedure(error, this, context, metadata, inMsg, outMsg);
return new SharedProcedure(status, this, context, metadata, inMsg, outMsg);
}
catch (const ThrowError::Exception& e)
catch (const StatusException& e)
{
e.stuff(error);
e.stuff(status);
return NULL;
}
}
ExternalTrigger* FB_CALL Engine::makeTrigger(Error* error, ExternalContext* context,
ExternalTrigger* FB_CALL Engine::makeTrigger(IStatus* status, ExternalContext* context,
const IRoutineMetadata* metadata, ITriggerMessage* fieldsMsg)
{
try
{
return new SharedTrigger(error, this, context, metadata, fieldsMsg);
return new SharedTrigger(status, this, context, metadata, fieldsMsg);
}
catch (const ThrowError::Exception& e)
catch (const StatusException& e)
{
e.stuff(error);
e.stuff(status);
return NULL;
}
}
void FB_CALL Engine::dispose(Error* /*error*/)
void FB_CALL Engine::dispose()
{
delete this;
}
@ -734,25 +734,6 @@ void FB_CALL Engine::dispose(Error* /*error*/)
//--------------------------------------
/***
class ExternalEngineFactoryImpl : public ExternalEngineFactory
{
public:
virtual ExternalEngine* FB_CALL createEngine(Error* error, int *version*,
const char* name)
{
if (strcmp(name, "UDR") == 0)
return new Engine();
const char* const msg = "Engine not implemented";
error->addCode(isc_arg_gds);
error->addCode(isc_random);
error->addString(msg, strlen(msg));
return NULL;
}
***/
class ExternalEngineFactoryImpl : public SimpleFactory<Engine>
{
} factory;

View File

@ -29,7 +29,6 @@
#include "../dsql/sqlda_pub.h"
#include "../yvalve/why_proto.h"
#include "../jrd/ErrorImpl.h"
#include "../common/os/path_utils.h"
#include "../jrd/err_proto.h"
#include "../common/isc_proto.h"