1 #ifndef DBAPI_DRIVER___EXCEPTION__HPP
2 #define DBAPI_DRIVER___EXCEPTION__HPP
3
4 /* $Id: exception.hpp 619521 2020-11-05 19:23:08Z grichenk $
5 * ===========================================================================
6 *
7 * PUBLIC DOMAIN NOTICE
8 * National Center for Biotechnology Information
9 *
10 * This software/database is a "United States Government Work" under the
11 * terms of the United States Copyright Act. It was written as part of
12 * the author's official duties as a United States Government employee and
13 * thus cannot be copyrighted. This software/database is freely available
14 * to the public for use. The National Library of Medicine and the U.S.
15 * Government have not placed any restriction on its use or reproduction.
16 *
17 * Although all reasonable efforts have been taken to ensure the accuracy
18 * and reliability of the software and data, the NLM and the U.S.
19 * Government do not and cannot warrant the performance or results that
20 * may be obtained by using this software or data. The NLM and the U.S.
21 * Government disclaim all warranties, express or implied, including
22 * warranties of performance, merchantability or fitness for any particular
23 * purpose.
24 *
25 * Please cite the author in any work or product based on this material.
26 *
27 * ===========================================================================
28 *
29 * Author: Vladimir Soussov, Denis Vakatov
30 *
31 * File Description: Exceptions
32 *
33 */
34
35 #include <corelib/ncbistd.hpp>
36 #include <corelib/ncbiobj.hpp>
37 #include <corelib/ncbithr.hpp>
38 #include <corelib/ncbimtx.hpp>
39
40 #include <deque>
41
42 /** @addtogroup DbExceptions
43 *
44 * @{
45 */
46
47
48 BEGIN_NCBI_SCOPE
49
50 class CDB_Object;
51 class CDBConnParams;
52 class CDBParams;
53
54 BEGIN_SCOPE(impl)
55 class CConnection;
56 class CDBHandlerStack;
57 END_SCOPE(impl)
58
59 ////////////////////////////////////////////////////////////////////////////////
60 /// Helper macro for default database exception implementation.
61 #define NCBI_DATABASE_EXCEPTION_DEFAULT_IMPLEMENTATION(exception_class, base_class, db_err_code) \
62 { \
63 this->x_InitCDB(db_err_code); \
64 } \
65 exception_class(const exception_class& other) \
66 : base_class(other) \
67 { \
68 x_Assign(other); \
69 } \
70 public: \
71 virtual ~exception_class(void) throw() {} \
72 const char* GetType(void) const override {return #exception_class;} \
73 typedef int TErrCode; \
74 TErrCode GetErrCode(void) const \
75 { \
76 return typeid(*this) == typeid(exception_class) ? \
77 (TErrCode)x_GetErrCode() : (TErrCode)CException::eInvalid; \
78 } \
79 virtual CDB_Exception* Clone(void) const override \
80 { \
81 return new exception_class(*this); \
82 } \
83 NCBI_EXCEPTION_DEFAULT_THROW(exception_class) \
84 protected: \
85 exception_class(void) {} \
86 virtual const CException* x_Clone(void) const override \
87 { \
88 return new exception_class(*this); \
89 } \
90 private: \
91 /* for the sake of semicolon at the end of macro...*/ \
92 static void xx_unused_##exception_class(void)
93
94
95 ////////////////////////////////////////////////////////////////////////////////
96 // DEPRECATED, Will be removed soon.
97 enum EDB_Severity {
98 eDB_Info,
99 eDB_Warning,
100 eDB_Error,
101 eDB_Fatal,
102 eDB_Unknown
103 };
104
105 ////////////////////////////////////////////////////////////////////////////////
106 ///
107 /// CDB_Exception --
108 ///
109 /// Define database exception. CDB_Exception inherits its basic
110 /// functionality from CException and defines additional error codes for
111 /// databases.
112
113
114 ////////////////////////////////////////////////////////////////////////////////
115 // class NCBI_DBAPIDRIVER_EXPORT CDB_Exception : public std::exception
116 class NCBI_DBAPIDRIVER_EXPORT CDB_Exception :
117 EXCEPTION_VIRTUAL_BASE public CException
118 {
119 friend class CDB_MultiEx;
120
121 public:
122 /// Error types that can be generated.
123 enum EErrCode {
124 eDS,
125 eRPC,
126 eSQL,
127 eDeadlock,
128 eTimeout,
129 eClient,
130 eMulti,
131 eTruncate
132 };
133 typedef EErrCode EType;
134
135 struct SParam {
136 string name;
137 CDB_Object* value;
138 };
139 struct NCBI_DBAPIDRIVER_EXPORT SParams : public CObject {
140 ~SParams(void);
141
142 typedef vector<SParam> TParams;
143 TParams params;
144 };
145
146 struct NCBI_DBAPIDRIVER_EXPORT SContext : public CObject {
SContextCDB_Exception::SContext147 SContext() { }
148 SContext(const CDBConnParams& params);
149
150 void UpdateFrom(const SContext& ctx);
151
152 string server_name;
153 string username;
154 string database_name;
155 string extra_msg;
156 };
157
158 struct NCBI_DBAPIDRIVER_EXPORT SMessageInContext {
SMessageInContextCDB_Exception::SMessageInContext159 SMessageInContext(const string& msg, const SContext& ctx)
160 : message(msg), context(&ctx)
161 { }
SMessageInContextCDB_Exception::SMessageInContext162 SMessageInContext(const string& msg = kEmptyStr)
163 : message(msg)
164 { }
SMessageInContextCDB_Exception::SMessageInContext165 SMessageInContext(const char* msg)
166 : message(msg)
167 { }
168
169 SMessageInContext operator+(const SContext& ctx) const;
170
171 string message;
172 CConstRef<SContext> context;
173
174 private:
175 friend class CDB_Exception;
176 friend class CSDB_Exception;
operator const string&CDB_Exception::SMessageInContext177 operator const string&(void) const { return message; }
178 };
179
180 // access
181 // DEPRECATED, Will be removed soon.
182 NCBI_DEPRECATED
183 EDB_Severity Severity(void) const;
GetDBErrCode(void) const184 int GetDBErrCode(void) const { return m_DBErrCode; }
185
186 const char* SeverityString(void) const;
187 // DEPRECATED, Will be removed soon.
188 NCBI_DEPRECATED
189 static const char* SeverityString(EDB_Severity sev);
190 virtual const char* GetErrCodeString(void) const override;
191
192 public:
193 // Duplicate methods. We need them to support the old interface.
194
195 EType Type(void) const;
196 // text representation of the exception type and severity
TypeString() const197 virtual const char* TypeString() const { return GetType(); }
ErrCode(void) const198 int ErrCode(void) const { return GetDBErrCode(); }
Message(void) const199 const string& Message(void) const { return GetMsg(); }
OriginatedFrom() const200 const string& OriginatedFrom() const { return GetModule(); }
201
SetServerName(const string & sn)202 void SetServerName(const string& sn) { x_SetContext().server_name = sn; }
GetServerName(void) const203 const string& GetServerName(void) const { return m_Context->server_name; }
204
SetUserName(const string & name)205 void SetUserName(const string& name) { x_SetContext().username = name; }
GetUserName(void) const206 const string& GetUserName(void) const { return m_Context->username; }
207
SetDatabaseName(const string & d)208 void SetDatabaseName(const string& d) { x_SetContext().database_name = d; }
GetDatabaseName(void) const209 const string& GetDatabaseName(void) const
210 { return m_Context->database_name; }
211
GetContext(void) const212 const SContext& GetContext(void) const { return *m_Context; }
ApplyContext(const SContext & ctx)213 void ApplyContext(const SContext& ctx)
214 { x_SetContext().UpdateFrom(ctx); }
215 void SetFromConnection(const impl::CConnection& connection);
216
SetExtraMsg(const string & msg)217 void SetExtraMsg(const string& msg) { x_SetContext().extra_msg = msg; }
GetExtraMsg(void) const218 const string& GetExtraMsg(void) const { return m_Context->extra_msg; }
219
220 void SetParams(const CDBParams* params);
SetParams(const CDBParams & params)221 void SetParams(const CDBParams& params) { SetParams(¶ms); }
GetParams(void) const222 CConstRef<SParams> GetParams(void) const { return m_Params; }
223
SetRowsInBatch(unsigned int n)224 void SetRowsInBatch(unsigned int n) { m_RowsInBatch = n; }
GetRowsInBatch(void) const225 unsigned int GetRowsInBatch(void) const { return m_RowsInBatch; }
226
227
228 /// WARNING !!! Sybase severity value can be provided by Sybase/FreeTDS
229 /// ctlib drivers only.
SetSybaseSeverity(int severity)230 void SetSybaseSeverity(int severity) { m_SybaseSeverity = severity;}
GetSybaseSeverity(void) const231 int GetSybaseSeverity(void) const { return m_SybaseSeverity; }
232
233 public:
234 virtual void ReportExtra(ostream& out) const override;
235 virtual CDB_Exception* Clone(void) const;
236
237 public:
238 // Warning: exception constructor must be "public" because MSVC 7.1 won't
239 // catch parent exceptions other way.
240 CDB_Exception(const CDiagCompileInfo& info,
241 const CException* prev_exception,
242 EErrCode err_code,
243 const SMessageInContext& message,
244 EDiagSev severity,
245 int db_err_code)
246 : CException(info,
247 prev_exception,
248 (CException::EErrCode)err_code,
249 message.message,
250 severity )
251 , m_DBErrCode(db_err_code)
252 , m_Context(message.context)
253 , m_SybaseSeverity(0)
254 , m_RowsInBatch(0)
255 NCBI_EXCEPTION_DEFAULT_IMPLEMENTATION(CDB_Exception, CException);
256
257 public:
258 template<class E>
MakeException(const CDiagCompileInfo & info,const SMessageInContext & message,EDiagSev severity,int db_err_code)259 NCBI_NORETURN static void MakeException(const CDiagCompileInfo& info,
260 const SMessageInContext& message,
261 EDiagSev severity,
262 int db_err_code)
263 {
264 E ex(info, nullptr, message, severity, db_err_code);
265 if (severity == eDiag_Error || severity == eDiag_Fatal)
266 ex.SetRetriable(eRetriable_No);
267 else
268 ex.SetRetriable(eRetriable_Unknown);
269 throw ex;
270 }
271
272 protected:
273 int m_DBErrCode;
274
275 protected:
276 void x_StartOfWhat(ostream& out) const;
277 void x_EndOfWhat (ostream& out) const;
278 void x_Init(const CDiagCompileInfo& info, const string& message,
279 const CException* prev_exception, EDiagSev severity) override;
280 virtual void x_Assign(const CException& src) override;
x_InitCDB(int db_error_code)281 void x_InitCDB(int db_error_code) { m_DBErrCode = db_error_code; }
282 SContext& x_SetContext(void);
283
284 private:
285 CConstRef<SContext> m_Context;
286 int m_SybaseSeverity;
287 CRef<SParams> m_Params;
288 unsigned int m_RowsInBatch;
289 };
290
291 inline
operator +(const string & msg,const CDB_Exception::SContext & ctx)292 CDB_Exception::SMessageInContext operator+(const string& msg,
293 const CDB_Exception::SContext& ctx)
294 {
295 return CDB_Exception::SMessageInContext(msg, ctx);
296 }
297
298 inline
operator +(const char * msg,const CDB_Exception::SContext & ctx)299 CDB_Exception::SMessageInContext operator+(const char* msg,
300 const CDB_Exception::SContext& ctx)
301 {
302 return CDB_Exception::SMessageInContext(msg, ctx);
303 }
304
305 NCBI_DBAPIDRIVER_EXPORT ostream& operator<<(ostream &os, const CDB_Exception::SContext& ctx);
306 NCBI_DBAPIDRIVER_EXPORT ostream& operator<<(ostream &os, const CDB_Exception::SMessageInContext& msg);
307
308
309 ////////////////////////////////////////////////////////////////////////////////
310 class NCBI_DBAPIDRIVER_EXPORT CDB_DSEx : public CDB_Exception
311 {
312 public:
313 CDB_DSEx(const CDiagCompileInfo& info,
314 const CException* prev_exception,
315 const SMessageInContext& message,
316 EDiagSev severity,
317 int db_err_code)
318 : CDB_Exception(info, prev_exception,
319 CDB_Exception::eDS,
320 message, severity,
321 db_err_code)
322 NCBI_DATABASE_EXCEPTION_DEFAULT_IMPLEMENTATION(CDB_DSEx,
323 CDB_Exception,
324 db_err_code);
325
326 };
327
328
329 ////////////////////////////////////////////////////////////////////////////////
330 class NCBI_DBAPIDRIVER_EXPORT CDB_RPCEx : public CDB_Exception
331 {
332 public:
333 CDB_RPCEx(const CDiagCompileInfo& info,
334 const CException* prev_exception,
335 const SMessageInContext& message,
336 EDiagSev severity,
337 int db_err_code,
338 const string& proc_name,
339 int proc_line)
340 : CDB_Exception(info,
341 prev_exception,
342 CDB_Exception::eRPC,
343 message,
344 severity,
345 db_err_code)
346 , m_ProcName(proc_name.empty() ? "Unknown" : proc_name)
347 , m_ProcLine(proc_line)
348 NCBI_DATABASE_EXCEPTION_DEFAULT_IMPLEMENTATION(CDB_RPCEx,
349 CDB_Exception,
350 db_err_code);
351
352 public:
ProcName() const353 const string& ProcName() const { return m_ProcName; }
ProcLine() const354 int ProcLine() const { return m_ProcLine; }
355
356 virtual void ReportExtra(ostream& out) const override;
357
358 protected:
359 virtual void x_Assign(const CException& src) override;
360
361 private:
362 string m_ProcName;
363 int m_ProcLine;
364 };
365
366
367 ////////////////////////////////////////////////////////////////////////////////
368 class NCBI_DBAPIDRIVER_EXPORT CDB_SQLEx : public CDB_Exception
369 {
370 public:
371 CDB_SQLEx(const CDiagCompileInfo& info,
372 const CException* prev_exception,
373 const SMessageInContext& message,
374 EDiagSev severity,
375 int db_err_code,
376 const string& sql_state,
377 int batch_line)
378 : CDB_Exception(info,
379 prev_exception,
380 CDB_Exception::eSQL,
381 message,
382 severity,
383 db_err_code)
384 , m_SqlState(sql_state.empty() ? "Unknown" : sql_state)
385 , m_BatchLine(batch_line)
386 NCBI_DATABASE_EXCEPTION_DEFAULT_IMPLEMENTATION(CDB_SQLEx,
387 CDB_Exception,
388 db_err_code);
389
390 public:
SqlState() const391 const string& SqlState() const { return m_SqlState; }
BatchLine() const392 int BatchLine() const { return m_BatchLine; }
393
394 virtual void ReportExtra(ostream& out) const override;
395
396 protected:
397 virtual void x_Assign(const CException& src) override;
398
399 private:
400 string m_SqlState;
401 int m_BatchLine;
402 };
403
404
405 ////////////////////////////////////////////////////////////////////////////////
406 class NCBI_DBAPIDRIVER_EXPORT CDB_DeadlockEx : public CDB_Exception
407 {
408 public:
409 CDB_DeadlockEx(const CDiagCompileInfo& info,
410 const CException* prev_exception,
411 const SMessageInContext& message)
412 : CDB_Exception(info,
413 prev_exception,
414 CDB_Exception::eDeadlock,
415 message,
416 eDiag_Error,
417 123456)
418 NCBI_DATABASE_EXCEPTION_DEFAULT_IMPLEMENTATION(CDB_DeadlockEx,
419 CDB_Exception,
420 123456);
421
422 };
423
424
425 ////////////////////////////////////////////////////////////////////////////////
426 class NCBI_DBAPIDRIVER_EXPORT CDB_TimeoutEx : public CDB_Exception
427 {
428 public:
429 CDB_TimeoutEx(const CDiagCompileInfo& info,
430 const CException* prev_exception,
431 const SMessageInContext& message,
432 int db_err_code)
433 : CDB_Exception(info,
434 prev_exception,
435 CDB_Exception::eTimeout,
436 message,
437 eDiag_Error,
438 db_err_code)
439 NCBI_DATABASE_EXCEPTION_DEFAULT_IMPLEMENTATION(CDB_TimeoutEx,
440 CDB_Exception,
441 db_err_code);
442 };
443
444
445 ////////////////////////////////////////////////////////////////////////////////
446 class NCBI_DBAPIDRIVER_EXPORT CDB_ClientEx : public CDB_Exception
447 {
448 public:
CDB_ClientEx(const CDiagCompileInfo & info,const CException * prev_exception,const SMessageInContext & message,EDiagSev severity,int db_err_code,const SContext & dbg_info,const impl::CConnection & connection,const CDBParams * params)449 CDB_ClientEx(const CDiagCompileInfo& info,
450 const CException* prev_exception,
451 const SMessageInContext& message,
452 EDiagSev severity,
453 int db_err_code,
454 const SContext& dbg_info,
455 const impl::CConnection& connection,
456 const CDBParams* params)
457 : CDB_Exception(info, prev_exception, CDB_Exception::eClient,
458 message + dbg_info, severity, db_err_code)
459 {
460 SetFromConnection(connection);
461 SetParams(params);
462 }
463 CDB_ClientEx(const CDiagCompileInfo& info,
464 const CException* prev_exception,
465 const SMessageInContext& message,
466 EDiagSev severity,
467 int db_err_code)
468 : CDB_Exception(info,
469 prev_exception,
470 CDB_Exception::eClient,
471 message,
472 severity,
473 db_err_code)
474 NCBI_DATABASE_EXCEPTION_DEFAULT_IMPLEMENTATION(CDB_ClientEx,
475 CDB_Exception,
476 db_err_code);
477 };
478
479
480
481 ////////////////////////////////////////////////////////////////////////////////
482 class NCBI_DBAPIDRIVER_EXPORT CDB_TruncateEx : public CDB_Exception
483 {
484 public:
485 CDB_TruncateEx(const CDiagCompileInfo& info,
486 const CException* prev_exception,
487 const SMessageInContext& message,
488 int db_err_code)
489 : CDB_Exception(info,
490 prev_exception,
491 CDB_Exception::eTruncate,
492 message,
493 eDiag_Warning,
494 db_err_code)
495 NCBI_DATABASE_EXCEPTION_DEFAULT_IMPLEMENTATION(CDB_TruncateEx,
496 CDB_Exception,
497 db_err_code);
498 };
499
500
501
502 ////////////////////////////////////////////////////////////////////////////////
503 class NCBI_DBAPIDRIVER_EXPORT CDB_MultiEx : public CDB_Exception
504 {
505 public:
506 // ctor/dtor
507 CDB_MultiEx(const CDiagCompileInfo& info,
508 const CException* prev_exception,
509 unsigned int capacity = 64)
510 : CDB_Exception(info,
511 prev_exception,
512 CDB_Exception::eMulti,
513 kEmptyStr,
514 eDiag_Info,
515 0)
516 , m_Bag( new CObjectFor<TExceptionStack>() )
517 , m_NofRooms( capacity )
518 NCBI_DATABASE_EXCEPTION_DEFAULT_IMPLEMENTATION(CDB_MultiEx,
519 CDB_Exception,
520 0 );
521
522 public:
523 bool Push(const CDB_Exception& ex);
524 // REsult is not owned by CDB_MultiEx
525 CDB_Exception* Pop(void);
526
NofExceptions() const527 unsigned int NofExceptions() const {
528 return static_cast<unsigned int>( m_Bag->GetData().size() );
529 }
Capacity() const530 unsigned int Capacity() const { return m_NofRooms; }
531
532 string WhatThis(void) const;
533
534 virtual void ReportExtra(ostream& out) const override;
535
536 protected:
537 void ReportErrorStack(ostream& out) const;
538 virtual void x_Assign(const CException& src) override;
539
540 private:
541 // We use "deque" instead of "stack" here we need to iterate over all
542 // recors in the container.
543 typedef deque<AutoPtr<const CDB_Exception> > TExceptionStack;
544
545 CRef<CObjectFor<TExceptionStack> > m_Bag;
546 unsigned int m_NofRooms; ///< Max number of error messages to print..
547 };
548
549
550
551
552 /////////////////////////////////////////////////////////////////////////////
553 //
554 // CDB_UserHandler:: base class for user-defined handlers
555 //
556 // Specializations of "CDB_UserHandler" -- to print error messages to:
557 //
558 // CDB_UserHandler_Default:: default destination (now: CDB_UserHandler_Diag)
559 // CDB_UserHandler_Diag:: C++ Toolkit diagnostics
560 // CDB_UserHandler_Stream:: std::ostream specified by the user
561 //
562
563
564 ////////////////////////////////////////////////////////////////////////////////
565 class NCBI_DBAPIDRIVER_EXPORT CDB_UserHandler : public CObject
566 {
567 public:
568 CDB_UserHandler(void);
569 virtual ~CDB_UserHandler(void);
570
571 public:
572 /// Exception container type
573 /// @sa HandleAll()
574 typedef deque<CDB_Exception*> TExceptions;
575 static void ClearExceptions(TExceptions& expts);
576
577 /// Handle all of the exceptions resulting from a native API call.
578 /// @param exceptions
579 /// List of exceptions
580 /// @return
581 /// TRUE if the exceptions are handled -- in this case, HandleIt() methods
582 /// will *NOT* be called.
583 /// @sa HandleIt(), CException::Throw()
584 virtual bool HandleAll(const TExceptions& exceptions);
585
586 /// Handle the exceptions resulting from a native API call, one-by-one.
587 /// @return
588 /// TRUE if "ex" is processed, FALSE if not (or if "ex" is NULL)
589 /// @sa HandleAll(), CException::Throw()
590 virtual bool HandleIt(CDB_Exception* ex) = 0;
591
592 /// Handle message resulting from a native API call.
593 /// Method MUST NOT throw any exceptions.
594 ///
595 /// @return
596 /// TRUE if message is processed and shouldn't be saved for later
597 /// appearance as CDB_Exception, FALSE otherwise (default value is FALSE)
598 virtual bool HandleMessage(int severity, int msgnum, const string& message);
599
600 // Get current global "last-resort" error handler.
601 // If not set, then the default will be "CDB_UserHandler_Default".
602 // This handler is guaranteed to be valid up to the program termination,
603 // and it will call the user-defined handler last set by SetDefault().
604 // NOTE: never pass it to SetDefault, like: "SetDefault(&GetDefault())"!
605 static CDB_UserHandler& GetDefault(void);
606
607 // Alternate the default global "last-resort" error handler.
608 // Passing NULL will mean to ignore all errors that reach it.
609 // Return previously set (or default-default if not set yet) handler.
610 // The returned handler should be delete'd by the caller; the last set
611 // handler will be delete'd automagically on the program termination.
612 static CDB_UserHandler* SetDefault(CDB_UserHandler* h);
613
614 /// Method is deprecated. Use CDB_Exception::GetExtraMsg() instead.
615 NCBI_DEPRECATED string GetExtraMsg(void) const;
616 /// Method is deprecated. Use CDB_Exception::SetExtraMsg() instead.
617 NCBI_DEPRECATED void SetExtraMsg(const string& msg) const;
618
619 protected:
620 /// Simply call HandleIt on each exception.
621 bool x_HandleAll(const TExceptions& exceptions);
622 };
623
624
625 ////////////////////////////////////////////////////////////////////////////////
626 class NCBI_DBAPIDRIVER_EXPORT CDB_UserHandler_Diag : public CDB_UserHandler
627 {
628 public:
629 CDB_UserHandler_Diag(const string& prefix = kEmptyStr);
630 virtual ~CDB_UserHandler_Diag();
631
632 // Print "*ex" to the standard C++ Toolkit diagnostics, with "prefix".
633 // Always return TRUE (i.e. always process the "ex").
634 virtual bool HandleIt(CDB_Exception* ex);
635
636 virtual bool HandleAll(const TExceptions& exceptions);
637
638 private:
639 string m_Prefix; // string to prefix each message with
640 };
641
642
643 ////////////////////////////////////////////////////////////////////////////////
644 class NCBI_DBAPIDRIVER_EXPORT CDB_UserHandler_Stream : public CDB_UserHandler
645 {
646 public:
647 CDB_UserHandler_Stream(ostream* os = 0 /*cerr*/,
648 const string& prefix = kEmptyStr,
649 bool own_os = false);
650 virtual ~CDB_UserHandler_Stream();
651
652 // Print "*ex" to the output stream "os", with "prefix" (as set by c-tor).
653 // Return TRUE (i.e. process the "ex") unless write to "os" failed.
654 virtual bool HandleIt(CDB_Exception* ex);
655
656 virtual bool HandleAll(const TExceptions& exceptions);
657
658 private:
659 mutable CFastMutex m_Mtx;
660
661 ostream* m_Output; // output stream to print messages to
662 string m_Prefix; // string to prefix each message with
663 bool m_OwnOutput; // if TRUE, then delete "m_Output" in d-tor
664 };
665
666
667 ////////////////////////////////////////////////////////////////////////////////
668 class NCBI_DBAPIDRIVER_EXPORT CDB_UserHandler_Exception :
669 public CDB_UserHandler
670 {
671 public:
672 virtual ~CDB_UserHandler_Exception(void);
673
674 virtual bool HandleIt(CDB_Exception* ex);
675 virtual bool HandleAll(const TExceptions& exceptions);
676 };
677
678
679 ////////////////////////////////////////////////////////////////////////////////
680 class NCBI_DBAPIDRIVER_EXPORT CDB_UserHandler_Deferred : public CDB_UserHandler
681 {
682 public:
683 CDB_UserHandler_Deferred(const impl::CDBHandlerStack& ultimate_handlers);
684 ~CDB_UserHandler_Deferred(void);
685
686 bool HandleIt(CDB_Exception* ex);
687 bool HandleAll(const TExceptions& exceptions);
688
689 void Flush(EDiagSev max_severity = eDiagSevMax);
690
691 private:
692 TExceptions m_SavedExceptions;
693 const impl::CDBHandlerStack& m_UltimateHandlers;
694 CFastMutex m_Mutex;
695 };
696
697
698 ////////////////////////////////////////////////////////////////////////////////
699 class NCBI_DBAPIDRIVER_EXPORT CDB_UserHandler_Exception_ODBC :
700 public CDB_UserHandler
701 {
702 public:
703 virtual ~CDB_UserHandler_Exception_ODBC(void);
704
705 virtual bool HandleIt(CDB_Exception* ex);
706 };
707
708
709 ////////////////////////////////////////////////////////////////////////////////
710 typedef CDB_UserHandler_Diag CDB_UserHandler_Default;
711
712 ////////////////////////////////////////////////////////////////////////////////
713 /// Generic macro to throw a database exception, given the exception class,
714 /// database error code and message string.
715 #define NCBI_DATABASE_THROW( exception_class, message, err_code, severity ) \
716 do { \
717 NCBI_NS_NCBI::CDB_Exception::MakeException<exception_class>( \
718 DIAG_COMPILE_INFO, (message), severity, err_code); \
719 } while(0)
720 #define NCBI_DATABASE_RETHROW( prev_exception, exception_class, message, \
721 err_code, severity ) \
722 throw exception_class( DIAG_COMPILE_INFO, \
723 &(prev_exception), (message), severity, err_code )
724
725 // Driver code typically redefines NCBI_DATABASE_(RE)THROW in terms of these.
726 #define NCBI_DATABASE_THROW_ANNOTATED(ex_class, message, err_code, severity, \
727 dbg_info, conn, params) \
728 do { \
729 ex_class ex(DIAG_COMPILE_INFO, NULL, (message), severity, err_code, \
730 dbg_info, conn, params); \
731 ex.SetRetriable(eRetriable_No); \
732 throw ex; \
733 } while (0)
734
735 #define NCBI_DATABASE_RETHROW_ANNOTATED(prev_ex, ex_class, message, err_code, \
736 severity, dbg_info, conn, params) \
737 throw ex_class(DIAG_COMPILE_INFO, &(prev_ex), (message), severity, \
738 err_code, dbg_info, conn, params)
739
740 #define DATABASE_DRIVER_ERROR( message, err_code ) \
741 NCBI_DATABASE_THROW( CDB_ClientEx, message, err_code, eDiag_Error )
742 #define DATABASE_DRIVER_ERROR_EX( prev_exception, message, err_code ) \
743 NCBI_DATABASE_RETHROW( prev_exception, CDB_ClientEx, message, err_code, \
744 eDiag_Error )
745
746 #define DATABASE_DRIVER_WARNING( message, err_code ) \
747 NCBI_DATABASE_THROW( CDB_ClientEx, message, err_code, eDiag_Warning )
748 #define DATABASE_DRIVER_WARNING_EX( prev_exception, message, err_code ) \
749 NCBI_DATABASE_RETHROW( prev_exception, CDB_ClientEx, message, err_code, \
750 eDiag_Warning )
751
752 #define DATABASE_DRIVER_FATAL( message, err_code ) \
753 NCBI_DATABASE_THROW( CDB_ClientEx, message, err_code, eDiag_Fatal )
754 #define DATABASE_DRIVER_FATAL_EX( prev_exception, message, err_code ) \
755 NCBI_DATABASE_RETHROW( prev_exception, CDB_ClientEx, message, err_code, \
756 eDiag_Fatal )
757
758 #define DATABASE_DRIVER_INFO( message, err_code ) \
759 NCBI_DATABASE_THROW( CDB_ClientEx, message, err_code, eDiag_Info )
760 #define DATABASE_DRIVER_INFO_EX( prev_exception, message, err_code ) \
761 NCBI_DATABASE_RETHROW( prev_exception, CDB_ClientEx, message, err_code, \
762 eDiag_Info )
763
764
765 #define CHECK_DRIVER_ERROR( failed, message, err_code ) \
766 if ( ( failed ) ) { DATABASE_DRIVER_ERROR( message, err_code ); }
767
768 #define CHECK_DRIVER_WARNING( failed, message, err_code ) \
769 if ( ( failed ) ) { DATABASE_DRIVER_WARNING( message, err_code ); }
770
771 #define CHECK_DRIVER_FATAL( failed, message, err_code ) \
772 if ( ( failed ) ) { DATABASE_DRIVER_FATAL( message, err_code ); }
773
774 #define CHECK_DRIVER_INFO( failed, message, err_code ) \
775 if ( ( failed ) ) { DATABASE_DRIVER_INFO( message, err_code ); }
776
777 END_NCBI_SCOPE
778
779
780 /* @} */
781
782
783 #endif /* DBAPI_DRIVER___EXCEPTION__HPP */
784