15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


C++ & DB-Library

Craig Hewitt -- chewitt@webzone.net
Wednesday, September 11, 1996

Environment: VC++ 4.0, NT 4.0

Problem :
	 I am trying to write a C++ class to handle connections to a SQL Server
using DB-Library. I am unsure about how to implement the error and message
handling routines.  On Knowledge Base article, Q151607, says to use per
process error and message handling using dbprocerrhandle and
dbprocmsghandle.  The other KB article, Q96433, says to use a global error
handler using dberrhandle and dbmsghandle.  These articles are for SQL 6.0
and 4.2.  I would like for the callback routines to call the functions in
the class that will in turn call virtual functions to handle the errors
from SQL Server.  What is the correct approach?  The class is complete with
exception of these two routines.

Craig Hewitt
chewitt@webzone.net
chew-it





Mark F. Fling -- mfling@stratacorp.com
Thursday, September 12, 1996

[Mini-digest: 2 responses]

Craig Hewitt  wrote:

>I am trying to write a C++ class to handle connections to a SQL Server
>using DB-Library. I am unsure about how to implement the error and =
message
>handling routines.=20
>...
>I would like for the callback routines to call the functions in
>the class that will in turn call virtual functions to handle the errors
>from SQL Server.  What is the correct approach?  The class is complete =
with
>exception of these two routines.

Both, actually.

I maintain a dynamic cache of available DBPROCESS handles for rapid =
use/reuse my multiple threads within my app.  My controlling SQLServer =
class performs dbinit() and dblogin() processing to create a single =
LOGINREC which is used during dbopen() to create these DBPROCESS =
handles.

Immediately after dbinit() and dblogin() calls, I issue a =
dbprocerrhandle() and dbprocmsghandle() to establish the global =
handlers, passing the LOGINREC instead of a DBPROCESS handle.  This =
assures there's error and message processing for any "leakers" during =
intiailization or destruction of the cached DBPROCESS handles.  Both =
handlers are static methods of the SQLServer class and simply issue dumb =
messages.

I've encapsulated the DBPROCESS in a C++ class SQLProcess.  It has an =
Open() method called by the SQLServer class during dynamic creation to =
perform a dbopen().  Immediately after a successful dbopen(), I issue a =
dbsetuserdata(m_dbProcess, this) to save the particular class instance =
pointer within the DBPROCESS.  I again issue a dbprocerrhandle() and =
dbprocmsghandle(), but this time using the just-created DBPROCESS handle =
and pointing to the SQLProcess::ErrorHandler() and MessageHandler() =
static callbacks.  You now have a global handler and a per-DBPROCESS =
handler. The statics handlers call ::dbgetuserdata to obtain the =
above-set class pointer to save the error number, severity, and various =
strings within the class member variables.

You'll notice I don't call any other functions, but merely stuff the =
error messages away for use later by the controlling thread.  I don't =
want to wander too far away from the exit function into my code since =
the callback is under the "context" of the DB-Library.  Making =
everything above thread-safe has been a nightmare.

Mark Fling
Strata Corporation
Santa Barbara, CA

-----From: Stephen Keeler 

Try making the error and message handling functions 'static' members of =
your C++ class.  This way, they don't get the magic 'this' pointer in =
the parameter list, and can be invoked as callback functions.

Regards,
Stephen Keeler
DeLab Enterprise Solutions Inc.





| Вернуться в корень Архива |