1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 //	File    : $Id: _ibpp.h 69 2006-04-11 13:18:22Z epocman $
4 //	Subject : IBPP internal declarations
5 //
6 ///////////////////////////////////////////////////////////////////////////////
7 //
8 //	(C) Copyright 2000-2006 T.I.P. Group S.A. and the IBPP Team (www.ibpp.org)
9 //
10 //	The contents of this file are subject to the IBPP License (the "License");
11 //	you may not use this file except in compliance with the License.  You may
12 //	obtain a copy of the License at http://www.ibpp.org or in the 'license.txt'
13 //	file which must have been distributed along with this file.
14 //
15 //	This software, distributed under the License, is distributed on an "AS IS"
16 //	basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the
17 //	License for the specific language governing rights and limitations
18 //	under the License.
19 //
20 ///////////////////////////////////////////////////////////////////////////////
21 //
22 //	COMMENTS
23 //
24 //	* 'Internal declarations' means everything used to implement ibpp. This
25 //	  file and its contents is NOT needed by users of the library. All those
26 //	  declarations are wrapped in a namespace : 'ibpp_internals'.
27 //	* Tabulations should be set every four characters when editing this file.
28 //
29 ///////////////////////////////////////////////////////////////////////////////
30 
31 #ifndef __INTERNAL_IBPP_H__
32 #define __INTERNAL_IBPP_H__
33 
34 #include "ibpp.h"
35 
36 #if defined(__BCPLUSPLUS__) || defined(_MSC_VER) || defined(__DMC__)
37 #define HAS_HDRSTOP
38 #endif
39 
40 #if (defined(__GNUC__) && defined(IBPP_WINDOWS))
41 //	Setting flags for ibase.h -- using GCC/Cygwin/MinGW on Win32
42 #ifndef _MSC_VER
43 #define _MSC_VER 1299
44 #endif
45 #ifndef _WIN32
46 #define _WIN32   1
47 #endif
48 #endif
49 
50 #include "ibase.h"		// From Firebird 1.x or InterBase 6.x installation
51 
52 #if (defined(__GNUC__) && defined(IBPP_WINDOWS))
53 //	UNSETTING flags used above for ibase.h -- Huge conflicts with libstdc++ !
54 #undef _MSC_VER
55 #undef _WIN32
56 #endif
57 
58 #ifdef IBPP_WINDOWS
59 #include <windows.h>
60 #endif
61 
62 #include <limits>
63 #include <string>
64 #include <vector>
65 #include <sstream>
66 #include <cstdarg>
67 
68 #ifdef _DEBUG
69 #define ASSERTION(x)	{if (!(x)) {throw LogicExceptionImpl("ASSERTION", \
70 							"'"#x"' is not verified at %s, line %d", \
71 								__FILE__, __LINE__);}}
72 #else
73 #define ASSERTION(x)	/* x */
74 #endif
75 
76 // Fix to famous MSVC 6 variable scope bug
77 #if defined(_MSC_VER) && (_MSC_VER < 1300)	// MSVC 6 should be < 1300
78 #define for if(true)for
79 #endif
80 
81 namespace ibpp_internals
82 {
83 
84 enum flush_debug_stream_type {fds};
85 
86 #ifdef _DEBUG
87 
88 struct DebugStream : public std::stringstream
89 {
90 	// next two operators fix some g++ and vc++ related problems
91 	std::ostream& operator<< (const char* p)
92 		{ static_cast<std::stringstream&>(*this)<< p; return *this; }
93 
94 	std::ostream& operator<< (const std::string& p)
95 		{ static_cast<std::stringstream&>(*this)<< p; return *this; }
96 
97 	DebugStream& operator=(const DebugStream&) {return *this;}
DebugStreamDebugStream98 	DebugStream(const DebugStream&) {}
DebugStreamDebugStream99 	DebugStream() {}
100 };
101 std::ostream& operator<< (std::ostream& a, flush_debug_stream_type);
102 
103 #else
104 
105 struct DebugStream
106 {
107 	template<class T> DebugStream& operator<< (const T&) { return *this; }
108 	// for manipulators
109 	DebugStream& operator<< (std::ostream&(*)(std::ostream&)) { return *this; }
110 };
111 
112 #endif	// _DEBUG
113 
114 class DatabaseImpl;
115 class TransactionImpl;
116 class StatementImpl;
117 class BlobImpl;
118 class ArrayImpl;
119 class EventsImpl;
120 
121 //	Native data types
122 typedef enum {ivArray, ivBlob, ivDate, ivTime, ivTimestamp, ivString,
123 			ivInt16, ivInt32, ivInt64, ivFloat, ivDouble,
124 			ivBool, ivDBKey, ivByte} IITYPE;
125 
126 //
127 //	Those are the Interbase C API prototypes that we use
128 //	Taken 'asis' from IBASE.H, prefix 'isc_' replaced with 'proto_',
129 //	and 'typedef' preprended...
130 //
131 
132 typedef ISC_STATUS ISC_EXPORT proto_create_database (ISC_STATUS *,
133 					    short,
134 					    char *,
135 					    isc_db_handle *,
136 					    short,
137 					    char *,
138 					    short);
139 
140 typedef ISC_STATUS ISC_EXPORT proto_attach_database (ISC_STATUS *,
141 					    short,
142 					    char *,
143 					    isc_db_handle *,
144 					    short,
145 					    char *);
146 
147 typedef ISC_STATUS  ISC_EXPORT proto_detach_database (ISC_STATUS *,
148 					    isc_db_handle *);
149 
150 typedef ISC_STATUS  ISC_EXPORT proto_drop_database (ISC_STATUS *,
151 					  isc_db_handle *);
152 
153 typedef ISC_STATUS  ISC_EXPORT proto_database_info (ISC_STATUS *,
154 					  isc_db_handle *,
155 					  short,
156 					  char *,
157 					  short,
158 					  char *);
159 
160 typedef ISC_STATUS  ISC_EXPORT proto_dsql_execute_immediate (ISC_STATUS *,
161 						   isc_db_handle *,
162 						   isc_tr_handle *,
163 						   unsigned short,
164 						   char *,
165 						   unsigned short,
166 						   XSQLDA *);
167 
168 typedef ISC_STATUS  ISC_EXPORT proto_open_blob2 (ISC_STATUS *,
169 				       isc_db_handle *,
170 				       isc_tr_handle *,
171 				       isc_blob_handle *,
172 				       ISC_QUAD *,
173 				       short,
174 				       char *);
175 
176 typedef ISC_STATUS  ISC_EXPORT proto_create_blob2 (ISC_STATUS *,
177 					isc_db_handle *,
178 					isc_tr_handle *,
179 					isc_blob_handle *,
180 					ISC_QUAD *,
181 					short,
182 					char *);
183 
184 typedef ISC_STATUS  ISC_EXPORT proto_close_blob (ISC_STATUS *,
185 				       isc_blob_handle *);
186 
187 typedef ISC_STATUS  ISC_EXPORT proto_cancel_blob (ISC_STATUS *,
188 				        isc_blob_handle *);
189 
190 typedef ISC_STATUS  ISC_EXPORT proto_get_segment (ISC_STATUS *,
191 				        isc_blob_handle *,
192 				        unsigned short *,
193 				        unsigned short,
194 				        char *);
195 
196 typedef ISC_STATUS  ISC_EXPORT proto_put_segment (ISC_STATUS *,
197 					isc_blob_handle *,
198 					unsigned short,
199 					char *);
200 
201 typedef ISC_STATUS  ISC_EXPORT proto_blob_info (ISC_STATUS *,
202 				      isc_blob_handle *,
203 				      short,
204  				      char *,
205 				      short,
206 				      char *);
207 
208 typedef ISC_STATUS  ISC_EXPORT proto_array_lookup_bounds (ISC_STATUS *,
209 						isc_db_handle *,
210 						isc_tr_handle *,
211 						char *,
212 						char *,
213 						ISC_ARRAY_DESC *);
214 
215 typedef ISC_STATUS  ISC_EXPORT proto_array_get_slice (ISC_STATUS *,
216 					    isc_db_handle *,
217 					    isc_tr_handle *,
218 					    ISC_QUAD *,
219 					    ISC_ARRAY_DESC *,
220 					    void *,
221 					    ISC_LONG *);
222 
223 typedef ISC_STATUS  ISC_EXPORT proto_array_put_slice (ISC_STATUS *,
224 					    isc_db_handle *,
225 					    isc_tr_handle *,
226 					    ISC_QUAD *,
227 					    ISC_ARRAY_DESC *,
228 					    void *,
229 					    ISC_LONG *);
230 
231 typedef ISC_LONG    ISC_EXPORT proto_vax_integer (char *,
232 					short);
233 
234 typedef ISC_LONG    ISC_EXPORT proto_sqlcode (ISC_STATUS *);
235 
236 typedef void        ISC_EXPORT proto_sql_interprete (short,
237 					   char *,
238 					   short);
239 
240 typedef ISC_STATUS  ISC_EXPORT proto_interprete (char *,
241 				       ISC_STATUS * *);
242 
243 typedef ISC_STATUS  ISC_EXPORT proto_que_events (ISC_STATUS *,
244 				       isc_db_handle *,
245 				       ISC_LONG *,
246 				       short,
247 				       char *,
248 				       isc_callback,
249 				       void *);
250 
251 typedef ISC_STATUS  ISC_EXPORT proto_cancel_events (ISC_STATUS *,
252 					  isc_db_handle *,
253 					  ISC_LONG *);
254 
255 typedef ISC_STATUS  ISC_EXPORT proto_start_multiple (ISC_STATUS *,
256 					   isc_tr_handle *,
257 					   short,
258 					   void *);
259 
260 typedef ISC_STATUS  ISC_EXPORT proto_commit_transaction (ISC_STATUS *,
261 					       isc_tr_handle *);
262 
263 typedef ISC_STATUS  ISC_EXPORT proto_commit_retaining (ISC_STATUS *,
264 					     isc_tr_handle *);
265 
266 typedef ISC_STATUS  ISC_EXPORT proto_rollback_transaction (ISC_STATUS *,
267 						 isc_tr_handle *);
268 
269 typedef ISC_STATUS  ISC_EXPORT proto_rollback_retaining (ISC_STATUS *,
270 						 isc_tr_handle *);
271 
272 ///////////
273 typedef ISC_STATUS  ISC_EXPORT proto_dsql_allocate_statement (ISC_STATUS *,
274 						    isc_db_handle *,
275 						    isc_stmt_handle *);
276 
277 typedef ISC_STATUS  ISC_EXPORT proto_dsql_describe (ISC_STATUS *,
278 					  isc_stmt_handle *,
279 					  unsigned short,
280 					  XSQLDA *);
281 
282 typedef ISC_STATUS  ISC_EXPORT proto_dsql_describe_bind (ISC_STATUS *,
283 					       isc_stmt_handle *,
284 					       unsigned short,
285 					       XSQLDA *);
286 
287 typedef ISC_STATUS  ISC_EXPORT proto_dsql_execute (ISC_STATUS *,
288 					 isc_tr_handle *,
289 					 isc_stmt_handle *,
290 					 unsigned short,
291 					 XSQLDA *);
292 
293 typedef ISC_STATUS  ISC_EXPORT proto_dsql_execute2 (ISC_STATUS *,
294 					  isc_tr_handle *,
295 					  isc_stmt_handle *,
296 					  unsigned short,
297 					  XSQLDA *,
298 					  XSQLDA *);
299 
300 typedef ISC_STATUS  ISC_EXPORT proto_dsql_fetch (ISC_STATUS *,
301 				       isc_stmt_handle *,
302 				       unsigned short,
303 				       XSQLDA *);
304 
305 typedef ISC_STATUS  ISC_EXPORT proto_dsql_free_statement (ISC_STATUS *,
306 						isc_stmt_handle *,
307 						unsigned short);
308 
309 typedef ISC_STATUS  ISC_EXPORT proto_dsql_prepare (ISC_STATUS *,
310 					 isc_tr_handle *,
311 					 isc_stmt_handle *,
312 					 unsigned short,
313 					 char *,
314 					 unsigned short,
315 				 	 XSQLDA *);
316 
317 typedef ISC_STATUS  ISC_EXPORT proto_dsql_set_cursor_name (ISC_STATUS *,
318 						 isc_stmt_handle *,
319 						 char *,
320 						 unsigned short);
321 
322 typedef ISC_STATUS  ISC_EXPORT proto_dsql_sql_info (ISC_STATUS *,
323 					  isc_stmt_handle *,
324 					  short,
325 					  char *,
326 					  short,
327 					  char *);
328 
329 typedef void        ISC_EXPORT proto_decode_date (ISC_QUAD *,
330 					void *);
331 
332 typedef void        ISC_EXPORT proto_encode_date (void *,
333 					ISC_QUAD *);
334 
335 typedef int			ISC_EXPORT proto_add_user (ISC_STATUS *, USER_SEC_DATA *);
336 typedef int			ISC_EXPORT proto_delete_user (ISC_STATUS *, USER_SEC_DATA *);
337 typedef int			ISC_EXPORT proto_modify_user (ISC_STATUS *, USER_SEC_DATA *);
338 
339 //
340 //	Those API are only available in versions 6.x of the GDS32.DLL
341 //
342 
343 typedef ISC_STATUS  ISC_EXPORT proto_service_attach (ISC_STATUS *,
344 					   unsigned short,
345 					   char *,
346 					   isc_svc_handle *,
347 					   unsigned short,
348 					   char *);
349 
350 typedef ISC_STATUS  ISC_EXPORT proto_service_detach (ISC_STATUS *,
351 					   isc_svc_handle *);
352 
353 typedef ISC_STATUS  ISC_EXPORT proto_service_query (ISC_STATUS *,
354 					  isc_svc_handle *,
355                       		          isc_resv_handle *,
356 					  unsigned short,
357 					  char *,
358 					  unsigned short,
359 					  char *,
360 					  unsigned short,
361 					  char *);
362 
363 typedef ISC_STATUS ISC_EXPORT proto_service_start (ISC_STATUS *,
364     					 isc_svc_handle *,
365                          		 isc_resv_handle *,
366     					 unsigned short,
367     					 char*);
368 
369 typedef void        ISC_EXPORT proto_decode_sql_date (ISC_DATE *,
370 					void *);
371 
372 typedef void        ISC_EXPORT proto_decode_sql_time (ISC_TIME *,
373 					void *);
374 
375 typedef void        ISC_EXPORT proto_decode_timestamp (ISC_TIMESTAMP *,
376 					void *);
377 
378 typedef void        ISC_EXPORT proto_encode_sql_date (void *,
379 					ISC_DATE *);
380 
381 typedef void        ISC_EXPORT proto_encode_sql_time (void *,
382 					ISC_TIME *);
383 
384 typedef void        ISC_EXPORT proto_encode_timestamp (void *,
385 					ISC_TIMESTAMP *);
386 
387 //
388 //	Internal binding structure to the GDS32 DLL
389 //
390 
391 struct GDS
392 {
393 	// Attributes
394 	bool mReady;
395 	int mGDSVersion; 		// Version of the GDS32.DLL (50 for 5.0, 60 for 6.0)
396 
397 #ifdef IBPP_WINDOWS
398 	HMODULE mHandle;			// The GDS32.DLL HMODULE
399 	std::string mSearchPaths;	// Optional additional search paths
400 #endif
401 
402 	GDS* Call();
403 
404 	// GDS32 Entry Points
405 	proto_create_database*			m_create_database;
406 	proto_attach_database*			m_attach_database;
407 	proto_detach_database*			m_detach_database;
408 	proto_drop_database*			m_drop_database;
409 	proto_database_info*			m_database_info;
410 	proto_dsql_execute_immediate*	m_dsql_execute_immediate;
411 	proto_open_blob2*				m_open_blob2;
412 	proto_create_blob2*				m_create_blob2;
413 	proto_close_blob*				m_close_blob;
414 	proto_cancel_blob*				m_cancel_blob;
415 	proto_get_segment*				m_get_segment;
416 	proto_put_segment*				m_put_segment;
417 	proto_blob_info*				m_blob_info;
418 	proto_array_lookup_bounds*		m_array_lookup_bounds;
419 	proto_array_get_slice*			m_array_get_slice;
420 	proto_array_put_slice*			m_array_put_slice;
421 
422 	proto_vax_integer*				m_vax_integer;
423 	proto_sqlcode*					m_sqlcode;
424 	proto_sql_interprete*			m_sql_interprete;
425 	proto_interprete*				m_interprete;
426 	proto_que_events*				m_que_events;
427 	proto_cancel_events* 			m_cancel_events;
428 	proto_start_multiple*			m_start_multiple;
429 	proto_commit_transaction*		m_commit_transaction;
430 	proto_commit_retaining*			m_commit_retaining;
431 	proto_rollback_transaction*		m_rollback_transaction;
432 	proto_rollback_retaining*		m_rollback_retaining;
433 	proto_dsql_allocate_statement*	m_dsql_allocate_statement;
434 	proto_dsql_describe*			m_dsql_describe;
435 	proto_dsql_describe_bind*		m_dsql_describe_bind;
436 	proto_dsql_prepare*				m_dsql_prepare;
437 	proto_dsql_execute*				m_dsql_execute;
438 	proto_dsql_execute2*			m_dsql_execute2;
439 	proto_dsql_fetch*				m_dsql_fetch;
440 	proto_dsql_free_statement*		m_dsql_free_statement;
441 	proto_dsql_set_cursor_name*		m_dsql_set_cursor_name;
442 	proto_dsql_sql_info* 			m_dsql_sql_info;
443 	//proto_decode_date*				m_decode_date;
444 	//proto_encode_date*				m_encode_date;
445 	//proto_add_user*					m_add_user;
446 	//proto_delete_user*				m_delete_user;
447 	//proto_modify_user*				m_modify_user;
448 
449 	proto_service_attach*			m_service_attach;
450 	proto_service_detach*			m_service_detach;
451 	proto_service_start*			m_service_start;
452 	proto_service_query*			m_service_query;
453 	//proto_decode_sql_date*			m_decode_sql_date;
454 	//proto_decode_sql_time*			m_decode_sql_time;
455 	//proto_decode_timestamp*			m_decode_timestamp;
456 	//proto_encode_sql_date*			m_encode_sql_date;
457 	//proto_encode_sql_time*			m_encode_sql_time;
458 	//proto_encode_timestamp*			m_encode_timestamp;
459 
460 	// Constructor (No need for a specific destructor)
GDSGDS461 	GDS()
462 	{
463 		mReady = false;
464 		mGDSVersion = 0;
465 #ifdef IBPP_WINDOWS
466 		mHandle = 0;
467 #endif
468 	};
469 };
470 
471 extern GDS gds;
472 
473 //
474 //	Service Parameter Block (used to define a service)
475 //
476 
477 class SPB
478 {
479 	static const int BUFFERINCR;
480 
481 	char* mBuffer;				// Dynamically allocated SPB structure
482 	int mSize;  				// Its used size in bytes
483 	int mAlloc;					// Its allocated size in bytes
484 
485 	void Grow(int needed);		// Alloc or grow the mBuffer
486 
487 public:
488 	void Insert(char);			// Insert a single byte code
489 	void InsertString(char, int, const char*);	// Insert a string, len can be defined as 1 or 2 bytes
490 	void InsertByte(char type, char data);
491 	void InsertQuad(char type, int32_t data);
492 	void Reset();			// Clears the SPB
Self()493 	char* Self() { return mBuffer; }
Size()494 	short Size() { return (short)mSize; }
495 
SPB()496 	SPB() : mBuffer(0), mSize(0), mAlloc(0) { }
~SPB()497 	~SPB() { Reset(); }
498 };
499 
500 //
501 //	Database Parameter Block (used to define a database)
502 //
503 
504 class DPB
505 {
506 	static const int BUFFERINCR;
507 
508 	char* mBuffer;				// Dynamically allocated DPB structure
509 	int mSize;  				// Its used size in bytes
510 	int mAlloc;					// Its allocated size in bytes
511 
512 	void Grow(int needed);		// Allocate or grow the mBuffer, so that
513 								// 'needed' bytes can be written (at least)
514 
515 public:
516 	void Insert(char, const char*);	// Insert a new char* 'cluster'
517 	void Insert(char, int16_t);		// Insert a new int16_t 'cluster'
518 	void Insert(char, bool);   		// Insert a new bool 'cluster'
519 	void Insert(char, char);   		// Insert a new byte 'cluster'
520 	void Reset();				// Clears the DPB
Self()521 	char* Self() { return mBuffer; }
Size()522 	short Size() { return (short)mSize; }
523 
DPB()524 	DPB() : mBuffer(0), mSize(0), mAlloc(0) { }
~DPB()525 	~DPB() { Reset(); }
526 };
527 
528 //
529 //	Transaction Parameter Block (used to define a transaction)
530 //
531 
532 class TPB
533 {
534 	static const int BUFFERINCR;
535 
536 	char* mBuffer;					// Dynamically allocated TPB structure
537 	int mSize;						// Its used size in bytes
538 	int mAlloc;						// Its allocated size
539 
540 	void Grow(int needed);			// Alloc or re-alloc the mBuffer
541 
542 public:
543 	void Insert(char);				// Insert a flag item
544 	void Insert(const std::string& data); // Insert a string (typically table name)
545 	void Reset();				// Clears the TPB
Self()546 	char* Self() { return mBuffer; }
Size()547 	int Size() { return mSize; }
548 
TPB()549 	TPB() : mBuffer(0), mSize(0), mAlloc(0) { }
~TPB()550 	~TPB() { Reset(); }
551 };
552 
553 //
554 //	Used to receive (and process) a results buffer in various API calls
555 //
556 
557 class RB
558 {
559 	char* mBuffer;
560 	int mSize;
561 
562 	char* FindToken(char token);
563 	char* FindToken(char token, char subtoken);
564 
565 public:
566 	void Reset();
567 	int GetValue(char token);
568 	int GetCountValue(char token);
569 	int GetValue(char token, char subtoken);
570 	bool GetBool(char token);
571 	int GetString(char token, std::string& data);
572 
Self()573 	char* Self() { return mBuffer; }
Size()574 	short Size() { return (short)mSize; }
575 
576 	RB();
577 	RB(int Size);
578 	~RB();
579 };
580 
581 //
582 //	Used to receive status info from API calls
583 //
584 
585 class IBS
586 {
587 	mutable ISC_STATUS mVector[20];
588 	mutable std::string mMessage;
589 
590 public:
Self()591 	ISC_STATUS* Self() { return mVector; }
Errors()592 	bool Errors() { return (mVector[0] == 1 && mVector[1] > 0) ? true : false; }
593 	const char* ErrorMessage() const;
594 	int SqlCode() const;
EngineCode()595 	int EngineCode() const { return (mVector[0] == 1) ? (int)mVector[1] : 0; }
596 	void Reset();
597 
598 	IBS();
599 	IBS(IBS&);	// Copy Constructor
600 	~IBS();
601 };
602 
603 ///////////////////////////////////////////////////////////////////////////////
604 //
605 //	Implementation of the "hidden" classes associated with their public
606 //	counterparts. Their private data and methods can freely change without
607 //	breaking the compatibility of the DLL. If they receive new public methods,
608 //	and those methods are reflected in the public class, then the compatibility
609 //	is broken.
610 //
611 ///////////////////////////////////////////////////////////////////////////////
612 
613 //
614 // Hidden implementation of Exception classes.
615 //
616 
617 /*
618                          std::exception
619                                 |
620                          IBPP::Exception
621                        /                 \
622                       /                   \
623   IBPP::LogicException    ExceptionBase    IBPP::SQLException
624         |        \         /   |     \     /
625         |   LogicExceptionImpl |   SQLExceptionImpl
626         |                      |
627     IBPP::WrongType            |
628                \               |
629               IBPP::WrongTypeImpl
630 */
631 
632 class ExceptionBase
633 {
634 	//	(((((((( OBJECT INTERNALS ))))))))
635 
636 protected:
637 	std::string mContext; 			// Exception context ("IDatabase::Drop")
638 	std::string mWhat;				// Full formatted message
639 
640 	void buildErrorMessage(const char* message);
641 	void raise(const std::string& context, const char* message, va_list argptr);
642 
643 public:
644 	// The following constructors are small and could be inlined, but for object
645 	// code compacity of the library it is much better to have them non-inlined.
646 	// The amount of code generated by compilers for a throw is well-enough.
647 
648 	ExceptionBase() throw();
649 	ExceptionBase(const ExceptionBase& copied) throw();
650 	ExceptionBase& operator=(const ExceptionBase& copied) throw();
651 	ExceptionBase(const std::string& context, const char* message = 0, ...) throw();
652 
653 	virtual ~ExceptionBase() throw();
654 
655 	//	(((((((( OBJECT INTERFACE ))))))))
656 
657     virtual const char* Origin() const throw();
658     virtual const char* ErrorMessage() const throw();
659 	virtual const char* what() const throw();
660 };
661 
662 class LogicExceptionImpl : public IBPP::LogicException, public ExceptionBase
663 {
664 	//	(((((((( OBJECT INTERNALS ))))))))
665 
666 public:
667 	// The following constructors are small and could be inlined, but for object
668 	// code compacity of the library it is much better to have them non-inlined.
669 	// The amount of code generated by compilers for a throw is well-enough.
670 
671 	LogicExceptionImpl() throw();
672 	LogicExceptionImpl(const LogicExceptionImpl& copied) throw();
673 	LogicExceptionImpl& operator=(const LogicExceptionImpl& copied) throw();
674 	LogicExceptionImpl(const std::string& context, const char* message = 0, ...) throw();
675 
676 	virtual ~LogicExceptionImpl() throw ();
677 
678 	//	(((((((( OBJECT INTERFACE ))))))))
679 	//
680 	//	The object public interface is partly implemented by inheriting from
681 	//	the ExceptionBase class.
682 
683 public:
684     virtual const char* Origin() const throw();
685     virtual const char* ErrorMessage() const throw();
686 	virtual const char* what() const throw();
687 };
688 
689 class SQLExceptionImpl : public IBPP::SQLException, public ExceptionBase
690 {
691 	//	(((((((( OBJECT INTERNALS ))))))))
692 
693 private:
694 	int mSqlCode;
695 	int mEngineCode;
696 
697 public:
698 	// The following constructors are small and could be inlined, but for object
699 	// code compacity of the library it is much better to have them non-inlined.
700 	// The amount of code generated by compilers for a throw is well-enough.
701 
702 	SQLExceptionImpl() throw();
703 	SQLExceptionImpl(const SQLExceptionImpl& copied) throw();
704 	SQLExceptionImpl& operator=(const SQLExceptionImpl& copied) throw();
705 	SQLExceptionImpl(const IBS& status, const std::string& context,
706 						const char* message = 0, ...) throw();
707 
708 	virtual ~SQLExceptionImpl() throw ();
709 
710 	//	(((((((( OBJECT INTERFACE ))))))))
711 	//
712 	//	The object public interface is partly implemented by inheriting from
713 	//	the ExceptionBase class.
714 
715 public:
716     virtual const char* Origin() const throw();
717     virtual const char* ErrorMessage() const throw();
718 	virtual const char* what() const throw();
719 	virtual int SqlCode() const throw();
720 	virtual int EngineCode() const throw();
721 };
722 
723 class WrongTypeImpl : public IBPP::WrongType, public ExceptionBase
724 {
725 	//	(((((((( OBJECT INTERNALS ))))))))
726 
727 public:
728 	// The following constructors are small and could be inlined, but for object
729 	// code compacity of the library it is much better to have them non-inlined.
730 	// The amount of code generated by compilers for a throw is well-enough.
731 
732 	WrongTypeImpl() throw();
733 	WrongTypeImpl(const WrongTypeImpl& copied) throw();
734 	WrongTypeImpl& operator=(const WrongTypeImpl& copied) throw();
735 	WrongTypeImpl(const std::string& context, int sqlType, IITYPE varType,
736 					const char* message = 0, ...) throw();
737 
738 	virtual ~WrongTypeImpl() throw ();
739 
740 	//	(((((((( OBJECT INTERFACE ))))))))
741 	//
742 	//	The object public interface is partly implemented by inheriting from
743 	//	the ExceptionBase class.
744 
745 public:
746     virtual const char* Origin() const throw();
747     virtual const char* ErrorMessage() const throw();
748 	virtual const char* what() const throw();
749 };
750 
751 class ServiceImpl : public IBPP::IService
752 {
753 	//	(((((((( OBJECT INTERNALS ))))))))
754 
755 private:
756 	int mRefCount;				// Reference counter
757     isc_svc_handle mHandle;		// InterBase API Service Handle
758 	std::string mServerName;	// Nom du serveur
759     std::string mUserName;		// Nom de l'utilisateur
760     std::string mUserPassword;	// Mot de passe de l'utilisateur
761 	std::string mWaitMessage;	// Progress message returned by WaitMsg()
762 
GetHandlePtr()763 	isc_svc_handle* GetHandlePtr() { return &mHandle; }
764 	void SetServerName(const char*);
765 	void SetUserName(const char*);
766 	void SetUserPassword(const char*);
767 
768 public:
GetHandle()769 	isc_svc_handle GetHandle() { return mHandle; }
770 
771 	ServiceImpl(const std::string& ServerName, const std::string& UserName,
772 					const std::string& UserPassword);
773     ~ServiceImpl();
774 
775 	//	(((((((( OBJECT INTERFACE ))))))))
776 
777 public:
778     void Connect();
Connected()779 	bool Connected() { return mHandle == 0 ? false : true; }
780 	void Disconnect();
781 
782 	void GetVersion(std::string& version);
783 
784 	void AddUser(const IBPP::User&);
785 	void GetUser(IBPP::User&);
786 	void GetUsers(std::vector<IBPP::User>&);
787 	void ModifyUser(const IBPP::User&);
788 	void RemoveUser(const std::string& username);
789 
790 	void SetPageBuffers(const std::string& dbfile, int buffers);
791 	void SetSweepInterval(const std::string& dbfile, int sweep);
792 	void SetSyncWrite(const std::string& dbfile, bool);
793 	void SetReadOnly(const std::string& dbfile, bool);
794 	void SetReserveSpace(const std::string& dbfile, bool);
795 
796 	void Shutdown(const std::string& dbfile, IBPP::DSM mode, int sectimeout);
797 	void Restart(const std::string& dbfile);
798 	void Sweep(const std::string& dbfile);
799 	void Repair(const std::string& dbfile, IBPP::RPF flags);
800 
801 	void StartBackup(const std::string& dbfile, const std::string& bkfile,
802 		IBPP::BRF flags = IBPP::BRF(0));
803 	void StartRestore(const std::string& bkfile, const std::string& dbfile,
804 		int pagesize, IBPP::BRF flags = IBPP::BRF(0));
805 
806 	const char* WaitMsg();
807 	void Wait();
808 
809 	IBPP::IService* AddRef();
810 	void Release();
811 };
812 
813 class DatabaseImpl : public IBPP::IDatabase
814 {
815 	//	(((((((( OBJECT INTERNALS ))))))))
816 
817 	int mRefCount;				// Reference counter
818     isc_db_handle mHandle;		// InterBase API Session Handle
819 	std::string mServerName;	// Server name
820     std::string mDatabaseName;	// Database name (path/file)
821     std::string mUserName;	  	// User name
822     std::string mUserPassword;	// User password
823     std::string mRoleName;	  	// Role used for the duration of the connection
824 	std::string mCharSet;	  	// Character Set used for the connection
825 	std::string mCreateParams;	// Other parameters (creation only)
826 
827 	int mDialect;							// 1 if IB5, 1 or 3 if IB6/FB1
828 	std::vector<TransactionImpl*> mTransactions;// Table of Transaction*
829 	std::vector<StatementImpl*> mStatements;// Table of Statement*
830 	std::vector<BlobImpl*> mBlobs;			// Table of Blob*
831 	std::vector<ArrayImpl*> mArrays;		// Table of Array*
832 	std::vector<EventsImpl*> mEvents;		// Table of Events*
833 
834 public:
GetHandlePtr()835 	isc_db_handle* GetHandlePtr() { return &mHandle; }
GetHandle()836 	isc_db_handle GetHandle() { return mHandle; }
837 
838 	void AttachTransactionImpl(TransactionImpl*);
839 	void DetachTransactionImpl(TransactionImpl*);
840 	void AttachStatementImpl(StatementImpl*);
841 	void DetachStatementImpl(StatementImpl*);
842 	void AttachBlobImpl(BlobImpl*);
843 	void DetachBlobImpl(BlobImpl*);
844 	void AttachArrayImpl(ArrayImpl*);
845 	void DetachArrayImpl(ArrayImpl*);
846 	void AttachEventsImpl(EventsImpl*);
847 	void DetachEventsImpl(EventsImpl*);
848 
849 	DatabaseImpl(const std::string& ServerName, const std::string& DatabaseName,
850 				const std::string& UserName, const std::string& UserPassword,
851 				const std::string& RoleName, const std::string& CharSet,
852 				const std::string& CreateParams);
853     ~DatabaseImpl();
854 
855 	//	(((((((( OBJECT INTERFACE ))))))))
856 
857 public:
ServerName()858 	const char* ServerName() const		{ return mServerName.c_str(); }
DatabaseName()859 	const char* DatabaseName() const	{ return mDatabaseName.c_str(); }
Username()860 	const char* Username() const		{ return mUserName.c_str(); }
UserPassword()861 	const char* UserPassword() const	{ return mUserPassword.c_str(); }
RoleName()862 	const char* RoleName() const		{ return mRoleName.c_str(); }
CharSet()863 	const char* CharSet() const			{ return mCharSet.c_str(); }
CreateParams()864 	const char* CreateParams() const	{ return mCreateParams.c_str(); }
865 
866 	void Info(int* ODSMajor, int* ODSMinor,
867 		int* PageSize, int* Pages, int* Buffers, int* Sweep,
868 		bool* SyncWrites, bool* Reserve);
869 	void Statistics(int* Fetches, int* Marks, int* Reads, int* Writes);
870 	void Counts(int* Insert, int* Update, int* Delete,
871 		int* ReadIdx, int* ReadSeq);
872 	void Users(std::vector<std::string>& users);
Dialect()873 	int Dialect() { return mDialect; }
874 
875     void Create(int dialect);
876 	void Connect();
Connected()877 	bool Connected() { return mHandle == 0 ? false : true; }
878 	void Inactivate();
879 	void Disconnect();
880     void Drop();
881 
882 	IBPP::IDatabase* AddRef();
883 	void Release();
884 };
885 
886 class TransactionImpl : public IBPP::ITransaction
887 {
888 	//	(((((((( OBJECT INTERNALS ))))))))
889 
890 private:
891 	int mRefCount;					// Reference counter
892     isc_tr_handle mHandle;			// Transaction InterBase
893 
894 	std::vector<DatabaseImpl*> mDatabases;   	// Tableau de IDatabase*
895 	std::vector<StatementImpl*> mStatements;	// Tableau de IStatement*
896 	std::vector<BlobImpl*> mBlobs;				// Tableau de IBlob*
897 	std::vector<ArrayImpl*> mArrays;			// Tableau de Array*
898 	std::vector<TPB*> mTPBs;					// Tableau de TPB
899 
900 	void Init();			// A usage exclusif des constructeurs
901 
902 public:
GetHandlePtr()903 	isc_tr_handle* GetHandlePtr() { return &mHandle; }
GetHandle()904 	isc_tr_handle GetHandle() { return mHandle; }
905 
906 	void AttachStatementImpl(StatementImpl*);
907 	void DetachStatementImpl(StatementImpl*);
908 	void AttachBlobImpl(BlobImpl*);
909 	void DetachBlobImpl(BlobImpl*);
910 	void AttachArrayImpl(ArrayImpl*);
911 	void DetachArrayImpl(ArrayImpl*);
912     void AttachDatabaseImpl(DatabaseImpl* dbi, IBPP::TAM am = IBPP::amWrite,
913 			IBPP::TIL il = IBPP::ilConcurrency,
914 			IBPP::TLR lr = IBPP::lrWait, IBPP::TFF flags = IBPP::TFF(0));
915     void DetachDatabaseImpl(DatabaseImpl* dbi);
916 
917 	TransactionImpl(DatabaseImpl* db, IBPP::TAM am = IBPP::amWrite,
918 		IBPP::TIL il = IBPP::ilConcurrency,
919 		IBPP::TLR lr = IBPP::lrWait, IBPP::TFF flags = IBPP::TFF(0));
920     ~TransactionImpl();
921 
922 	//	(((((((( OBJECT INTERFACE ))))))))
923 
924 public:
925     void AttachDatabase(IBPP::Database db, IBPP::TAM am = IBPP::amWrite,
926 			IBPP::TIL il = IBPP::ilConcurrency,
927 			IBPP::TLR lr = IBPP::lrWait, IBPP::TFF flags = IBPP::TFF(0));
928     void DetachDatabase(IBPP::Database db);
929 	void AddReservation(IBPP::Database db,
930 			const std::string& table, IBPP::TTR tr);
931 
932     void Start();
Started()933 	bool Started() { return mHandle == 0 ? false : true; }
934     void Commit();
935     void Rollback();
936     void CommitRetain();
937 	void RollbackRetain();
938 
939 	IBPP::ITransaction* AddRef();
940 	void Release();
941 };
942 
943 class RowImpl : public IBPP::IRow
944 {
945 	//	(((((((( OBJECT INTERNALS ))))))))
946 
947 private:
948 	int mRefCount;					// Reference counter
949 
950 	XSQLDA* mDescrArea;				// XSQLDA descriptor itself
951 	std::vector<double> mNumerics;	// Temporary storage for Numerics
952 	std::vector<float> mFloats;	 	// Temporary storage for Floats
953 	std::vector<int64_t> mInt64s;	// Temporary storage for 64 bits
954 	std::vector<int32_t> mInt32s;	// Temporary storage for 32 bits
955 	std::vector<int16_t> mInt16s;	// Temporary storage for 16 bits
956 	std::vector<char> mBools;		// Temporary storage for Bools
957 	std::vector<std::string> mStrings;	// Temporary storage for Strings
958 	std::vector<bool> mUpdated;		// Which columns where updated (Set()) ?
959 
960 	int mDialect;					// Related database dialect
961 	DatabaseImpl* mDatabase;		// Related Database (important for Blobs, ...)
962 	TransactionImpl* mTransaction;	// Related Transaction (same remark)
963 
964 	void SetValue(int, IITYPE, const void* value, int = 0);
965 	void* GetValue(int, IITYPE, void* = 0);
966 
967 public:
968 	void Free();
AllocatedSize()969 	short AllocatedSize() { return mDescrArea->sqln; }
970 	void Resize(int n);
971 	void AllocVariables();
972 	bool MissingValues();		// Returns wether one of the mMissing[] is true
Self()973 	XSQLDA* Self() { return mDescrArea; }
974 
975 	RowImpl& operator=(const RowImpl& copied);
976 	RowImpl(const RowImpl& copied);
977 	RowImpl(int dialect, int size, DatabaseImpl* db, TransactionImpl* tr);
978     ~RowImpl();
979 
980 	//	(((((((( OBJECT INTERFACE ))))))))
981 
982 public:
983 	void SetNull(int);
984 	void Set(int, bool);
985 	void Set(int, const char*);				// c-strings
986 	void Set(int, const void*, int);		// byte buffers
987 	void Set(int, const std::string&);
988 	void Set(int, int16_t);
989 	void Set(int, int32_t);
990 	void Set(int, int64_t);
991 	void Set(int, float);
992 	void Set(int, double);
993 	void Set(int, const IBPP::Timestamp&);
994 	void Set(int, const IBPP::Date&);
995 	void Set(int, const IBPP::Time&);
996 	void Set(int, const IBPP::DBKey&);
997 	void Set(int, const IBPP::Blob&);
998 	void Set(int, const IBPP::Array&);
999 
1000 	bool IsNull(int);
1001 	bool Get(int, bool&);
1002 	bool Get(int, char*);  		// c-strings, len unchecked
1003 	bool Get(int, void*, int&);	// byte buffers
1004 	bool Get(int, std::string&);
1005 	bool Get(int, int16_t&);
1006 	bool Get(int, int32_t&);
1007 	bool Get(int, int64_t&);
1008 	bool Get(int, float&);
1009 	bool Get(int, double&);
1010 	bool Get(int, IBPP::Timestamp&);
1011 	bool Get(int, IBPP::Date&);
1012 	bool Get(int, IBPP::Time&);
1013 	bool Get(int, IBPP::DBKey&);
1014 	bool Get(int, IBPP::Blob&);
1015 	bool Get(int, IBPP::Array&);
1016 
1017 	bool IsNull(const std::string&);
1018 	bool Get(const std::string&, bool&);
1019 	bool Get(const std::string&, char*);	// c-strings, len unchecked
1020 	bool Get(const std::string&, void*, int&);	// byte buffers
1021 	bool Get(const std::string&, std::string&);
1022 	bool Get(const std::string&, int16_t&);
1023 	bool Get(const std::string&, int32_t&);
1024 	bool Get(const std::string&, int64_t&);
1025 	bool Get(const std::string&, float&);
1026 	bool Get(const std::string&, double&);
1027 	bool Get(const std::string&, IBPP::Timestamp&);
1028 	bool Get(const std::string&, IBPP::Date&);
1029 	bool Get(const std::string&, IBPP::Time&);
1030 	bool Get(const std::string&, IBPP::DBKey&);
1031 	bool Get(const std::string&, IBPP::Blob&);
1032 	bool Get(const std::string&, IBPP::Array&);
1033 
1034 	int ColumnNum(const std::string&);
1035 	const char* ColumnName(int);
1036 	const char* ColumnAlias(int);
1037 	const char* ColumnTable(int);
1038 	IBPP::SDT ColumnType(int);
1039 	int ColumnSubtype(int);
1040 	int ColumnSize(int);
1041 	int ColumnScale(int);
1042 	int Columns();
1043 
1044 	bool ColumnUpdated(int);
1045 	bool Updated();
1046 
1047 	IBPP::Database DatabasePtr() const;
1048 	IBPP::Transaction TransactionPtr() const;
1049 
1050 	IBPP::IRow* Clone();
1051 	IBPP::IRow* AddRef();
1052 	void Release();
1053 };
1054 
1055 class StatementImpl : public IBPP::IStatement
1056 {
1057 	//	(((((((( OBJECT INTERNALS ))))))))
1058 
1059 private:
1060 	friend class TransactionImpl;
1061 
1062 	int mRefCount;				// Reference counter
1063 	isc_stmt_handle mHandle;	// Statement Handle
1064 
1065 	DatabaseImpl* mDatabase;		// Attached database
1066 	TransactionImpl* mTransaction;	// Attached transaction
1067 	RowImpl* mInRow;
1068 	//bool* mInMissing;			// Quels param�tres n'ont pas �t� sp�cifi�s
1069 	RowImpl* mOutRow;
1070 	bool mResultSetAvailable;	// Executed and result set is available
1071 	bool mCursorOpened;			// dsql_set_cursor_name was called
1072 	IBPP::STT mType;			// Type de requ�te
1073 	std::string mSql;			// Last SQL statement prepared or executed
1074 
1075 	// Internal Methods
1076 	void CursorFree();
1077 
1078 public:
1079 	// Properties and Attributes Access Methods
GetHandle()1080 	isc_stmt_handle GetHandle() { return mHandle; }
1081 
1082 	void AttachDatabaseImpl(DatabaseImpl*);
1083 	void DetachDatabaseImpl();
1084 	void AttachTransactionImpl(TransactionImpl*);
1085 	void DetachTransactionImpl();
1086 
1087 	StatementImpl(DatabaseImpl*, TransactionImpl*, const std::string&);
1088     ~StatementImpl();
1089 
1090 	//	(((((((( OBJECT INTERFACE ))))))))
1091 
1092 public:
1093 	void Prepare(const std::string& sql);
1094 	void Execute(const std::string& sql);
Execute()1095 	inline void Execute()	{ Execute(std::string()); }
1096 	void ExecuteImmediate(const std::string&);
1097 	void CursorExecute(const std::string& cursor, const std::string& sql);
CursorExecute(const std::string & cursor)1098 	inline void CursorExecute(const std::string& cursor)	{ CursorExecute(cursor, std::string()); }
1099 	bool Fetch();
1100 	bool Fetch(IBPP::Row&);
1101 	int AffectedRows();
1102 	void Close();	// Free resources, attachments maintained
Sql()1103 	std::string& Sql() { return mSql; }
Type()1104 	IBPP::STT Type() { return mType; }
1105 
1106 	void SetNull(int);
1107 	void Set(int, bool);
1108 	void Set(int, const char*);				// c-strings
1109 	void Set(int, const void*, int);		// byte buffers
1110 	void Set(int, const std::string&);
1111 	void Set(int, int16_t);
1112 	void Set(int, int32_t);
1113 	void Set(int, int64_t);
1114 	void Set(int, float);
1115 	void Set(int, double);
1116 	void Set(int, const IBPP::Timestamp&);
1117 	void Set(int, const IBPP::Date&);
1118 	void Set(int, const IBPP::Time&);
1119 	void Set(int, const IBPP::DBKey&);
1120 	void Set(int, const IBPP::Blob&);
1121 	void Set(int, const IBPP::Array&);
1122 
1123 	bool IsNull(int);
1124 	bool Get(int, bool*);
1125 	bool Get(int, bool&);
1126 	bool Get(int, char*);				// c-strings, len unchecked
1127 	bool Get(int, void*, int&);			// byte buffers
1128 	bool Get(int, std::string&);
1129 	bool Get(int, int16_t*);
1130 	bool Get(int, int16_t&);
1131 	bool Get(int, int32_t*);
1132 	bool Get(int, int32_t&);
1133 	bool Get(int, int64_t*);
1134 	bool Get(int, int64_t&);
1135 	bool Get(int, float*);
1136 	bool Get(int, float&);
1137 	bool Get(int, double*);
1138 	bool Get(int, double&);
1139 	bool Get(int, IBPP::Timestamp&);
1140 	bool Get(int, IBPP::Date&);
1141 	bool Get(int, IBPP::Time&);
1142 	bool Get(int, IBPP::DBKey&);
1143 	bool Get(int, IBPP::Blob&);
1144 	bool Get(int, IBPP::Array&);
1145 
1146 	bool IsNull(const std::string&);
1147 	bool Get(const std::string&, bool*);
1148 	bool Get(const std::string&, bool&);
1149 	bool Get(const std::string&, char*);		// c-strings, len unchecked
1150 	bool Get(const std::string&, void*, int&);	// byte buffers
1151 	bool Get(const std::string&, std::string&);
1152 	bool Get(const std::string&, int16_t*);
1153 	bool Get(const std::string&, int16_t&);
1154 	bool Get(const std::string&, int32_t*);
1155 	bool Get(const std::string&, int32_t&);
1156 	bool Get(const std::string&, int64_t*);
1157 	bool Get(const std::string&, int64_t&);
1158 	bool Get(const std::string&, float*);
1159 	bool Get(const std::string&, float&);
1160 	bool Get(const std::string&, double*);
1161 	bool Get(const std::string&, double&);
1162 	bool Get(const std::string&, IBPP::Timestamp&);
1163 	bool Get(const std::string&, IBPP::Date&);
1164 	bool Get(const std::string&, IBPP::Time&);
1165 	bool Get(const std::string&, IBPP::DBKey&);
1166 	bool Get(const std::string&, IBPP::Blob&);
1167 	bool Get(const std::string&, IBPP::Array&);
1168 
1169 	int ColumnNum(const std::string&);
1170     int ColumnNumAlias(const std::string&);
1171 	const char* ColumnName(int);
1172 	const char* ColumnAlias(int);
1173 	const char* ColumnTable(int);
1174 	IBPP::SDT ColumnType(int);
1175 	int ColumnSubtype(int);
1176 	int ColumnSize(int);
1177 	int ColumnScale(int);
1178 	int Columns();
1179 
1180 	IBPP::SDT ParameterType(int);
1181 	int ParameterSubtype(int);
1182 	int ParameterSize(int);
1183 	int ParameterScale(int);
1184 	int Parameters();
1185 
1186 	void Plan(std::string&);
1187 
1188 	IBPP::Database DatabasePtr() const;
1189 	IBPP::Transaction TransactionPtr() const;
1190 
1191 	IBPP::IStatement* AddRef();
1192 	void Release();
1193 };
1194 
1195 class BlobImpl : public IBPP::IBlob
1196 {
1197 	//	(((((((( OBJECT INTERNALS ))))))))
1198 
1199 private:
1200 	friend class RowImpl;
1201 
1202 	int mRefCount;
1203 	bool					mIdAssigned;
1204 	ISC_QUAD				mId;
1205 	isc_blob_handle			mHandle;
1206 	bool					mWriteMode;
1207 	DatabaseImpl*  			mDatabase;		// Belongs to this database
1208 	TransactionImpl*		mTransaction;	// Belongs to this transaction
1209 
1210 	void Init();
1211 	void SetId(ISC_QUAD*);
1212 	void GetId(ISC_QUAD*);
1213 
1214 public:
1215 	void AttachDatabaseImpl(DatabaseImpl*);
1216 	void DetachDatabaseImpl();
1217 	void AttachTransactionImpl(TransactionImpl*);
1218 	void DetachTransactionImpl();
1219 
1220 	BlobImpl(const BlobImpl&);
1221 	BlobImpl(DatabaseImpl*, TransactionImpl* = 0);
1222 	~BlobImpl();
1223 
1224 	//	(((((((( OBJECT INTERFACE ))))))))
1225 
1226 public:
1227 	void Create();
1228 	void Open();
1229 	void Close();
1230 	void Cancel();
1231 	int Read(void*, int size);
1232 	void Write(const void*, int size);
1233 	void Info(int* Size, int* Largest, int* Segments);
1234 
1235 	void Save(const std::string& data);
1236 	void Load(std::string& data);
1237 
1238 	IBPP::Database DatabasePtr() const;
1239 	IBPP::Transaction TransactionPtr() const;
1240 
1241 	IBPP::IBlob* AddRef();
1242 	void Release();
1243 };
1244 
1245 class ArrayImpl : public IBPP::IArray
1246 {
1247 	//	(((((((( OBJECT INTERNALS ))))))))
1248 
1249 private:
1250 	friend class RowImpl;
1251 
1252 	int					mRefCount;		// Reference counter
1253 	bool				mIdAssigned;
1254 	ISC_QUAD			mId;
1255 	bool				mDescribed;
1256 	ISC_ARRAY_DESC		mDesc;
1257 	DatabaseImpl*  		mDatabase;		// Database attach�e
1258 	TransactionImpl*	mTransaction;	// Transaction attach�e
1259 	void*				mBuffer;		// Buffer for native data
1260 	int					mBufferSize;	// Size of this buffer in bytes
1261 	int					mElemCount;		// Count of elements in this array
1262 	int					mElemSize;		// Size of an element in the buffer
1263 
1264 	void Init();
1265 	void SetId(ISC_QUAD*);
1266 	void GetId(ISC_QUAD*);
1267 	void ResetId();
1268 	void AllocArrayBuffer();
1269 
1270 public:
1271 	void AttachDatabaseImpl(DatabaseImpl*);
1272 	void DetachDatabaseImpl();
1273 	void AttachTransactionImpl(TransactionImpl*);
1274 	void DetachTransactionImpl();
1275 
1276 	ArrayImpl(const ArrayImpl&);
1277 	ArrayImpl(DatabaseImpl*, TransactionImpl* = 0);
1278 	~ArrayImpl();
1279 
1280 	//	(((((((( OBJECT INTERFACE ))))))))
1281 
1282 public:
1283 	void Describe(const std::string& table, const std::string& column);
1284 	void ReadTo(IBPP::ADT, void*, int);
1285 	void WriteFrom(IBPP::ADT, const void*, int);
1286 	IBPP::SDT ElementType();
1287 	int ElementSize();
1288 	int ElementScale();
1289 	int Dimensions();
1290 	void Bounds(int dim, int* low, int* high);
1291 	void SetBounds(int dim, int low, int high);
1292 
1293 	IBPP::Database DatabasePtr() const;
1294 	IBPP::Transaction TransactionPtr() const;
1295 
1296 	IBPP::IArray* AddRef();
1297 	void Release();
1298 };
1299 
1300 //
1301 //	EventBufferIterator: used in EventsImpl implementation.
1302 //
1303 
1304 template<class It>
1305 struct EventBufferIterator
1306 {
1307 	It mIt;
1308 
1309 public:
1310 	EventBufferIterator& operator++()
1311 		{ mIt += 1 + static_cast<int>(*mIt) + 4; return *this; }
1312 
1313 	bool operator == (const EventBufferIterator& i) const { return i.mIt == mIt; }
1314 	bool operator != (const EventBufferIterator& i) const { return i.mIt != mIt; }
1315 
1316 #ifdef __BCPLUSPLUS__
1317 #pragma warn -8027
1318 #endif
get_nameEventBufferIterator1319 	std::string get_name() const
1320 	{
1321 		return std::string(mIt + 1, mIt + 1 + static_cast<int32_t>(*mIt));
1322 	}
1323 #ifdef __BCPLUSPLUS__
1324 #pragma warn .8027
1325 #endif
1326 
get_countEventBufferIterator1327 	uint32_t get_count() const
1328 	{
1329 		return (*gds.Call()->m_vax_integer)
1330 			(const_cast<char*>(&*(mIt + 1 + static_cast<int>(*mIt))), 4);
1331 	}
1332 
1333 	// Those container like begin() and end() allow access to the underlying type
beginEventBufferIterator1334 	It begin()	{ return mIt; }
endEventBufferIterator1335 	It end()	{ return mIt + 1 + static_cast<int>(*mIt) + 4; }
1336 
EventBufferIteratorEventBufferIterator1337 	EventBufferIterator() {}
EventBufferIteratorEventBufferIterator1338 	EventBufferIterator(It it) : mIt(it) {}
1339 };
1340 
1341 class EventsImpl : public IBPP::IEvents
1342 {
1343 	static const size_t MAXEVENTNAMELEN;
1344 	static void EventHandler(const char*, short, const char*);
1345 
1346 	typedef std::vector<IBPP::EventInterface*> ObjRefs;
1347 	ObjRefs mObjectReferences;
1348 
1349 	typedef std::vector<char> Buffer;
1350 	Buffer mEventBuffer;
1351 	Buffer mResultsBuffer;
1352 
1353 	int mRefCount;		// Reference counter
1354 
1355 	DatabaseImpl* mDatabase;
1356 	ISC_LONG mId;			// Firebird internal Id of these events
1357 	bool mQueued;			// Has isc_que_events() been called?
1358 	bool mTrapped;			// EventHandled() was called since last que_events()
1359 
1360 	void FireActions();
1361 	void Queue();
1362 	void Cancel();
1363 
1364 	EventsImpl& operator=(const EventsImpl&);
1365 	EventsImpl(const EventsImpl&);
1366 
1367 public:
1368 	void AttachDatabaseImpl(DatabaseImpl*);
1369 	void DetachDatabaseImpl();
1370 
1371 	EventsImpl(DatabaseImpl* dbi);
1372 	~EventsImpl();
1373 
1374 	//	(((((((( OBJECT INTERFACE ))))))))
1375 
1376 public:
1377 	void Add(const std::string&, IBPP::EventInterface*);
1378 	void Drop(const std::string&);
1379 	void List(std::vector<std::string>&);
1380 	void Clear();				// Drop all events
1381 	void Dispatch();			// Dispatch NON async events
1382 
1383 	IBPP::Database DatabasePtr() const;
1384 
1385 	IBPP::IEvents* AddRef();
1386 	void Release();
1387 };
1388 
1389 void encodeDate(ISC_DATE& isc_dt, const IBPP::Date& dt);
1390 void decodeDate(IBPP::Date& dt, const ISC_DATE& isc_dt);
1391 
1392 void encodeTime(ISC_TIME& isc_tm, const IBPP::Time& tm);
1393 void decodeTime(IBPP::Time& tm, const ISC_TIME& isc_tm);
1394 
1395 void encodeTimestamp(ISC_TIMESTAMP& isc_ts, const IBPP::Timestamp& ts);
1396 void decodeTimestamp(IBPP::Timestamp& ts, const ISC_TIMESTAMP& isc_ts);
1397 
1398 struct consts	// See _ibpp.cpp for initializations of these constants
1399 {
1400 	static const double dscales[19];
1401 	static const int Dec31_1899;
1402 	static const int16_t min16;
1403 	static const int16_t max16;
1404 	static const int32_t min32;
1405 	static const int32_t max32;
1406 };
1407 
1408 }	// namespace ibpp_internal
1409 
1410 #endif // __INTERNAL_IBPP_H__
1411 
1412 //
1413 //	Eof
1414 //
1415