2002-12-16 17:35:13 +01:00
|
|
|
/*
|
2005-01-10 19:06:14 +01:00
|
|
|
* 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.
|
2002-12-16 17:35:13 +01:00
|
|
|
*
|
2005-01-10 19:06:14 +01:00
|
|
|
* 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.
|
2002-12-16 17:35:13 +01:00
|
|
|
*
|
2005-01-10 19:06:14 +01:00
|
|
|
* The Original Code was created by Alexander Peshkoff
|
|
|
|
* for the Firebird Open Source RDBMS project.
|
|
|
|
*
|
2005-01-12 05:34:16 +01:00
|
|
|
* Copyright (c) 2002 Alexander Peshkoff <peshkoff@mail.ru>
|
2005-01-10 19:06:14 +01:00
|
|
|
* and all contributors signed below.
|
2002-12-16 17:35:13 +01:00
|
|
|
*
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
2005-01-10 19:06:14 +01:00
|
|
|
* Contributor(s): ______________________________
|
2002-12-16 17:35:13 +01:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2005-01-12 05:34:16 +01:00
|
|
|
#ifndef JRD_Y_HANDLE_H
|
|
|
|
#define JRD_Y_HANDLE_H
|
|
|
|
|
2007-01-20 15:45:45 +01:00
|
|
|
#include "../common/classes/alloc.h"
|
|
|
|
#include "../common/classes/array.h"
|
|
|
|
#include "../common/classes/fb_string.h"
|
|
|
|
#include "../dsql/sqlda_pub.h"
|
|
|
|
#include "../dsql/sqlda.h"
|
|
|
|
#include "../jrd/thread_proto.h"
|
|
|
|
|
|
|
|
#include "gen/iberror.h"
|
|
|
|
|
2002-12-16 17:35:13 +01:00
|
|
|
|
2004-03-20 15:57:40 +01:00
|
|
|
namespace Jrd {
|
|
|
|
class Attachment;
|
|
|
|
class jrd_tra;
|
|
|
|
class jrd_req;
|
|
|
|
}
|
|
|
|
|
2007-01-20 15:45:45 +01:00
|
|
|
class dsql_req;
|
2002-12-16 17:35:13 +01:00
|
|
|
|
2007-01-20 15:45:45 +01:00
|
|
|
namespace YValve
|
2002-12-16 17:35:13 +01:00
|
|
|
{
|
2007-01-20 15:45:45 +01:00
|
|
|
// flags
|
2007-01-26 02:24:48 +01:00
|
|
|
const UCHAR HANDLE_TRANSACTION_limbo = 0x01;
|
|
|
|
const UCHAR HANDLE_BLOB_filter = 0x02; // Blob is locally filtered
|
|
|
|
const UCHAR HANDLE_STATEMENT_local = 0x04; // Process DSQL statement locally
|
|
|
|
const UCHAR HANDLE_STATEMENT_prepared = 0x08;
|
2007-01-20 15:45:45 +01:00
|
|
|
const UCHAR HANDLE_shutdown = 0x10; // Database shutdown
|
|
|
|
|
|
|
|
// forwards
|
|
|
|
class Attachment;
|
|
|
|
class Transaction;
|
|
|
|
class Request;
|
|
|
|
class Blob;
|
|
|
|
class Statement;
|
|
|
|
class Service;
|
|
|
|
|
|
|
|
// force use of default memory pool for Y-Valve objects
|
|
|
|
class DefaultMemory
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
void* operator new(size_t size)
|
|
|
|
{
|
|
|
|
return getDefaultMemoryPool()->allocate(size);
|
|
|
|
}
|
|
|
|
|
|
|
|
void operator delete(void* mem)
|
|
|
|
{
|
|
|
|
getDefaultMemoryPool()->deallocate(mem);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// stored handle types
|
2007-02-06 10:48:50 +01:00
|
|
|
typedef Jrd::jrd_tra StoredTra;
|
|
|
|
typedef void StoredReq;
|
|
|
|
typedef void StoredBlb;
|
|
|
|
typedef Jrd::Attachment StoredAtt;
|
|
|
|
typedef dsql_req StoredStm;
|
|
|
|
typedef void StoredSvc;
|
2007-01-20 15:45:45 +01:00
|
|
|
|
|
|
|
template <typename CleanupRoutine, typename CleanupArg>
|
|
|
|
class Clean : public DefaultMemory
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
struct st_clean
|
|
|
|
{
|
|
|
|
CleanupRoutine *Routine;
|
|
|
|
void* clean_arg;
|
|
|
|
st_clean(CleanupRoutine *r, void* a)
|
|
|
|
: Routine(r), clean_arg(a) { }
|
|
|
|
st_clean()
|
|
|
|
: Routine(0), clean_arg(0) { }
|
|
|
|
};
|
|
|
|
Firebird::HalfStaticArray<st_clean, 1> calls;
|
|
|
|
|
|
|
|
public:
|
|
|
|
Clean() : calls(*getDefaultMemoryPool()) { }
|
|
|
|
|
|
|
|
void add(CleanupRoutine *r, void* a)
|
|
|
|
{
|
|
|
|
for (size_t i = 0; i < calls.getCount(); ++i)
|
|
|
|
{
|
|
|
|
if (calls[i].Routine == r &&
|
|
|
|
calls[i].clean_arg == a)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
calls.add(st_clean(r, a));
|
|
|
|
}
|
|
|
|
|
|
|
|
void call(CleanupArg public_handle)
|
|
|
|
{
|
|
|
|
for (size_t i = 0; i < calls.getCount(); ++i)
|
|
|
|
{
|
|
|
|
if (calls[i].Routine)
|
|
|
|
{
|
|
|
|
THREAD_EXIT();
|
|
|
|
calls[i].Routine(public_handle, calls[i].clean_arg);
|
|
|
|
THREAD_ENTER();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2007-02-06 10:48:50 +01:00
|
|
|
class BaseHandle : public DefaultMemory
|
2007-01-20 15:45:45 +01:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
UCHAR type;
|
|
|
|
UCHAR flags;
|
|
|
|
USHORT implementation;
|
|
|
|
FB_API_HANDLE public_handle;
|
|
|
|
Attachment* parent;
|
|
|
|
FB_API_HANDLE* user_handle;
|
|
|
|
|
|
|
|
protected:
|
2007-02-06 10:48:50 +01:00
|
|
|
BaseHandle(UCHAR t, FB_API_HANDLE* pub, Attachment* par, USHORT imp = ~0);
|
2007-01-20 15:45:45 +01:00
|
|
|
|
|
|
|
public:
|
2007-02-06 10:48:50 +01:00
|
|
|
static BaseHandle* translate(FB_API_HANDLE);
|
2007-01-20 15:45:45 +01:00
|
|
|
Jrd::Attachment* getAttachmentHandle();
|
|
|
|
void cancel();
|
2007-02-06 10:48:50 +01:00
|
|
|
~BaseHandle();
|
2007-01-20 15:45:45 +01:00
|
|
|
|
|
|
|
// required to put pointers to it into the tree
|
2007-02-06 10:48:50 +01:00
|
|
|
static const FB_API_HANDLE& generate(const void* sender, BaseHandle* value) {
|
2007-01-20 15:45:45 +01:00
|
|
|
return value->public_handle;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename HType>
|
|
|
|
void toParent(Firebird::SortedArray<HType*>& members, HType* newMember)
|
|
|
|
{
|
|
|
|
members.add(newMember);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename HType>
|
|
|
|
void fromParent(Firebird::SortedArray<HType*>& members, HType* newMember)
|
|
|
|
{
|
|
|
|
size_t pos;
|
|
|
|
if (members.find(newMember, pos))
|
|
|
|
{
|
|
|
|
members.remove(pos);
|
|
|
|
}
|
|
|
|
#ifdef DEV_BUILD
|
|
|
|
else
|
|
|
|
{
|
|
|
|
//Attempt to deregister not registered member
|
|
|
|
fb_assert(false);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename ToHandle>
|
|
|
|
ToHandle* translate(FB_API_HANDLE* handle)
|
|
|
|
{
|
|
|
|
if (handle && *handle)
|
|
|
|
{
|
2007-02-06 10:48:50 +01:00
|
|
|
BaseHandle* rc = BaseHandle::translate(*handle);
|
2007-01-20 15:45:45 +01:00
|
|
|
if (rc && rc->type == ToHandle::hType())
|
|
|
|
{
|
2007-03-01 14:20:17 +01:00
|
|
|
return static_cast<ToHandle*>(rc);
|
2007-01-20 15:45:45 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Firebird::status_exception::raise(ToHandle::hError(),
|
|
|
|
isc_arg_end);
|
|
|
|
// compiler warning silencer
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-02-06 10:48:50 +01:00
|
|
|
class Attachment : public BaseHandle
|
2007-01-20 15:45:45 +01:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
Firebird::SortedArray<Transaction*> transactions;
|
|
|
|
Firebird::SortedArray<Request*> requests;
|
|
|
|
Firebird::SortedArray<Blob*> blobs;
|
|
|
|
Firebird::SortedArray<Statement*> statements;
|
|
|
|
|
|
|
|
Clean<AttachmentCleanupRoutine, FB_API_HANDLE*> cleanup;
|
2007-02-06 10:48:50 +01:00
|
|
|
StoredAtt* handle;
|
2007-01-20 15:45:45 +01:00
|
|
|
Firebird::PathName db_path;
|
|
|
|
Firebird::Array<SCHAR> db_prepare_buffer;
|
|
|
|
|
|
|
|
static ISC_STATUS hError()
|
|
|
|
{
|
|
|
|
return isc_bad_db_handle;
|
|
|
|
}
|
|
|
|
|
|
|
|
static UCHAR hType()
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
2007-02-06 10:48:50 +01:00
|
|
|
Attachment(StoredAtt*, FB_API_HANDLE*, USHORT);
|
2007-01-20 15:45:45 +01:00
|
|
|
void cancel2();
|
|
|
|
~Attachment();
|
2002-12-16 17:35:13 +01:00
|
|
|
};
|
2007-01-20 15:45:45 +01:00
|
|
|
|
2007-02-06 10:48:50 +01:00
|
|
|
class Transaction : public BaseHandle
|
2007-01-20 15:45:45 +01:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
Clean<TransactionCleanupRoutine, FB_API_HANDLE> cleanup;
|
|
|
|
Transaction* next;
|
2007-02-06 10:48:50 +01:00
|
|
|
StoredTra* handle;
|
2007-01-20 15:45:45 +01:00
|
|
|
|
|
|
|
static ISC_STATUS hError()
|
|
|
|
{
|
|
|
|
return isc_bad_trans_handle;
|
|
|
|
}
|
|
|
|
|
|
|
|
static UCHAR hType()
|
|
|
|
{
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
2007-02-06 10:48:50 +01:00
|
|
|
Transaction(StoredTra* h, FB_API_HANDLE* pub, Attachment* par)
|
|
|
|
: BaseHandle(hType(), pub, par),
|
2007-01-20 15:45:45 +01:00
|
|
|
next(0), handle(h)
|
|
|
|
{
|
2007-02-02 11:51:31 +01:00
|
|
|
toParent<Transaction>(parent->transactions, this);
|
2007-01-20 15:45:45 +01:00
|
|
|
}
|
|
|
|
|
2007-02-08 11:17:06 +01:00
|
|
|
Transaction(FB_API_HANDLE* pub, USHORT a_implementation)
|
|
|
|
: BaseHandle(hType(), pub, 0, a_implementation),
|
2007-01-20 15:45:45 +01:00
|
|
|
next(0), handle(0)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
~Transaction()
|
|
|
|
{
|
|
|
|
cleanup.call(public_handle);
|
|
|
|
if (parent)
|
|
|
|
{
|
2007-02-02 11:51:31 +01:00
|
|
|
fromParent<Transaction>(parent->transactions, this);
|
2007-01-20 15:45:45 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2007-02-06 10:48:50 +01:00
|
|
|
class Request : public BaseHandle
|
2007-01-20 15:45:45 +01:00
|
|
|
{
|
|
|
|
public:
|
2007-02-06 10:48:50 +01:00
|
|
|
StoredReq* handle;
|
2007-01-20 15:45:45 +01:00
|
|
|
|
|
|
|
static ISC_STATUS hError()
|
|
|
|
{
|
|
|
|
return isc_bad_req_handle;
|
|
|
|
}
|
|
|
|
|
|
|
|
static UCHAR hType()
|
|
|
|
{
|
|
|
|
return 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
2007-02-06 10:48:50 +01:00
|
|
|
Request(StoredReq* h, FB_API_HANDLE* pub, Attachment* par)
|
|
|
|
: BaseHandle(hType(), pub, par), handle(h)
|
2007-01-20 15:45:45 +01:00
|
|
|
{
|
2007-02-02 11:51:31 +01:00
|
|
|
toParent<Request>(parent->requests, this);
|
2007-01-20 15:45:45 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
~Request()
|
|
|
|
{
|
2007-02-02 11:51:31 +01:00
|
|
|
fromParent<Request>(parent->requests, this);
|
2007-01-20 15:45:45 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2007-02-06 10:48:50 +01:00
|
|
|
class Blob : public BaseHandle
|
2007-01-20 15:45:45 +01:00
|
|
|
{
|
|
|
|
public:
|
2007-02-06 10:48:50 +01:00
|
|
|
StoredBlb* handle;
|
2007-01-20 15:45:45 +01:00
|
|
|
|
|
|
|
static ISC_STATUS hError()
|
|
|
|
{
|
|
|
|
return isc_bad_segstr_handle;
|
|
|
|
}
|
|
|
|
|
|
|
|
static UCHAR hType()
|
|
|
|
{
|
|
|
|
return 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
2007-02-06 10:48:50 +01:00
|
|
|
Blob(StoredBlb* h, FB_API_HANDLE* pub, Attachment* par)
|
|
|
|
: BaseHandle(hType(), pub, par), handle(h)
|
2007-01-20 15:45:45 +01:00
|
|
|
{
|
2007-02-02 11:51:31 +01:00
|
|
|
toParent<Blob>(parent->blobs, this);
|
2007-01-20 15:45:45 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
~Blob()
|
|
|
|
{
|
2007-02-02 11:51:31 +01:00
|
|
|
fromParent<Blob>(parent->blobs, this);
|
2007-01-20 15:45:45 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2007-02-06 10:48:50 +01:00
|
|
|
class Statement : public BaseHandle
|
2007-01-20 15:45:45 +01:00
|
|
|
{
|
|
|
|
public:
|
2007-02-06 10:48:50 +01:00
|
|
|
StoredStm* handle;
|
2007-01-20 15:45:45 +01:00
|
|
|
struct sqlda_sup das;
|
|
|
|
|
|
|
|
static ISC_STATUS hError()
|
|
|
|
{
|
|
|
|
return isc_bad_stmt_handle;
|
|
|
|
}
|
|
|
|
|
|
|
|
static UCHAR hType()
|
|
|
|
{
|
|
|
|
return 5;
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
2007-02-06 10:48:50 +01:00
|
|
|
Statement(StoredStm* h, FB_API_HANDLE* pub, Attachment* par)
|
|
|
|
: BaseHandle(hType(), pub, par), handle(h)
|
2007-01-20 15:45:45 +01:00
|
|
|
{
|
2007-02-02 11:51:31 +01:00
|
|
|
toParent<Statement>(parent->statements, this);
|
2007-01-20 15:45:45 +01:00
|
|
|
memset(&das, 0, sizeof das);
|
|
|
|
}
|
|
|
|
|
|
|
|
void checkPrepared()
|
|
|
|
{
|
|
|
|
if (!(flags & HANDLE_STATEMENT_prepared))
|
|
|
|
{
|
|
|
|
Firebird::status_exception::raise(isc_unprepared_stmt, isc_arg_end);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
~Statement()
|
|
|
|
{
|
2007-02-02 11:51:31 +01:00
|
|
|
fromParent<Statement>(parent->statements, this);
|
2007-01-20 15:45:45 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2007-02-06 10:48:50 +01:00
|
|
|
class Service : public BaseHandle
|
2007-01-20 15:45:45 +01:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
Clean<AttachmentCleanupRoutine, FB_API_HANDLE*> cleanup;
|
2007-02-06 10:48:50 +01:00
|
|
|
StoredSvc* handle;
|
2007-01-20 15:45:45 +01:00
|
|
|
|
|
|
|
static ISC_STATUS hError()
|
|
|
|
{
|
|
|
|
return isc_bad_svc_handle;
|
|
|
|
}
|
|
|
|
|
|
|
|
static UCHAR hType()
|
|
|
|
{
|
|
|
|
return 6;
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
2007-02-06 10:48:50 +01:00
|
|
|
Service(StoredSvc* h, FB_API_HANDLE* pub, USHORT impl)
|
|
|
|
: BaseHandle(hType(), pub, 0, impl), handle(h)
|
2007-01-20 15:45:45 +01:00
|
|
|
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
~Service()
|
|
|
|
{
|
|
|
|
cleanup.call(&public_handle);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
2006-05-02 00:23:31 +02:00
|
|
|
|
2003-05-22 13:13:22 +02:00
|
|
|
#endif // JRD_Y_HANDLE_H
|