why.cpp (Firebird-3.0.2.32703-0.tar.bz2) | : | why.cpp (Firebird-3.0.4.33054-0.tar.bz2) | ||
---|---|---|---|---|
skipping to change at line 1104 | skipping to change at line 1104 | |||
void* arg; | void* arg; | |||
}; | }; | |||
static AtomicCounter dispCounter; | static AtomicCounter dispCounter; | |||
template <typename Y> | template <typename Y> | |||
class YEntry : public FpeControl //// TODO: move FpeControl to the engine | class YEntry : public FpeControl //// TODO: move FpeControl to the engine | |||
{ | { | |||
public: | public: | |||
YEntry(CheckStatusWrapper* aStatus, Y* object, int checkAttachmen t = 1) | YEntry(CheckStatusWrapper* aStatus, Y* object, int checkAttachmen t = 1) | |||
: ref(object->attachment), nextRef(NULL) | : ref(object->attachment.get()), nextRef(NULL) | |||
{ | { | |||
aStatus->init(); | aStatus->init(); | |||
init(object->next); | init(object->next); | |||
if (checkAttachment && !(nextRef.hasData())) | if (checkAttachment && !(nextRef.hasData())) | |||
{ | { | |||
fini(); | fini(); | |||
Arg::Gds(Y::ERROR_CODE).raise(); | Arg::Gds(Y::ERROR_CODE).raise(); | |||
} | } | |||
if (checkAttachment && ref && ref->savedStatus.getError() ) | if (checkAttachment && ref && ref->savedStatus.getError() ) | |||
{ | { | |||
fini(); | fini(); | |||
status_exception::raise(object->attachment->saved Status.value()); | status_exception::raise(object->attachment.get()- >savedStatus.value()); | |||
} | } | |||
} | } | |||
~YEntry() | ~YEntry() | |||
{ | { | |||
fini(); | fini(); | |||
} | } | |||
void init(typename Y::NextInterface* nxt) | void init(typename Y::NextInterface* nxt) | |||
{ | { | |||
signalInit(); | signalInit(); | |||
if (ref) | if (ref) | |||
{ | { | |||
MutexLockGuard guard(ref->enterMutex, FB_FUNCTION ); | MutexLockGuard guard(ref->enterMutex, FB_FUNCTION ); | |||
++ref->enterCount; | ++ref->enterCount; | |||
nextRef = nxt; | ||||
} | } | |||
else | else | |||
{ | { | |||
++dispCounter; | ++dispCounter; | |||
nextRef = nxt; | ||||
} | } | |||
if (shutdownStarted) | if (shutdownStarted) | |||
{ | { | |||
fini(); | fini(); | |||
Arg::Gds(isc_att_shutdown).raise(); | Arg::Gds(isc_att_shutdown).raise(); | |||
} | } | |||
nextRef = nxt; | ||||
} | } | |||
void fini() | void fini() | |||
{ | { | |||
RefDeb(DEB_RLS_JATT, "YEntry::fini"); | RefDeb(DEB_RLS_JATT, "YEntry::fini"); | |||
nextRef = NULL; | ||||
if (ref) | if (ref) | |||
{ | { | |||
MutexLockGuard guard(ref->enterMutex, FB_FUNCTION ); | MutexLockGuard guard(ref->enterMutex, FB_FUNCTION ); | |||
nextRef = NULL; | ||||
--ref->enterCount; | --ref->enterCount; | |||
} | } | |||
else | else | |||
{ | { | |||
nextRef = NULL; | ||||
--dispCounter; | --dispCounter; | |||
} | } | |||
} | } | |||
typename Y::NextInterface* next() | typename Y::NextInterface* next() | |||
{ | { | |||
return nextRef; | return nextRef; | |||
} | } | |||
private: | private: | |||
skipping to change at line 1185 | skipping to change at line 1186 | |||
RefPtr<typename Y::YRef> ref; | RefPtr<typename Y::YRef> ref; | |||
RefPtr<typename Y::NextInterface> nextRef; | RefPtr<typename Y::NextInterface> nextRef; | |||
}; | }; | |||
class IscStatement : public RefCounted, public GlobalStorage, public YObj ect | class IscStatement : public RefCounted, public GlobalStorage, public YObj ect | |||
{ | { | |||
public: | public: | |||
static const ISC_STATUS ERROR_CODE = isc_bad_stmt_handle; | static const ISC_STATUS ERROR_CODE = isc_bad_stmt_handle; | |||
explicit IscStatement(YAttachment* aAttachment) | explicit IscStatement(YAttachment* aAttachment) | |||
: cursorName(getPool()), | : attachment(aAttachment), | |||
attachment(aAttachment), | cursorName(getPool()), | |||
statement(NULL), | statement(NULL), | |||
userHandle(NULL), | userHandle(NULL), | |||
pseudoOpened(false), | pseudoOpened(false), | |||
delayedFormat(false) | delayedFormat(false) | |||
{ } | { } | |||
~IscStatement(); | ~IscStatement(); | |||
FB_API_HANDLE& getHandle(); | FB_API_HANDLE& getHandle(); | |||
void destroy(unsigned); | void destroy(unsigned); | |||
skipping to change at line 1224 | skipping to change at line 1225 | |||
if (!statement || !statement->cursor) | if (!statement || !statement->cursor) | |||
Arg::Gds(isc_dsql_cursor_not_open).raise(); | Arg::Gds(isc_dsql_cursor_not_open).raise(); | |||
} | } | |||
void checkCursorClosed() const | void checkCursorClosed() const | |||
{ | { | |||
if (statement && statement->cursor) | if (statement && statement->cursor) | |||
Arg::Gds(isc_dsql_cursor_open_err).raise(); | Arg::Gds(isc_dsql_cursor_open_err).raise(); | |||
} | } | |||
AtomicAttPtr attachment; | ||||
string cursorName; | string cursorName; | |||
YAttachment* attachment; | ||||
YStatement* statement; | YStatement* statement; | |||
FB_API_HANDLE* userHandle; | FB_API_HANDLE* userHandle; | |||
bool pseudoOpened, delayedFormat; | bool pseudoOpened, delayedFormat; | |||
}; | }; | |||
template <> | template <> | |||
YEntry<YAttachment>::YEntry(CheckStatusWrapper* aStatus, YAttachment* aAt tachment, int checkAttachment) | YEntry<YAttachment>::YEntry(CheckStatusWrapper* aStatus, YAttachment* aAt tachment, int checkAttachment) | |||
: ref(aAttachment), nextRef(NULL) | : ref(aAttachment), nextRef(NULL) | |||
{ | { | |||
aStatus->init(); | aStatus->init(); | |||
skipping to change at line 1318 | skipping to change at line 1319 | |||
//------------------------------------- | //------------------------------------- | |||
static void badHandle(ISC_STATUS code) | static void badHandle(ISC_STATUS code) | |||
{ | { | |||
status_exception::raise(Arg::Gds(code)); | status_exception::raise(Arg::Gds(code)); | |||
} | } | |||
static bool isNetworkError(const IStatus* status) | static bool isNetworkError(const IStatus* status) | |||
{ | { | |||
ISC_STATUS code = status->getErrors()[1]; | ISC_STATUS code = status->getErrors()[1]; | |||
return code == isc_network_error || code == isc_net_write_err || code == isc_net_read_err; | return fb_utils::isNetworkError(code); | |||
} | } | |||
static void nullCheck(const FB_API_HANDLE* ptr, ISC_STATUS code) | static void nullCheck(const FB_API_HANDLE* ptr, ISC_STATUS code) | |||
{ | { | |||
// This function is called for incoming API handles, proposed to be creat ed by the call. | // This function is called for incoming API handles, proposed to be creat ed by the call. | |||
if (!ptr || *ptr) | if (!ptr || *ptr) | |||
badHandle(code); | badHandle(code); | |||
} | } | |||
static void badSqldaVersion(const short version) | static void badSqldaVersion(const short version) | |||
skipping to change at line 1618 | skipping to change at line 1619 | |||
{ | { | |||
if (ex.value()[1] == isc_bad_events_handle) | if (ex.value()[1] == isc_bad_events_handle) | |||
{ | { | |||
// Ignore invalid handle/ID in cancelation call f or backward compatibility | // Ignore invalid handle/ID in cancelation call f or backward compatibility | |||
return status[1]; | return status[1]; | |||
} | } | |||
throw; | throw; | |||
} | } | |||
if (event->attachment != attachment) | if (event->attachment.get() != attachment) | |||
Arg::Gds(isc_bad_events_handle).raise(); | Arg::Gds(isc_bad_events_handle).raise(); | |||
event->cancel(&statusWrapper); | event->cancel(&statusWrapper); | |||
if (!(status.getState() & Firebird::IStatus::STATE_ERRORS)) | if (!(status.getState() & Firebird::IStatus::STATE_ERRORS)) | |||
*id = 0; | *id = 0; | |||
} | } | |||
catch (const Exception& e) | catch (const Exception& e) | |||
{ | { | |||
e.stuffException(&statusWrapper); | e.stuffException(&statusWrapper); | |||
skipping to change at line 2497 | skipping to change at line 2498 | |||
statement->closeStatement(&statusWrapper); | statement->closeStatement(&statusWrapper); | |||
if (status.getState() & Firebird::IStatus::STATE_ERRORS) | if (status.getState() & Firebird::IStatus::STATE_ERRORS) | |||
return status[1]; | return status[1]; | |||
} | } | |||
statement->cursorName = ""; | statement->cursorName = ""; | |||
if (traHandle && *traHandle) | if (traHandle && *traHandle) | |||
transaction = translateHandle(transactions, traHandle); | transaction = translateHandle(transactions, traHandle); | |||
statement->statement = statement->attachment->prepare(&statusWrap per, transaction, | statement->statement = statement->attachment.get()->prepare(&stat usWrapper, transaction, | |||
stmtLength, sqlStmt, dialect, IStatement::PREPARE_PREFETC H_METADATA); | stmtLength, sqlStmt, dialect, IStatement::PREPARE_PREFETC H_METADATA); | |||
if (!(status.getState() & Firebird::IStatus::STATE_ERRORS)) | if (!(status.getState() & Firebird::IStatus::STATE_ERRORS)) | |||
{ | { | |||
StatusVector tempStatus(NULL); | StatusVector tempStatus(NULL); | |||
CheckStatusWrapper tempCheckStatusWrapper(&tempStatus); | CheckStatusWrapper tempCheckStatusWrapper(&tempStatus); | |||
RefPtr<IMessageMetadata> parameters(REF_NO_INCR, | RefPtr<IMessageMetadata> parameters(REF_NO_INCR, | |||
statement->statement->next->getOutputMetadata(&te mpCheckStatusWrapper)); | statement->statement->next->getOutputMetadata(&te mpCheckStatusWrapper)); | |||
tempStatus.check(); | tempStatus.check(); | |||
skipping to change at line 2548 | skipping to change at line 2549 | |||
} | } | |||
statement->cursorName = ""; | statement->cursorName = ""; | |||
if (traHandle && *traHandle) | if (traHandle && *traHandle) | |||
transaction = translateHandle(transactions, traHandle); | transaction = translateHandle(transactions, traHandle); | |||
unsigned flags = StatementMetadata::buildInfoFlags( | unsigned flags = StatementMetadata::buildInfoFlags( | |||
itemLength, reinterpret_cast<const UCHAR*>(items)); | itemLength, reinterpret_cast<const UCHAR*>(items)); | |||
statement->statement = statement->attachment->prepare(&statusWrap per, transaction, | statement->statement = statement->attachment.get()->prepare(&stat usWrapper, transaction, | |||
stmtLength, sqlStmt, dialect, flags); | stmtLength, sqlStmt, dialect, flags); | |||
if (!(status.getState() & Firebird::IStatus::STATE_ERRORS)) | if (!(status.getState() & Firebird::IStatus::STATE_ERRORS)) | |||
{ | { | |||
StatusVector tempStatus(NULL); | StatusVector tempStatus(NULL); | |||
CheckStatusWrapper tempCheckStatusWrapper(&tempStatus); | CheckStatusWrapper tempCheckStatusWrapper(&tempStatus); | |||
statement->statement->getInfo(&tempCheckStatusWrapper, | statement->statement->getInfo(&tempCheckStatusWrapper, | |||
itemLength, reinterpret_cast<const UCHAR*>(items) , | itemLength, reinterpret_cast<const UCHAR*>(items) , | |||
bufferLength, reinterpret_cast<UCHAR*>(buffer)); | bufferLength, reinterpret_cast<UCHAR*>(buffer)); | |||
tempStatus.check(); | tempStatus.check(); | |||
skipping to change at line 3655 | skipping to change at line 3656 | |||
template <typename Impl, typename Intf> | template <typename Impl, typename Intf> | |||
YHelper<Impl, Intf>::YHelper(NextInterface* aNext) | YHelper<Impl, Intf>::YHelper(NextInterface* aNext) | |||
{ | { | |||
next.assignRefNoIncr(aNext); | next.assignRefNoIncr(aNext); | |||
} | } | |||
//------------------------------------- | //------------------------------------- | |||
YEvents::YEvents(YAttachment* aAttachment, IEvents* aNext, IEventCallback* aCall back) | YEvents::YEvents(YAttachment* aAttachment, IEvents* aNext, IEventCallback* aCall back) | |||
: YHelper(aNext) | : YHelper(aNext), attachment(aAttachment), callback(aCallback) | |||
{ | { | |||
attachment = aAttachment; | aAttachment->childEvents.add(this); | |||
callback = aCallback; | ||||
attachment->childEvents.add(this); | ||||
} | } | |||
FB_API_HANDLE& YEvents::getHandle() | FB_API_HANDLE& YEvents::getHandle() | |||
{ | { | |||
if (!handle) | if (!handle) | |||
makeHandle(&events, this, handle); | makeHandle(&events, this, handle); | |||
return handle; | return handle; | |||
} | } | |||
void YEvents::destroy(unsigned dstrFlags) | void YEvents::destroy(unsigned dstrFlags) | |||
{ | { | |||
attachment->childEvents.remove(this); | YAttachment* att = attachment.release(); | |||
attachment = NULL; | if (att) | |||
att->childEvents.remove(this); | ||||
removeHandle(&events, handle); | removeHandle(&events, handle); | |||
if (!(dstrFlags & DF_RELEASE)) | if (!(dstrFlags & DF_RELEASE)) | |||
{ | { | |||
const bool allowCancel = destroyed.compareExchange(0, 1); | const bool allowCancel = destroyed.compareExchange(0, 1); | |||
if (!allowCancel) | if (!allowCancel) | |||
return; | return; | |||
} | } | |||
destroy2(dstrFlags); | destroy2(dstrFlags); | |||
skipping to change at line 3698 | skipping to change at line 3697 | |||
const bool allowCancel = destroyed.compareExchange(0, 1); | const bool allowCancel = destroyed.compareExchange(0, 1); | |||
if (!allowCancel) | if (!allowCancel) | |||
return; | return; | |||
try | try | |||
{ | { | |||
YEntry<YEvents> entry(status, this); | YEntry<YEvents> entry(status, this); | |||
entry.next()->cancel(status); | entry.next()->cancel(status); | |||
if (status->getErrors()[1] == isc_att_shutdown) | ||||
status->init(); | ||||
if (!(status->getState() & Firebird::IStatus::STATE_ERRORS)) | if (!(status->getState() & Firebird::IStatus::STATE_ERRORS)) | |||
destroy(DF_RELEASE); | destroy(DF_RELEASE); | |||
} | } | |||
catch (const Exception& e) | catch (const Exception& e) | |||
{ | { | |||
e.stuffException(status); | e.stuffException(status); | |||
} | } | |||
} | } | |||
//------------------------------------- | //------------------------------------- | |||
YRequest::YRequest(YAttachment* aAttachment, IRequest* aNext) | YRequest::YRequest(YAttachment* aAttachment, IRequest* aNext) | |||
: YHelper(aNext), | : YHelper(aNext), | |||
attachment(aAttachment), | attachment(aAttachment), | |||
userHandle(NULL) | userHandle(NULL) | |||
{ | { | |||
attachment->childRequests.add(this); | attachment.get()->childRequests.add(this); | |||
} | } | |||
FB_API_HANDLE& YRequest::getHandle() | FB_API_HANDLE& YRequest::getHandle() | |||
{ | { | |||
if (!handle) | if (!handle) | |||
makeHandle(&requests, this, handle); | makeHandle(&requests, this, handle); | |||
return handle; | return handle; | |||
} | } | |||
void YRequest::destroy(unsigned dstrFlags) | void YRequest::destroy(unsigned dstrFlags) | |||
{ | { | |||
if (userHandle) | if (userHandle) | |||
{ | { | |||
*userHandle = 0; | *userHandle = 0; | |||
userHandle = NULL; | userHandle = NULL; | |||
} | } | |||
attachment->childRequests.remove(this); | YAttachment* att = attachment.release(); | |||
attachment = NULL; | if (att) | |||
att->childRequests.remove(this); | ||||
removeHandle(&requests, handle); | removeHandle(&requests, handle); | |||
destroy2(dstrFlags); | destroy2(dstrFlags); | |||
} | } | |||
void YRequest::receive(CheckStatusWrapper* status, int level, unsigned int msgTy pe, | void YRequest::receive(CheckStatusWrapper* status, int level, unsigned int msgTy pe, | |||
unsigned int length, unsigned char* message) | unsigned int length, unsigned char* message) | |||
{ | { | |||
try | try | |||
skipping to change at line 3789 | skipping to change at line 3792 | |||
} | } | |||
} | } | |||
void YRequest::start(CheckStatusWrapper* status, ITransaction* transaction, int level) | void YRequest::start(CheckStatusWrapper* status, ITransaction* transaction, int level) | |||
{ | { | |||
try | try | |||
{ | { | |||
YEntry<YRequest> entry(status, this); | YEntry<YRequest> entry(status, this); | |||
NextTransaction trans; | NextTransaction trans; | |||
attachment->getNextTransaction(status, transaction, trans); | attachment.get()->getNextTransaction(status, transaction, trans); | |||
entry.next()->start(status, trans, level); | entry.next()->start(status, trans, level); | |||
} | } | |||
catch (const Exception& e) | catch (const Exception& e) | |||
{ | { | |||
e.stuffException(status); | e.stuffException(status); | |||
} | } | |||
} | } | |||
void YRequest::startAndSend(CheckStatusWrapper* status, ITransaction* transactio n, int level, | void YRequest::startAndSend(CheckStatusWrapper* status, ITransaction* transactio n, int level, | |||
unsigned int msgType, unsigned int length, const unsigned char* message) | unsigned int msgType, unsigned int length, const unsigned char* message) | |||
{ | { | |||
try | try | |||
{ | { | |||
YEntry<YRequest> entry(status, this); | YEntry<YRequest> entry(status, this); | |||
NextTransaction trans; | NextTransaction trans; | |||
attachment->getNextTransaction(status, transaction, trans); | attachment.get()->getNextTransaction(status, transaction, trans); | |||
entry.next()->startAndSend(status, trans, level, msgType, length, message); | entry.next()->startAndSend(status, trans, level, msgType, length, message); | |||
} | } | |||
catch (const Exception& e) | catch (const Exception& e) | |||
{ | { | |||
e.stuffException(status); | e.stuffException(status); | |||
} | } | |||
} | } | |||
void YRequest::unwind(CheckStatusWrapper* status, int level) | void YRequest::unwind(CheckStatusWrapper* status, int level) | |||
{ | { | |||
skipping to change at line 3852 | skipping to change at line 3855 | |||
} | } | |||
} | } | |||
//------------------------------------- | //------------------------------------- | |||
YBlob::YBlob(YAttachment* aAttachment, YTransaction* aTransaction, IBlob* aNext) | YBlob::YBlob(YAttachment* aAttachment, YTransaction* aTransaction, IBlob* aNext) | |||
: YHelper(aNext), | : YHelper(aNext), | |||
attachment(aAttachment), | attachment(aAttachment), | |||
transaction(aTransaction) | transaction(aTransaction) | |||
{ | { | |||
attachment->childBlobs.add(this); | aAttachment->childBlobs.add(this); | |||
transaction->childBlobs.add(this); | aTransaction->childBlobs.add(this); | |||
} | } | |||
FB_API_HANDLE& YBlob::getHandle() | FB_API_HANDLE& YBlob::getHandle() | |||
{ | { | |||
if (!handle) | if (!handle) | |||
makeHandle(&blobs, this, handle); | makeHandle(&blobs, this, handle); | |||
return handle; | return handle; | |||
} | } | |||
void YBlob::destroy(unsigned dstrFlags) | void YBlob::destroy(unsigned dstrFlags) | |||
{ | { | |||
attachment->childBlobs.remove(this); | YAttachment* att = attachment.release(); | |||
attachment = NULL; | if (att) | |||
transaction->childBlobs.remove(this); | att->childBlobs.remove(this); | |||
transaction = NULL; | ||||
YTransaction* tra = transaction.release(); | ||||
if (tra) | ||||
tra->childBlobs.remove(this); | ||||
removeHandle(&blobs, handle); | removeHandle(&blobs, handle); | |||
destroy2(dstrFlags); | destroy2(dstrFlags); | |||
} | } | |||
void YBlob::getInfo(CheckStatusWrapper* status, unsigned int itemsLength, | void YBlob::getInfo(CheckStatusWrapper* status, unsigned int itemsLength, | |||
const unsigned char* items, unsigned int bufferLength, unsigned char* buf fer) | const unsigned char* items, unsigned int bufferLength, unsigned char* buf fer) | |||
{ | { | |||
try | try | |||
{ | { | |||
YEntry<YBlob> entry(status, this); | YEntry<YBlob> entry(status, this); | |||
entry.next()->getInfo(status, itemsLength, items, bufferLength, b uffer); | entry.next()->getInfo(status, itemsLength, items, bufferLength, b uffer); | |||
skipping to change at line 3973 | skipping to change at line 3978 | |||
return 0; | return 0; | |||
} | } | |||
//------------------------------------- | //------------------------------------- | |||
YStatement::YStatement(YAttachment* aAttachment, IStatement* aNext) | YStatement::YStatement(YAttachment* aAttachment, IStatement* aNext) | |||
: YHelper(aNext), | : YHelper(aNext), | |||
attachment(aAttachment), cursor(NULL), input(true), output(false) | attachment(aAttachment), cursor(NULL), input(true), output(false) | |||
{ | { | |||
attachment->childStatements.add(this); | attachment.get()->childStatements.add(this); | |||
} | } | |||
void YStatement::destroy(unsigned dstrFlags) | void YStatement::destroy(unsigned dstrFlags) | |||
{ | { | |||
{ // scope | { // scope | |||
MutexLockGuard guard(statementMutex, FB_FUNCTION); | MutexLockGuard guard(statementMutex, FB_FUNCTION); | |||
if (cursor) | if (cursor) | |||
{ | { | |||
cursor->destroy(DF_RELEASE); | cursor->destroy(DF_RELEASE); | |||
cursor = NULL; | cursor = NULL; | |||
} | } | |||
} | } | |||
attachment->childStatements.remove(this); | YAttachment* att = attachment.release(); | |||
attachment = NULL; | if (att) | |||
att->childStatements.remove(this); | ||||
destroy2(dstrFlags); | destroy2(dstrFlags); | |||
} | } | |||
void YStatement::getInfo(CheckStatusWrapper* status, unsigned int itemsLength, | void YStatement::getInfo(CheckStatusWrapper* status, unsigned int itemsLength, | |||
const unsigned char* items, unsigned int bufferLength, unsigned char* buf fer) | const unsigned char* items, unsigned int bufferLength, unsigned char* buf fer) | |||
{ | { | |||
try | try | |||
{ | { | |||
YEntry<YStatement> entry(status, this); | YEntry<YStatement> entry(status, this); | |||
skipping to change at line 4144 | skipping to change at line 4150 | |||
ITransaction* YStatement::execute(CheckStatusWrapper* status, ITransaction* tran saction, | ITransaction* YStatement::execute(CheckStatusWrapper* status, ITransaction* tran saction, | |||
IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetada ta, void* outBuffer) | IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetada ta, void* outBuffer) | |||
{ | { | |||
try | try | |||
{ | { | |||
YEntry<YStatement> entry(status, this); | YEntry<YStatement> entry(status, this); | |||
NextTransaction trans; | NextTransaction trans; | |||
if (transaction) | if (transaction) | |||
attachment->getNextTransaction(status, transaction, trans ); | attachment.get()->getNextTransaction(status, transaction, trans); | |||
ITransaction* newTrans = entry.next()->execute(status, trans, inM etadata, inBuffer, | ITransaction* newTrans = entry.next()->execute(status, trans, inM etadata, inBuffer, | |||
outMetadata, outBuffer); | outMetadata, outBuffer); | |||
if (newTrans == trans) | if (newTrans == trans) | |||
newTrans = transaction; | newTrans = transaction; | |||
else | else | |||
{ | { | |||
if (transaction) | if (transaction) | |||
{ | { | |||
if (trans) | if (trans) | |||
trans->addRef(); // Will be decrem ented by release on next line | trans->addRef(); // Will be decrem ented by release on next line | |||
transaction->release(); | transaction->release(); | |||
transaction = NULL; // Get ready for correct return in OOM case | transaction = NULL; // Get ready for correct return in OOM case | |||
} | } | |||
if (newTrans) | if (newTrans) | |||
{ | { | |||
newTrans = FB_NEW YTransaction(attachment, newTra ns); | newTrans = FB_NEW YTransaction(attachment.get(), newTrans); | |||
newTrans->addRef(); | newTrans->addRef(); | |||
} | } | |||
} | } | |||
return newTrans; | return newTrans; | |||
} | } | |||
catch (const Exception& e) | catch (const Exception& e) | |||
{ | { | |||
e.stuffException(status); | e.stuffException(status); | |||
} | } | |||
skipping to change at line 4187 | skipping to change at line 4193 | |||
IResultSet* YStatement::openCursor(Firebird::CheckStatusWrapper* status, ITransa ction* transaction, | IResultSet* YStatement::openCursor(Firebird::CheckStatusWrapper* status, ITransa ction* transaction, | |||
IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetada ta, unsigned int flags) | IMessageMetadata* inMetadata, void* inBuffer, IMessageMetadata* outMetada ta, unsigned int flags) | |||
{ | { | |||
try | try | |||
{ | { | |||
YEntry<YStatement> entry(status, this); | YEntry<YStatement> entry(status, this); | |||
NextTransaction trans; | NextTransaction trans; | |||
if (transaction) | if (transaction) | |||
attachment->getNextTransaction(status, transaction, trans ); | attachment.get()->getNextTransaction(status, transaction, trans); | |||
IResultSet* rs = entry.next()->openCursor(status, trans, inMetada ta, inBuffer, outMetadata, flags); | IResultSet* rs = entry.next()->openCursor(status, trans, inMetada ta, inBuffer, outMetadata, flags); | |||
if (status->getState() & Firebird::IStatus::STATE_ERRORS) | if (status->getState() & Firebird::IStatus::STATE_ERRORS) | |||
{ | { | |||
return NULL; | return NULL; | |||
} | } | |||
fb_assert(rs); | fb_assert(rs); | |||
YTransaction* const yTra = attachment->getTransaction(status, tra nsaction); | YTransaction* const yTra = attachment.get()->getTransaction(statu s, transaction); | |||
YResultSet* r = FB_NEW YResultSet(attachment, yTra, this, rs); | YResultSet* r = FB_NEW YResultSet(attachment.get(), yTra, this, r s); | |||
r->addRef(); | r->addRef(); | |||
return r; | return r; | |||
} | } | |||
catch (const Exception& e) | catch (const Exception& e) | |||
{ | { | |||
e.stuffException(status); | e.stuffException(status); | |||
} | } | |||
return NULL; | return NULL; | |||
} | } | |||
skipping to change at line 4244 | skipping to change at line 4250 | |||
if (userHandle) | if (userHandle) | |||
{ | { | |||
*userHandle = 0; | *userHandle = 0; | |||
userHandle = NULL; | userHandle = NULL; | |||
} | } | |||
removeHandle(&statements, handle); | removeHandle(&statements, handle); | |||
} | } | |||
void IscStatement::destroy(unsigned) | void IscStatement::destroy(unsigned) | |||
{ | { | |||
attachment->childIscStatements.remove(this); | YAttachment* att = attachment.release(); | |||
attachment = NULL; | if (att) | |||
att->childIscStatements.remove(this); | ||||
release(); | release(); | |||
} | } | |||
FB_API_HANDLE& IscStatement::getHandle() | FB_API_HANDLE& IscStatement::getHandle() | |||
{ | { | |||
if (!handle) | if (!handle) | |||
makeHandle(&statements, this, handle); | makeHandle(&statements, this, handle); | |||
return handle; | return handle; | |||
} | } | |||
skipping to change at line 4360 | skipping to change at line 4368 | |||
//------------------------------------- | //------------------------------------- | |||
YResultSet::YResultSet(YAttachment* anAttachment, YTransaction* aTransaction, IR esultSet* aNext) | YResultSet::YResultSet(YAttachment* anAttachment, YTransaction* aTransaction, IR esultSet* aNext) | |||
: YHelper(aNext), | : YHelper(aNext), | |||
attachment(anAttachment), | attachment(anAttachment), | |||
transaction(aTransaction), | transaction(aTransaction), | |||
statement(NULL) | statement(NULL) | |||
{ | { | |||
fb_assert(aTransaction && aNext); | fb_assert(aTransaction && aNext); | |||
transaction->childCursors.add(this); | aTransaction->childCursors.add(this); | |||
} | } | |||
YResultSet::YResultSet(YAttachment* anAttachment, YTransaction* aTransaction, | YResultSet::YResultSet(YAttachment* anAttachment, YTransaction* aTransaction, | |||
YStatement* aStatement, IResultSet* aNext) | YStatement* aStatement, IResultSet* aNext) | |||
: YHelper(aNext), | : YHelper(aNext), | |||
attachment(anAttachment), | attachment(anAttachment), | |||
transaction(aTransaction), | transaction(aTransaction), | |||
statement(aStatement) | statement(aStatement) | |||
{ | { | |||
fb_assert(aTransaction && aNext); | fb_assert(aTransaction && aNext); | |||
transaction->childCursors.add(this); | aTransaction->childCursors.add(this); | |||
MutexLockGuard guard(statement->statementMutex, FB_FUNCTION); | MutexLockGuard guard(statement->statementMutex, FB_FUNCTION); | |||
if (statement->cursor) | if (statement->cursor) | |||
Arg::Gds(isc_cursor_already_open).raise(); | Arg::Gds(isc_cursor_already_open).raise(); | |||
statement->cursor = this; | statement->cursor = this; | |||
} | } | |||
void YResultSet::destroy(unsigned dstrFlags) | void YResultSet::destroy(unsigned dstrFlags) | |||
{ | { | |||
if (statement) | if (statement) | |||
{ | { | |||
MutexLockGuard guard(statement->statementMutex, FB_FUNCTION); | MutexLockGuard guard(statement->statementMutex, FB_FUNCTION); | |||
fb_assert(statement->cursor == this); | fb_assert(statement->cursor == this); | |||
statement->cursor = NULL; | statement->cursor = NULL; | |||
} | } | |||
fb_assert(transaction); | YTransaction* tra = transaction.release(); | |||
transaction->childCursors.remove(this); | if (tra) | |||
transaction = NULL; | tra->childCursors.remove(this); | |||
destroy2(dstrFlags); | destroy2(dstrFlags); | |||
} | } | |||
void YStatement::setCursorName(CheckStatusWrapper* status, const char* name) | void YStatement::setCursorName(CheckStatusWrapper* status, const char* name) | |||
{ | { | |||
try | try | |||
{ | { | |||
YEntry<YStatement> entry(status, this); | YEntry<YStatement> entry(status, this); | |||
skipping to change at line 4595 | skipping to change at line 4603 | |||
//------------------------------------- | //------------------------------------- | |||
YTransaction::YTransaction(YAttachment* aAttachment, ITransaction* aNext) | YTransaction::YTransaction(YAttachment* aAttachment, ITransaction* aNext) | |||
: YHelper(aNext), | : YHelper(aNext), | |||
attachment(aAttachment), | attachment(aAttachment), | |||
childBlobs(getPool()), | childBlobs(getPool()), | |||
childCursors(getPool()), | childCursors(getPool()), | |||
cleanupHandlers(getPool()) | cleanupHandlers(getPool()) | |||
{ | { | |||
if (attachment) | if (aAttachment) | |||
attachment->childTransactions.add(this); | aAttachment->childTransactions.add(this); | |||
} | } | |||
FB_API_HANDLE& YTransaction::getHandle() | FB_API_HANDLE& YTransaction::getHandle() | |||
{ | { | |||
if (!handle) | if (!handle) | |||
makeHandle(&transactions, this, handle); | makeHandle(&transactions, this, handle); | |||
return handle; | return handle; | |||
} | } | |||
void YTransaction::destroy(unsigned dstrFlags) | void YTransaction::destroy(unsigned dstrFlags) | |||
skipping to change at line 4620 | skipping to change at line 4628 | |||
++handler) | ++handler) | |||
{ | { | |||
(*handler)->cleanupCallbackFunction(); | (*handler)->cleanupCallbackFunction(); | |||
} | } | |||
cleanupHandlers.clear(); | cleanupHandlers.clear(); | |||
childBlobs.destroy(dstrFlags & ~DF_RELEASE); | childBlobs.destroy(dstrFlags & ~DF_RELEASE); | |||
childCursors.destroy(dstrFlags & ~DF_RELEASE); | childCursors.destroy(dstrFlags & ~DF_RELEASE); | |||
if (attachment) | YAttachment* att = attachment.release(); | |||
{ | if (att) | |||
attachment->childTransactions.remove(this); | att->childTransactions.remove(this); | |||
attachment = NULL; | ||||
} | ||||
removeHandle(&transactions, handle); | removeHandle(&transactions, handle); | |||
destroy2(dstrFlags); | destroy2(dstrFlags); | |||
} | } | |||
void YTransaction::getInfo(CheckStatusWrapper* status, unsigned int itemsLength, | void YTransaction::getInfo(CheckStatusWrapper* status, unsigned int itemsLength, | |||
const unsigned char* items, unsigned int bufferLength, unsigned char* buf fer) | const unsigned char* items, unsigned int bufferLength, unsigned char* buf fer) | |||
{ | { | |||
Array<unsigned char> newItemsBuffer; | Array<unsigned char> newItemsBuffer; | |||
try | try | |||
{ | { | |||
YEntry<YTransaction> entry(status, this); | YEntry<YTransaction> entry(status, this); | |||
fb_utils::getDbPathInfo(itemsLength, items, bufferLength, buffer, | fb_utils::getDbPathInfo(itemsLength, items, bufferLength, buffer, | |||
newItemsBuffer, a ttachment->dbPath); | newItemsBuffer, a ttachment.get()->dbPath); | |||
entry.next()->getInfo(status, itemsLength, items, bufferLength, b uffer); | entry.next()->getInfo(status, itemsLength, items, bufferLength, b uffer); | |||
} | } | |||
catch (const Exception& e) | catch (const Exception& e) | |||
{ | { | |||
e.stuffException(status); | e.stuffException(status); | |||
} | } | |||
} | } | |||
void YTransaction::prepare(CheckStatusWrapper* status, unsigned int msgLength, | void YTransaction::prepare(CheckStatusWrapper* status, unsigned int msgLength, | |||
skipping to change at line 4802 | skipping to change at line 4808 | |||
return NULL; | return NULL; | |||
} | } | |||
ITransaction* YTransaction::validate(CheckStatusWrapper* status, IAttachment* te stAtt) | ITransaction* YTransaction::validate(CheckStatusWrapper* status, IAttachment* te stAtt) | |||
{ | { | |||
try | try | |||
{ | { | |||
YEntry<YTransaction> entry(status, this); | YEntry<YTransaction> entry(status, this); | |||
// Do not raise error in status - just return NULL if attachment does not match | // Do not raise error in status - just return NULL if attachment does not match | |||
if (attachment == testAtt) | if (attachment.get() == testAtt) | |||
return this; | return this; | |||
return entry.next()->validate(status, testAtt); | return entry.next()->validate(status, testAtt); | |||
} | } | |||
catch (const Exception& ex) | catch (const Exception& ex) | |||
{ | { | |||
ex.stuffException(status); | ex.stuffException(status); | |||
} | } | |||
return NULL; | return NULL; | |||
skipping to change at line 4827 | skipping to change at line 4833 | |||
try | try | |||
{ | { | |||
YEntry<YTransaction> entry(status, this); | YEntry<YTransaction> entry(status, this); | |||
YTransaction* copy = FB_NEW YTransaction(this); | YTransaction* copy = FB_NEW YTransaction(this); | |||
// copy is created with zero handle | // copy is created with zero handle | |||
copy->addRef(); | copy->addRef(); | |||
copy->addRef(); | copy->addRef(); | |||
next->addRef(); // We use NoIncr in YTransaction ctor | next->addRef(); // We use NoIncr in YTransaction ctor | |||
if (attachment) | YAttachment* att = attachment.release(); | |||
{ | if (att) | |||
attachment->childTransactions.remove(this); | att->childTransactions.remove(this); | |||
attachment = NULL; | ||||
} | ||||
removeHandle(&transactions, handle); | removeHandle(&transactions, handle); | |||
next = NULL; | next = NULL; | |||
release(); | release(); | |||
return copy; | return copy; | |||
} | } | |||
catch (const Exception& ex) | catch (const Exception& ex) | |||
{ | { | |||
ex.stuffException(status); | ex.stuffException(status); | |||
skipping to change at line 5350 | skipping to change at line 5354 | |||
void YAttachment::detach(CheckStatusWrapper* status) | void YAttachment::detach(CheckStatusWrapper* status) | |||
{ | { | |||
try | try | |||
{ | { | |||
YEntry<YAttachment> entry(status, this, 0); | YEntry<YAttachment> entry(status, this, 0); | |||
if (entry.next()) | if (entry.next()) | |||
entry.next()->detach(status); | entry.next()->detach(status); | |||
if (isNetworkError(status)) | ||||
status->init(); | ||||
if (!(status->getState() & Firebird::IStatus::STATE_ERRORS)) | if (!(status->getState() & Firebird::IStatus::STATE_ERRORS)) | |||
destroy(DF_RELEASE); | destroy(DF_RELEASE); | |||
} | } | |||
catch (const Exception& e) | catch (const Exception& e) | |||
{ | { | |||
e.stuffException(status); | e.stuffException(status); | |||
} | } | |||
} | } | |||
void YAttachment::dropDatabase(CheckStatusWrapper* status) | void YAttachment::dropDatabase(CheckStatusWrapper* status) | |||
End of changes. 43 change blocks. | ||||
60 lines changed or deleted | 67 lines changed or added |