]> git.saurik.com Git - wxWidgets.git/blame - docs/latex/wx/tdb.tex
tried to make wxCloseEvent docs more clear too
[wxWidgets.git] / docs / latex / wx / tdb.tex
CommitLineData
a660d684
KB
1\section{Database classes overview}\label{odbcoverview}
2
b25ba5b7 3\normalboxd{The more sophisticated wxODBC classes (wxDb/wxDbTable) are the
2564094b
JS
4recommended classes for doing database/ODBC work with wxWindows. These new
5classes replace the wxWindows v1.6x classes wxDatabase. Documentation for the
b25ba5b7
GT
6old wxDatabase class and its associated classes is still
7included in the class documentation and in this overview section, but support
8for these old classes has been phased out, and all future development work
9is being done solely on the new wxDb/wxDbTable classes.}
10
11\subsection{Different ODBC Class Libraries in wxWindows}
12
2564094b
JS
13Following is a detailed overview of how to use the wxWindows ODBC classes - \helpref{wxDb}{wxdb}
14and \helpref{wxDbTable}{wxdbtable} and their associated functions. These are
b25ba5b7 15the ODBC classes donated by Remstar International, and are collectively
2564094b 16referred to herein as the wxODBC classes. Since their initial inclusion with
5f6d6405 17wxWindows v2.x, they have become the recommended wxWindows classes for database
b25ba5b7
GT
18access.
19
20An older version of some classes ported over from wxWindows v1.68 still exist
21(see \helpref{wxDatabase}{wxdatabase} in odbc.cpp), but are now deprecated in favor of the more
2564094b 22robust and comprehensive wxDb/wxDbTable classes. All current and future
b25ba5b7 23feature development, as well as active debugging, are only being done on
2564094b
JS
24the wxODBC classes. Documentation for the older classes is still provided
25in this manual. The \helpref{wxDatabase overview}{wxdatabaseoverview} of the
b25ba5b7
GT
26older classes follows the overview of the new classes.
27
28\subsection{wxDb/wxDbTable wxODBC Overview}\label{wxodbcoverview}
29
30Classes: \helpref{wxDb}{wxdb}, \helpref{wxDbTable}{wxdbtable}
31
2564094b 32The wxODBC classes were designed for database independence. Although SQL and
b25ba5b7
GT
33ODBC both have standards which define the minimum requirements they must
34support to be in compliance with specifications, different database vendors
2564094b 35may implement things slightly differently. One example of this is that Oracle
b25ba5b7 36requires all user names for the datasources to be supplied in uppercase
2564094b 37characters. In situations like this, the wxODBC classes have been written
b25ba5b7 38to make this transparent to the programmer when using functions that require
2564094b 39database-specific syntax.
b25ba5b7
GT
40
41Currently several major databases, along with other widely used databases,
2564094b 42have been tested and supported through the wxODBC classes. The list of
b25ba5b7
GT
43supported databases is certain to grow as more users start implementing
44software with these classes, but at the time of the writing of this document,
45users have successfully used the classes with the following datasources:
46
47\begin{itemize}\itemsep=0pt
48\item Oracle (v7, v8, v8i)
49\item Sybase (ASA and ASE)
50\item MS SQL Server (v7 - minimal testing)
51\item MS Access (97 and 2000)
52\item MySQL
53\item DBase (IV, V)**
54\item PostgreSQL
55\item INFORMIX
56\item VIRTUOSO
57\item DB2
509cd921
VZ
58\item Interbase
59\item Pervasive SQL
b25ba5b7
GT
60\end{itemize}
61
62An up-to-date list can be obtained by looking in the comments of the function
63\helpref{wxDb::Dbms}{wxdbdbms} in db.cpp, or in the enumerated type
64\helpref{wxDBMS}{wxdbenumeratedtypes} in db.h.
65
66**dBase is not truly an ODBC datasource, but there are drivers which can
2564094b 67emulate much of the functionality of an ODBC connection to a dBase table.
b25ba5b7
GT
68See the \helpref{wxODBC Known Issues}{wxodbcknownissues} section of this
69overview for details.
70
71
72\subsection{wxODBC Where To Start}\label{wxodbcwheretostart}
73
74First, if you are not familiar with SQL and ODBC, go to your local bookstore
2564094b 75and pick up a good book on each. This documentation is not meant to teach
b25ba5b7
GT
76you many details about SQL or ODBC, though you may learn some just from
77immersion in the subject.
78
79If you have worked with non-SQL/ODBC datasources before, there are some
2564094b 80things you will need to un-learn. First some terminology as these phrases will
b25ba5b7
GT
81be used heavily in this section of the manual.
82
83\begin{twocollist}\itemsep=0pt
84\twocolitem{Datasource}{(usually a database) that contains the data that will be
85accessed by the wxODBC classes.}
86\twocolitem{Data table}{The section of the datasource that contains the rows and
87columns of data.}
88\twocolitem{ODBC driver}{The middle-ware software that interprets the ODBC
89commands sent by your application and converts them to the SQL format expected
90by the target datasource.}
91\twocolitem{Datasource connection}{An open pipe between your application and
2564094b 92the ODBC driver which in turn has a connection to the target datasource.
b25ba5b7 93Datasource connections can have a virtually unlimited number of wxDbTable
2564094b 94instances using the same connect (dependent on the ODBC driver). A separate
b25ba5b7
GT
95connection is not needed for each table (the exception is for isolating
96commits/rollbacks on different tables from affecting more than the desired
2564094b 97table. See the class documentation on
b25ba5b7 98\helpref{wxDb::CommitTrans}{wxdbcommittrans} and
2564094b 99\helpref{wxDb::RollbackTrans}{wxdbrollbacktrans}.)}
b25ba5b7
GT
100\twocolitem{Rows}{Similar to records in old relational databases, a row is a
101collection of one instance of each column of the data table that are all
102associated with each other.}
103\twocolitem{Columns}{Individual fields associated with each row of a data
104table.}
105\twocolitem{Query}{Request from the client to the datasource asking for
2564094b 106the data that matches the requirements specified in the users request. When
b25ba5b7
GT
107a query is performed, the datasource performs the lookup of the rows with
108satisfy the query, and creates a result set.}
109\twocolitem{Result set}{The data which matches the requirements specified
2564094b 110in a query sent to the datasource. Dependent on drivers, a result set
b25ba5b7
GT
111typically remains at the datasource (no data is transmitted to the ODBC driver)
112until the client actually instructs the ODBC driver to retrieve it.}
2564094b 113\twocolitem{Cursor}{A logical pointer into the result set that a query
b25ba5b7
GT
114generates, indicating the next record that will be returned to the client
115when a request for the next record is made.}
116\twocolitem{Scrolling cursors}{Scrolling refers to the movement of cursors
2564094b
JS
117through the result set. Cursors can always scroll forward sequentially in
118the result set (FORWARD ONLY scrolling cursors). With Forward only scrolling
b25ba5b7
GT
119cursors, once a row in the result set has been returned to the ODBC driver
120and on to the client, there is no way to have the cursor move backward in
121the result set to look at the row that is previous to the current row in
2564094b 122the result set. If BACKWARD scrolling cursors are supported by both the
b25ba5b7
GT
123ODBC driver and the datasource that are being used, then backward
124scrolling cursor functions may be used (
125\helpref{wxDbTable::GetPrev}{wxdbtablegetprev},
126\helpref{wxDbTable::GetFirst}{wxdbtablegetfirst}, and
2564094b 127\helpref{wxDbTable::GetLast}{wxdbtablegetlast}). If the datasource or the
b25ba5b7
GT
128ODBC driver only support forward scrolling cursors, your program and logic
129must take this in to account.}
130\twocolitem{Commit/Rollback}{Commit will physically save
131insertions/deletions/updates, while rollback basically does an undo of
132everything done against the datasource connection that has not been
2564094b
JS
133previously committed. Note that Commit and Rollbacks are done on a
134connection, not on individual tables. All tables which use a shared
b25ba5b7
GT
135connection to the datasource are all committed/rolled back at the same
136time when a call to
137\helpref{wxDb::CommitTrans}{wxdbcommittrans} or
138\helpref{wxDb::RollbackTrans}{wxdbrollbacktrans} is made.}
2564094b 139\twocolitem{Index}{Indexes are datasource-maintained lookup structures
b25ba5b7 140that allow the datasource to quickly locate data rows based on the values
2564094b
JS
141of certain columns. Without indexes, the datasource would need to do a
142sequential search of a table every time a query request is made. Proper
b25ba5b7
GT
143unique key index construction can make datasource queries nearly instantaneous.}
144\end{twocollist}
145
146Before you are able to read data from a data table in a datasource, you must
2564094b 147have a connection to the datasource. Each datasource connection may be used
b25ba5b7
GT
148to open multiple tables all on the same connection (number of tables open are
149dependent on the driver, datasource configuration and the amount of memory on
2564094b 150the client workstation). Multiple connections can be opened to the same
b25ba5b7
GT
151datasource by the same client (number of concurrent connections is dependent
152on the driver and datasource configuration).
153
154When a query is performed, the client passes the query to the ODBC driver,
2564094b 155and the driver then translates it and passes it along to the datasource. The
b25ba5b7
GT
156database engine (in most cases - exceptions are text and dBase files) running
157on the machine hosting the database does all the work of performing the search
2564094b
JS
158for the requested data. The client simply waits for a status to come back
159through the ODBC driver from the datasource.
b25ba5b7
GT
160
161Depending on the ODBC driver, the result set either remains "queued" on the
162database server side, or is transferred to the machine that the driver is
2564094b 163queued on. The client does not receive this data. The client must request
b25ba5b7
GT
164some or all of the result set to be returned before any data rows are
165returned to the client application.
166
167Result sets do not need to include all columns of every row matching the
2564094b 168query. In fact, result sets can actually be joinings of columns from two
b25ba5b7
GT
169or more data tables, may have derived column values, or calculated values
170returned.
171
172For each result set, a cursor is maintained (typically by the database)
2564094b 173which keeps track of where in the result set the user currently is.
b25ba5b7
GT
174Depending on the database, ODBC driver, and how you configured the
175wxWindows ODBC settings in setup.h (see \helpref{wxODBC - Compiling}{wxodbccompiling}), cursors can be
2564094b
JS
176either forward or backward scrolling. At a minimum, cursors must scroll
177forward. For example, if a query resulted in a result set with 100 rows,
b25ba5b7 178as the data is read by the client application, it will read row 1, then 2,
2564094b 179then 3, etc. With forward only cursors, once the cursor has moved to
b25ba5b7 180the next row, the previous row cannot be accessed again without re-querying
2564094b 181the datasource for the result set over again. Backward scrolling cursors
b25ba5b7
GT
182allow you to request the previous row from the result set, actually
183scrolling the cursor backward.
184
185Backward scrolling cursors are not supported on all database/driver
2564094b
JS
186combinations. For this reason, forward-only cursors are the default in
187the wxODBC classes. If your datasource does support backward scrolling
b25ba5b7 188cursors and you wish to use them, make the appropriate changes in setup.h
2564094b 189to enable them (see \helpref{wxODBC - Compiling}{wxodbccompiling}). For greatest portability between
b25ba5b7 190datasources, writing your program in such a way that it only requires
2564094b 191forward scrolling cursors is your best bet. On the other hand, if you are
b25ba5b7
GT
192focusing on using only datasources that support backward scrolling cursors,
193potentially large performance benefits can be gained from using them.
194
195There is a limit to the number of cursors that can be open on each connection
196to the datasource, and usually a maximum number of cursors for the datasource
2564094b
JS
197itself. This is all dependent on the database. Each connection that is
198opened (each instance of a wxDb) opens a minimum of 5 cursors on creation
199that are required for things such as updates/deletions/rollbacks/queries.
b25ba5b7
GT
200Cursors are a limited resource, so use care in creating large numbers of
201cursors.
202
203Additional cursors can be created if necessary with the
2564094b
JS
204\helpref{wxDbTable::GetNewCursor}{wxdbtablegetnewcursor} function. One example
205use for additional cursors is to track multiple scroll points in result
206sets. By creating a new cursor, a program could request a second result set
b25ba5b7
GT
207from the datasource while still maintaining the original cursor position in
208the first result set.
209
210Different than non-SQL/ODBC datasources, when a program performs an
211insertion, deletion, or update (or other SQL functions like altering
212tables, etc) through ODBC, the program must issue a "commit" to the
213datasource to tell the datasource that the action(s) it has been told to
2564094b 214perform are to be recorded as permanent. Until a commit is performed,
b25ba5b7
GT
215any other programs that query the datasource will not see the changes that
216have been made (although there are databases that can be configured to
2564094b 217auto-commit). NOTE: With most datasources, until the commit is
b25ba5b7 218performed, any cursor that is open on that same datasource connection
2564094b
JS
219will be able to see the changes that are uncommitted. Check your
220database's documentation/configuration to verify this before relying on it
b25ba5b7
GT
221though.
222
2564094b 223A rollback is basically an UNDO command on the datasource connection. When
b25ba5b7
GT
224a rollback is issued, the datasource will flush all commands it has been told
225to do since the last commit that was performed.
226
227NOTE: Commits/Rollbacks are done on datasource connections (wxDb instances)
2564094b 228not on the wxDbTable instances. This means that if more than one table
b25ba5b7
GT
229shares the same connection, and a commit or rollback is done on that
230connection, all pending changes for ALL tables using that connection are
231committed/rolled back.
232
b25ba5b7
GT
233\subsection{wxODBC - Configuring your system for ODBC use}\label{wxodbcconfiguringyoursystem}
234
235Before you are able to access a datasource, you must have installed and
2564094b
JS
236configured an ODBC driver. Doing this is system specific, so it will not be
237covered in detail here. But here are a few details to get you started.
b25ba5b7
GT
238
239Most database vendors provide at least a minimal ODBC driver with their
2564094b
JS
240database product. In practice, many of these drivers have proven to be slow
241and/or incomplete. Rumour has it that this is because the vendors do not want
242you using the ODBC interface to their products; they want you to use their
243applications to access the data.
244
245Whatever the reason, for database-intensive applications, you may want to
246consider using a third-party ODBC driver for your needs. One example of a
247third-party set of ODBC drivers that has been heavily tested and used is
248Rogue Wave's drivers. Rogue Wave has drivers available for many different
b25ba5b7
GT
249platforms and databases.
250
2564094b 251Under Microsoft Windows, install the ODBC driver you are planning to use. You
b25ba5b7 252will then use the ODBC Administrator in the Control Panel to configure an
2564094b 253instance of the driver for your intended datasource. Note that with all
b25ba5b7 254flavors of NT, this configuration can be set up as a System or User DSN
2564094b 255(datasource name). Configuring it as a system resource will make it
b25ba5b7 256available to all users (if you are logged in as 'administrator'), otherwise
2564094b 257the datasource will only be available to the user who configured the DSN.
b25ba5b7 258
2564094b
JS
259Under Unix, iODBC is used for implementation of the ODBC API. To compile the
260wxODBC classes, you must first obtain iODBC from \urlref{http://www.iodbc.org}{www.iodbc.org} and install it.
261(Note: wxWindows currently includes a version of iODBC.) Then you must create the file "~/.odbc.ini" (or optionally create
262"/etc/odbc.ini" for access for all users on the system). This file contains
263the settings for your system/datasource. Below is an example section of a
b25ba5b7
GT
264odbc.ini file for use with the "samples/db" sample program using MySQL:
265
266\begin{verbatim}
267 [contacts]
268 Trace = Off
269 TraceFile= stderr
270 Driver = /usr/local/lib/libmyodbc.so
271 DSN = contacts
272 SERVER = 192.168.1.13
273 USER = qet
274 PASSWORD =
275 PORT = 3306
276\end{verbatim}
277
b25ba5b7
GT
278\subsection{wxODBC - Compiling}\label{wxodbccompiling}
279
280The wxWindows setup.h file has several settings in it pertaining to compiling
281the wxODBC classes.
282
283\begin{twocollist}\itemsep=0pt
509cd921 284\twocolitem{wxUSE\_ODBC}{This must be set to 1 in order for the compiler to
2564094b
JS
285compile the wxODBC classes. Without setting this to 1, there will be no
286access to any of the wxODBC classes. The default is 0.}
509cd921 287\twocolitem{wxODBC\_FWD\_ONLY\_CURSORS}{When a new database connection is
b25ba5b7
GT
288requested, this setting controls the default of whether the connection allows
289only forward scrolling cursors, or forward and backward scrolling cursors
290(see the section in "WHERE TO START" on cursors for more information on
2564094b 291cursors). This default can be overridden by passing a second parameter to
b25ba5b7 292either the \helpref{wxDbGetConnection}{wxdbfunctions} or
2564094b 293\helpref{wxDb constructor}{wxdbconstr}. The default is 1.}
509cd921 294\twocolitem{wxODBC\_BACKWARD\_COMPATABILITY}{Between v2.0 and 2.2, massive
b25ba5b7
GT
295renaming efforts were done to the ODBC classes to get naming conventions
296similar to those used throughout wxWindows, as well as to preface all wxODBC
2564094b 297classes names and functions with a wxDb preface. Because this renaming would
b25ba5b7
GT
298affect applications written using the v2.0 names, this compile-time directive
299was added to allow those programs written for v2.0 to still compile using the
7af3ca16 300old naming conventions. These deprecated names are all {\tt\#}define'd to their
b25ba5b7 301corresponding new function names at the end of the db.cpp/dbtable.cpp source
2564094b
JS
302files. These deprecated class/function names should not be used in future
303development, as at some point in the future they will be removed. The default
b25ba5b7
GT
304is 0.}
305\end{twocollist}
306
307{\it Under MS Windows}
308
309You are required to include the "odbc32.lib" provided by your compiler vendor
2564094b 310in the list of external libraries to be linked in. If using the makefiles
b25ba5b7
GT
311supplied with wxWindows, this library should already be included for use with
312makefile.b32, makefile.vc, and makefile.g95.
313
314You cannot compile the wxODBC classes under Win16 - sorry.
315
316\normalbox{MORE TO COME}
317
318{\it Under Unix}
6b2878de 319--with-odbc flag for configure
b25ba5b7
GT
320
321\normalbox{MORE TO COME}
322
b25ba5b7
GT
323\subsection{wxODBC - Basic Step-By-Step Guide}\label{wxodbcstepbystep}
324
325To use the classes in an application, there are eight basic steps:
326
327\begin{itemize}\itemsep=0pt
328\item Define datasource connection information
329\item Get a datasource connection
330\item Create table definition
331\item Open the table
332\item Use the table
333\item Close the table
334\item Close the datasource connection
335\item Release the ODBC environment handle
336\end{itemize}
337
338Following each of these steps is detailed to explain the step, and to
339hopefully mention as many of the pitfalls that beginning users fall in
2564094b
JS
340to when first starting to use the classes. Throughout the steps, small
341snippets of code are provided to show the syntax of performing the step. A
b25ba5b7
GT
342complete code snippet is provided at the end of this overview that shows a
343complete working flow of all these steps (see
7af3ca16 344\helpref{wxODBC - Sample Code {\tt\#}1}{wxodbcsamplecode1}).
b25ba5b7 345
b25ba5b7
GT
346{\bf Define datasource connection information}
347
348To be able to connect to a datasource through the ODBC driver, a program must
349supply a minimum of three pieces of information: Datasource name, User ID, and
2564094b 350Authorization string (password). A fourth piece of information, a default
b25ba5b7
GT
351directory indicating where the data file is stored, is required for Text and
352dBase drivers for ODBC.
353
9fe17bd3 354The wxWindows data class wxDbConnectInf exists for holding all of these
b25ba5b7
GT
355values, plus some others that may be desired.
356
b25ba5b7 357The 'Henv' member is the environment handle used to access memory for use by the
2564094b 358ODBC driver. Use of this member is described below in the "Getting a Connection
b25ba5b7
GT
359to the Datasource" section.
360
361The 'Dsn' must exactly match the datasource name used to configure the ODBC
362datasource (in the ODBC Administrator (MSW only) or in the .odbc.ini file).
363
2564094b 364The 'Uid' is the User ID that is to be used to log in to the datasource. This
b25ba5b7 365User ID must already have been created and assigned rights within the
2564094b 366datasource to which you are connecting. The user that the connection is
b25ba5b7
GT
367establish by will determine what rights and privileges the datasource
368connection will allow the program to have when using the connection that
2564094b 369this connection information was used to establish. Some datasources are
b25ba5b7
GT
370case sensitive for User IDs, and though the wxODBC classes attempt to hide
371this from you by manipulating whatever data you pass in to match the
372datasource's needs, it is always best to pass the 'Uid' in the case that
373the datasource requires.
374
2564094b
JS
375The 'AuthStr' is the password for the User ID specified in the 'Uid' member.
376As with the 'Uid', some datasources are case sensitive (in fact most are).
377The wxODBC classes do NOT try to manage the case of the 'AuthStr' at all.
b25ba5b7
GT
378It is passed verbatim to the datasource, so you must use the case that the
379datasource is expecting.
380
381The 'defaultDir' member is used with file based datasources (i.e. dBase,
2564094b
JS
382FoxPro, text files). It contains a full path to the location where the
383data table or file is located. When setting this value, use forward
b25ba5b7
GT
384slashes '/' rather than backslashes '\' to avoid compatibility differences
385between ODBC drivers.
386
2564094b 387The other fields are currently unused. The intent of these fields are that
b25ba5b7 388they will be used to write our own ODBC Administrator type program that will
2564094b 389work on both MSW and Un*x systems, regardless of the datasource. Very little
b25ba5b7
GT
390work has been done on this to date.
391
b25ba5b7
GT
392{\bf Get a Datasource Connection}
393
2564094b 394There are two methods of establishing a connection to a datasource. You
b25ba5b7
GT
395may either manually create your own wxDb instance and open the connection,
396or you may use the caching functions provided with the wxODBC classes to
397create/maintain/delete the connections.
398
399Regardless of which method you use, you must first have a fully populated
2564094b
JS
400wxDbConnectInf object. In the wxDbConnectInf instance, provide a valid
401Dns, Uid, and AuthStr (along with a 'defaultDir' if necessary). Before
b25ba5b7
GT
402using this though, you must allocate an environment handle to the 'Henv'
403member.
404
405\begin{verbatim}
406 wxDbConnectInf DbConnectInf;
2b5f62a0
VZ
407 DbConnectInf.SetDsn("MyDSN");
408 DbConnectInf.SetUserID("MyUserName");
9fe17bd3
GT
409 DbConnectInf.SetPassword("MyPassword");
410 DbConnectInf.SetDefaultDir("");
b25ba5b7
GT
411\end{verbatim}
412
413To allocate an environment handle for the ODBC connection to use, the
19320af4
GT
414wxDbConnectInf class has a datasource independent method for creating
415the necessary handle:
b25ba5b7
GT
416
417\begin{verbatim}
9fe17bd3 418 if (DbConnectInf.AllocHenv())
b25ba5b7
GT
419 {
420 wxMessageBox("Unable to allocate an ODBC environment handle",
421 "DB CONNECTION ERROR", wxOK | wxICON_EXCLAMATION);
422 return;
423 }
424\end{verbatim}
425
19320af4 426When the wxDbConnectInf::AllocHenv() function is called successfully, a
2564094b 427value of TRUE will be returned. A value of FALSE means allocation failed,
19320af4 428and the handle will be undefined.
9fe17bd3
GT
429
430A shorter form of doing the above steps is encapsulated into the
431long form of the constructor for wxDbConnectInf.
432
9fe17bd3
GT
433\begin{verbatim}
434 wxDbConnectInf *DbConnectInf;
435
436 DbConnectInf = new wxDbConnectInf(NULL, "MyDSN", "MyUserName",
437 "MyPassword", "");
438\end{verbatim}
439
440This shorthand form of initializing the constructor passes a NULL for the SQL
441environment handle, telling the constructor to allocate a handle during
2564094b 442construction. This handle is also managed for the life of wxDbConnectInf
9fe17bd3 443instance, and is freed automatically upon destruction of the instance.
b25ba5b7 444
9fe17bd3
GT
445Once the wxDbConnectInf instance is initialized, you are ready to
446connect to the datasource.
b25ba5b7
GT
447
448To manually create datasource connections, you must create a wxDb
449instance, and then open it.
450
451\begin{verbatim}
9fe17bd3
GT
452 wxDb *db = new wxDb(DbConnectInf->GetHenv());
453
454 opened = db->Open(DbConnectInf);
b25ba5b7
GT
455\end{verbatim}
456
9fe17bd3 457The first line does the house keeping needed to initialize all
2564094b 458the members of the wxDb class. The second line actually sends the request
b25ba5b7
GT
459to the ODBC driver to open a connection to its associated datasource using
460the parameters supplied in the call to \helpref{wxDb::Open}{wxdbopen}.
461
2564094b
JS
462A more advanced form of opening a connection is to use the connection
463caching functions that are included with the wxODBC classes. The caching
464mechanisms perform the same functions as the manual approach to opening a
b25ba5b7
GT
465connection, but they also manage each connection they have created,
466re-using them and cleaning them up when they are closed, without you
2564094b 467needing to do the coding.
b25ba5b7
GT
468
469To use the caching function \helpref{wxDbGetConnection}{wxdbfunctions} to get
470a connection to a datasource, simply call it with a single parameter of the
471type wxDbConnectInf:
472
473\begin{verbatim}
9fe17bd3 474 db = wxDbGetConnection(DbConnectInf);
b25ba5b7
GT
475\end{verbatim}
476
2564094b 477The wxDb pointer that is returned is both initialized and opened. If
b25ba5b7
GT
478something failed in creating or opening the connection, the return value
479from \helpref{wxDbGetConnection}{wxdbfunctions} will be NULL.
480
481The connection that is returned is either a new connection, or it is a
482"free" connection from the cache of connections that the class maintains
2564094b
JS
483that was no longer in use. Any wxDb instance created with a call to
484\helpref{wxDbGetConnection}{wxdbfunctions} is recorded in a linked list of established
485connections. When a program is finished with a connection, a call to
b25ba5b7
GT
486\helpref{wxDbFreeConnection}{wxdbfunctions} is made, and the datasource
487connection will then be tagged as FREE, making it available for the next
488call to \helpref{wxDbGetConnection}{wxdbfunctions} that needs a connection
2564094b 489using the same connection information (Dsn, Uid, AuthStr). The cached
b25ba5b7
GT
490connections remain cached until a call to \helpref{wxDbCloseConnections}{wxdbfunctions} is made,
491at which time all cached connections are closed and deleted.
492
493Besides the obvious advantage of using the single command caching routine to
494obtain a datasource connection, using cached connections can be quite a
2564094b 495performance boost as well. Each time that a new connection is created
b25ba5b7
GT
496(not retrieved from the cache of free connections), the wxODBC classes
497perform many queries against the datasource to determine the datasource's
2564094b 498datatypes and other fundamental behaviours. Depending on the hardware,
b25ba5b7 499network bandwidth, and datasource speed, this can in some cases take a
2564094b
JS
500few seconds to establish the new connection (with well-balanced systems,
501it should only be a fraction of a second). Re-using already established
b25ba5b7 502datasource connections rather than creating/deleting, creating/deleting
2564094b 503connections can be quite a time-saver.
b25ba5b7 504
2564094b
JS
505Another time-saver is the "copy connection" features of both
506\helpref{wxDb::Open}{wxdbopen} and \helpref{wxDbGetConnection}{wxdbfunctions}.
b25ba5b7
GT
507If manually creating a wxDb instance and opening it, you must pass an existing
508connection to the \helpref{wxDb::Open}{wxdbopen} function yourself to gain the performance
2564094b 509benefit of copying existing connection settings. The
b25ba5b7
GT
510\helpref{wxDbGetConnection}{wxdbfunctions} function automatically does this
511for you, checking the Dsn, Uid, and AuthStr parameters when you request
2564094b 512a connection for any existing connections that use those same settings.
b25ba5b7
GT
513If one is found, \helpref{wxDbGetConnection}{wxdbfunctions} copies the datasource settings for
514datatypes and other datasource specific information that was previously
515queried, rather than re-querying the datasource for all those same settings.
516
2564094b 517One final note on creating a connection. When a connection is created, it
b25ba5b7 518will default to only allowing cursor scrolling to be either forward only,
2564094b 519or both backward and forward scrolling. The default behavior is
509cd921 520determined by the setting {\tt wxODBC\_FWD\_ONLY\_CURSORS} in setup.h when you
2564094b 521compile the wxWindows library. The library default is to only support
b25ba5b7
GT
522forward scrolling cursors only, though this can be overridden by parameters
523for wxDb() constructor or the \helpref{wxDbGetConnection}{wxdbfunctions}
2564094b
JS
524function. All datasources and ODBC drivers must support forward scrolling
525cursors. Many datasources support backward scrolling cursors, and many
526ODBC drivers support backward scrolling cursors. Before planning on using
b25ba5b7 527backward scrolling cursors, you must be certain that both your datasource
2564094b 528and ODBC driver fully support backward scrolling cursors. See the small
b25ba5b7
GT
529blurb about "Scrolling cursors" in the definitions at the beginning of
530this overview, or other details of setting the cursor behavior in the wxDb
531class documentation.
532
b25ba5b7
GT
533{\bf Create Table Definition}
534
535Data can be accessed in a datasource's tables directly through various
2564094b 536functions of the wxDb class (see \helpref{wxDb::GetData}{wxdbgetdata}). But to make life much
b25ba5b7
GT
537simpler, the wxDbTable class encapsulates all of the SQL specific API calls
538that would be necessary to do this, wrapping it in an intuitive class of APIs.
539
540The first step in accessing data in a datasource's tables via the wxDbTable
541class is to create a wxDbTable instance.
542
543\begin{verbatim}
9fe17bd3
GT
544 table = new wxDbTable(db, tableName, numTableColumns, "",
545 !wxDB_QUERY_ONLY, "");
b25ba5b7
GT
546\end{verbatim}
547
548When you create the instance, you indicate the previously established
549datasource connection to be used to access the table, the name of the
550primary table that is to be accessed with the datasource's tables, how many
551columns of each row are going to be returned, the name of the view of the
552table that will actually be used to query against (works with Oracle only
553at this time), whether the data returned is for query purposes only, and
554finally the path to the table, if different than the path specified when
555connecting to the datasource.
556
557Each of the above parameters are described in detail in the wxDbTable
558class' description, but one special note here about the fifth
2564094b
JS
559parameter - the queryOnly setting. If a wxDbTable instance is created as
560{\tt wxDB\_QUERY\_ONLY}, then no inserts/deletes/updates can be performed
561using this instance of the wxDbTable. Any calls to \helpref{wxDb::CommitTrans}{wxdbcommittrans}
b25ba5b7 562or \helpref{wxDb::RollbackTrans}{wxdbrollbacktrans} against the datasource
2564094b 563connection used by this wxDbTable instance are ignored by this instance. If
509cd921 564the wxDbTable instance is created with {\tt !wxDB\_QUERY\_ONLY} as shown above,
b25ba5b7
GT
565then all the cursors and other overhead associated with being able to
566insert/update/delete data in the table are created, and thereby those
567operations can then be performed against the associated table with this
568wxDbTable instance.
569
570If a table is to be accessed via a wxDbTable instance, and the table will
571only be read from, not written to, there is a performance benefit (not as
572many cursors need to be maintained/updated, hence speeding up access times),
573as well as a resource savings due to fewer cursors being created for the
2564094b
JS
574wxDbTable instance. Also, with some datasources, the number of
575simultaneous cursors is limited.
b25ba5b7
GT
576
577When defining the columns to be retrievable by the wxDbTable instance, you
2564094b 578can specify anywhere from one column up to all columns in the table.
b25ba5b7
GT
579
580\begin{verbatim}
581 table->SetColDefs(0, "FIRST_NAME", DB_DATA_TYPE_VARCHAR, FirstName,
582 SQL_C_CHAR, sizeof(name), TRUE, TRUE);
583 table->SetColDefs(1, "LAST_NAME", DB_DATA_TYPE_VARCHAR, LastName,
584 SQL_C_CHAR, sizeof(LastName), TRUE, TRUE);
585\end{verbatim}
586
587Notice that column definitions start at index 0 and go up to one less than
588the number of columns specified when the wxDbTable instance was created
589(in this example, two columns - one with index 0, one with index 1).
590
591The above lines of code "bind" the datasource columns specified to the
2564094b 592memory variables in the client application. So when the application
b25ba5b7
GT
593makes a call to \helpref{wxDbTable::GetNext}{wxdbtablegetnext} (or any other function that retrieves
594data from the result set), the variables that are bound to the columns will
2564094b 595have the column value stored into them. See the
b25ba5b7
GT
596\helpref{wxDbTable::SetColDefs}{wxdbtablesetcoldefs}
597class documentation for more details on all the parameters for this function.
598
599The bound memory variables have undefined data in them until a call to a
600function that retrieves data from a result set is made
601(e.g. \helpref{wxDbTable::GetNext}{wxdbtablegetnext},
2564094b 602\helpref{wxDbTable::GetPrev}{wxdbtablegetprev}, etc). The variables are not
b25ba5b7 603initialized to any data by the wxODBC classes, and they still contain
2564094b 604undefined data after a call to \helpref{wxDbTable::Query}{wxdbtablequery}. Only
b25ba5b7
GT
605after a successful call to one of the ::GetXxxx() functions is made do the
606variables contain valid data.
607
608It is not necessary to define column definitions for columns whose data is
2564094b 609not going to be returned to the client. For example, if you want to query
b25ba5b7 610the datasource for all users with a first name of 'GEORGE', but you only want
509cd921 611the list of last names associated with those rows (why return the FIRST\_NAME
b25ba5b7
GT
612column every time when you already know it is 'GEORGE'), you would only have
613needed to define one column above.
614
615You may have as many wxDbTable instances accessing the same table using the
2564094b
JS
616same wxDb instance as you desire. There is no limit imposed by the classes
617on this. All datasources supported (so far) also have no limitations on this.
b25ba5b7
GT
618
619{\bf Open the table}
620
2564094b
JS
621Opening the table is not technically doing anything with the datasource
622itself. Calling \helpref{wxDbTable::Open}{wxdbtableopen} simply does all the
623housekeeping of checking that the specified table exists, that the current
b25ba5b7 624connected user has at least SELECT privileges for accessing the table,
2564094b 625setting up the requisite cursors, binding columns and cursors, and
b25ba5b7 626constructing the default INSERT statement that is used when a new row is
509cd921 627inserted into the table (non-wxDB\_QUERY\_ONLY tables only).
b25ba5b7
GT
628
629\begin{verbatim}
630 if (!table->Open())
631 {
632 // An error occurred opening (setting up) the table
633 }
634\end{verbatim}
635
2564094b
JS
636The only reason that a call to \helpref{wxDbTable::Open}{wxdbtableopen} is likely to fail is if the
637user has insufficient privileges to even SELECT the table. Other problems
b25ba5b7 638could occur, such as being unable to bind columns, but these other reason
2564094b 639point to some lack of resource (like memory). Any errors generated
b25ba5b7
GT
640internally in the \helpref{wxDbTable::Open}{wxdbtableopen} function are logged to the error log
641if SQL logging is turned on for the classes.
642
b25ba5b7
GT
643{\bf Use the table}
644
645To use the table and the definitions that are now set up, we must first
646define what data we want the datasource to collect in to a result set, tell
647it where to get the data from, and in what sequence we want the data returned.
648
649\begin{verbatim}
650 // the WHERE clause limits/specifies which rows in the table
651 // are to be returned in the result set
652 table->SetWhereClause("FIRST_NAME = 'GEORGE'");
653
654 // Result set will be sorted in ascending alphabetical
655 // order on the data in the 'LAST_NAME' column of each row
656 // If the same last name is in the table for two rows,
657 // sub-sort on the 'AGE' column
658 table->SetOrderByClause("LAST_NAME, AGE");
659
660 // No other tables (joins) are used for this query
661 table->SetFromClause("");
662\end{verbatim}
663
664The above lines will be used to tell the datasource to return in the result
509cd921 665all the rows in the table whose column "FIRST\_NAME" contains the name
b25ba5b7
GT
666'GEORGE' (note the required use of the single quote around the string
667literal) and that the result set will return the rows sorted by ascending
668last names (ascending is the default, and can be overridden with the
509cd921 669"DESC" keyword for datasources that support it - "LAST\_NAME DESC").
b25ba5b7
GT
670
671Specifying a blank WHERE clause will result in the result set containing
672all rows in the datasource.
673
674Specifying a blank ORDERBY clause means that the datasource will return
675the result set in whatever sequence it encounters rows which match the
2564094b 676selection criteria. What this sequence is can be hard to determine.
b25ba5b7 677Typically it depends on the index that the datasource used to find the
2564094b 678rows which match the WHERE criteria. BEWARE - relying on the datasource
b25ba5b7 679to return data in a certain sequence when you have not provided an ORDERBY
2564094b 680clause will eventually cause a problem for your program. Databases can be
b25ba5b7 681tuned to be COST-based, SPEED-based, or some other basis for how it gets
2564094b 682your result set. In short, if you need your result set returned in a
b25ba5b7
GT
683specific sequence, ask for it that way by providing an ORDERBY clause.
684
685Using an ORDERBY clause can be a performance hit, as the database must
2564094b 686sort the items before making the result set available to the client.
b25ba5b7 687Creating efficient indexes that cause the data to be "found" in the correct
2564094b 688ORDERBY sequence can be a big performance benefit. Also, in the large
b25ba5b7
GT
689majority of cases, the database will be able to sort the records faster
690than your application can read all the records in (unsorted) and then sort
2564094b 691them. Let the database do the work for you!
b25ba5b7
GT
692
693Notice in the example above, a column that is not included in the bound
694data columns ('AGE') will be used to sub-sort the result set.
695
696The FROM clause in this example is blanked, as we are not going to be
2564094b 697performing any table joins with this simple query. When the FROM clause
b25ba5b7
GT
698is blank, it is assumed that all columns referenced are coming from
699the default table for the wxDbTable instance.
700
701After the selection criteria have been specified, the program can now
702ask the datasource to perform the search and create a result set that
703can be retrieved:
704
705\begin{verbatim}
706 // Instruct the datasource to perform a query based on the
707 // criteria specified above in the where/orderBy/from clauses.
708 if (!table->Query())
709 {
710 // An error occurred performing the query
711 }
712\end{verbatim}
713
714Typically, when an error occurs when calling \helpref{wxDbTable::Query}{wxdbtablequery}, it is a
2564094b
JS
715syntax problem in the WHERE clause that was specified. The exact SQL
716(datasource-specific) reason for what caused the failure of \helpref{wxDbTable::Query}{wxdbtablequery}
b25ba5b7
GT
717(and all other operations against the datasource can be found by
718parsing the table's database connection's "errorList[]" array member for
719the stored text of the error.
720
721When the \helpref{wxDbTable::Query}{wxdbtablequery} returns TRUE, the
722database was able to successfully complete the requested query using the
2564094b 723provided criteria. This does not mean that there are any rows in the
b25ba5b7
GT
724result set, it just mean that the query was successful.
725
726\normalbox{IMPORTANT: The result created by the call to
2564094b 727\helpref{wxDbTable::Query}{wxdbtablequery} can take one of two forms. It is
b25ba5b7
GT
728either a snapshot of the data at the exact moment that the database
729determined the record matched the search criteria, or it is a pointer to
2564094b
JS
730the row that matched the selection criteria. Which form of behavior is
731datasource dependent. If it is a snapshot, the data may have changed
b25ba5b7 732since the result set was constructed, so beware if your datasource
2564094b 733uses snapshots and call \helpref{wxDbTable::Refresh}{wxdbtablerefresh}. Most larger brand databases
b25ba5b7 734do not use snapshots, but it is important to mention so that your application
2564094b 735can handle it properly if your datasource does.}
b25ba5b7
GT
736
737To retrieve the data, one of the data fetching routines must be used to
738request a row from the result set, and to store the data from the result
2564094b 739set into the bound memory variables. After \helpref{wxDbTable::Query}{wxdbtablequery}
b25ba5b7 740has completed successfully, the default/current cursor is placed so it
2564094b 741is pointing just before the first record in the result set. If the
b25ba5b7
GT
742result set is empty (no rows matched the criteria), then any calls to
743retrieve data from the result set will return FALSE.
744
745\begin{verbatim}
746 wxString msg;
747
748 while (table->GetNext())
749 {
750 msg.Printf("Row #%lu -- First Name : %s Last Name is %s",
751 table->GetRowNum(), FirstName, LastName);
752 wxMessageBox(msg, "Data", wxOK | wxICON_INFORMATION, NULL);
753 }
754\end{verbatim}
755
756The sample code above will read the next record in the result set repeatedly
2564094b 757until the end of the result set has been reached. The first time that
b25ba5b7
GT
758\helpref{wxDbTable::GetNext}{wxdbtablegetnext} is called right after the successful
759call to \helpref{wxDbTable::Query}{wxdbtablequery}, it actually returns the first record
760in the result set.
761
762When \helpref{wxDbTable::GetNext}{wxdbtablegetnext} is called and there are
763no rows remaining in the result set after the current cursor position,
764\helpref{wxDbTable::GetNext}{wxdbtablegetnext} (as well as all the other
765wxDbTable::GetXxxxx() functions) will return FALSE.
766
b25ba5b7
GT
767{\bf Close the table}
768
769When the program is done using a wxDbTable instance, it is as simple as
770deleting the table pointer (or if declared statically, letting the
2564094b 771variable go out of scope). Typically the default destructor will take
b25ba5b7
GT
772care of all that is required for cleaning up the wxDbTable instance.
773
774\begin{verbatim}
775 if (table)
776 {
777 delete table;
778 table = NULL;
779 }
780\end{verbatim}
781
782Deleting a wxDbTable instance releases all of its cursors, deletes the
783column definitions and frees the SQL environment handles used by the
784table (but not the environment handle used by the datasource connection
785that the wxDbTable instance was using).
786
b25ba5b7
GT
787{\bf Close the datasource connection}
788
789After all tables that have been using a datasource connection have been
2564094b 790closed (this can be verified by calling \helpref{wxDb::GetTableCount}{wxdbgettablecount}
b25ba5b7 791and checking that it returns 0), then you may close the datasource
2564094b 792connection. The method of doing this is dependent on whether the
b25ba5b7
GT
793non-caching or caching method was used to obtain the datasource connection.
794
795If the datasource connection was created manually (non-cached), closing the
796connection is done like this:
797
798\begin{verbatim}
799 if (db)
800 {
801 db->Close();
802 delete db;
803 db = NULL;
804 }
805\end{verbatim}
806
807If the program used the \helpref{wxDbGetConnection}{wxdbfunctions} function to get a datasource
808connection, the following is the code that should be used to free the
809connection(s):
810
811\begin{verbatim}
812 if (db)
813 {
814 wxDbFreeConnection(db);
815 db = NULL;
816 }
817\end{verbatim}
818
819Note that the above code just frees the connection so that it can be
2564094b 820re-used on the next call the \helpref{wxDbGetConnection}{wxdbfunctions}. To actually dispose
b25ba5b7
GT
821of the connection, releasing all of its resources (other than the
822environment handle), do the following:
823
824\begin{verbatim}
825 wxDbCloseConnections();
826\end{verbatim}
827
b25ba5b7
GT
828{\bf Release the ODBC environment handle}
829
830Once all of the connections that used the ODBC environment handle (in
831this example it was stored in "DbConnectInf.Henv") have been closed, then
832it is safe to release the environment handle:
833
834\begin{verbatim}
2b5f62a0 835 DbConnectInf->FreeHenv();
9fe17bd3 836\end{verbatim}
b25ba5b7 837
9fe17bd3
GT
838Or, if the long form of the constructor was used and the constructor was allowed
839to allocate its own SQL environment handle, leaving scope or destruction of the
840wxDbConnectInf will free the handle automatically.
841
842\begin{verbatim}
843 delete DbConnectInf;
b25ba5b7
GT
844\end{verbatim}
845
846\normalbox{Remember to never release this environment handle if there are any
5f6d6405 847connections still using the handle.}
b25ba5b7 848
b25ba5b7
GT
849\subsection{wxODBC - Known Issues}\label{wxodbcknownissues}
850
851As with creating wxWindows, writing the wxODBC classes was not the simple
2564094b 852task of writing an application to run on a single type of computer system.
b25ba5b7
GT
853The classes need to be cross-platform for different operating systems, and
854they also needed to take in to account different database manufacturers and
2564094b 855different ODBC driver manufacturers. Because of all the possible combinations
b25ba5b7 856of OS/database/drivers, it is impossible to say that these classes will work
2564094b 857perfectly with datasource ABC, ODBC driver XYZ, on platform LMN. You may run
b25ba5b7 858in to some incompatibilities or unsupported features when moving your
2564094b
JS
859application from one environment to another. But that is what makes
860cross-platform programming fun. It is also pinpoints one of the great
861things about open source software. It can evolve!
b25ba5b7
GT
862
863The most common difference between different database/ODBC driver
864manufacturers in regards to these wxODBC classes is the lack of
2564094b 865standard error codes being returned to the calling program. Sometimes
b25ba5b7 866manufacturers have even changed the error codes between versions of
2564094b 867their databases/drivers.
b25ba5b7
GT
868
869In all the tested databases, every effort has been made to determine
870the correct error codes and handle them in the class members that need
871to check for specific error codes (such as TABLE DOES NOT EXIST when
2564094b 872you try to open a table that has not been created yet). Adding support
b25ba5b7
GT
873for additional databases in the future requires adding an entry for the
874database in the \helpref{wxDb::Dbms}{wxdbdbms} function, and then handling any error codes
875returned by the datasource that do not match the expected values.
876
b25ba5b7
GT
877{\bf Databases}
878
879Following is a list of known issues and incompatibilities that the
2564094b 880wxODBC classes have between different datasources. An up to date
b25ba5b7
GT
881listing of known issues can be seen in the comments of the source
882for \helpref{wxDb::Dbms}{wxdbdbms}.
883
884{\it ORACLE}
885\begin{itemize}\itemsep=0pt
886\item Currently the only database supported by the wxODBC classes to support VIEWS
887\end{itemize}
888
889{\it DBASE}
890
2564094b 891NOTE: dBase is not a true ODBC datasource. You only have access to as much
b25ba5b7
GT
892functionality as the driver can emulate.
893
894\begin{itemize}\itemsep=0pt
509cd921 895\item Does not support the SQL\_TIMESTAMP structure
b25ba5b7 896\item Supports only one cursor and one connect (apparently? with Microsoft driver only?)
2564094b 897\item Does not automatically create the primary index if the 'keyField' param of SetColDef is TRUE. The user must create ALL indexes from their program with calls to \helpref{wxDbTable::CreateIndex}{wxdbtablecreateindex}
b25ba5b7
GT
898\item Table names can only be 8 characters long
899\item Column names can only be 10 characters long
900\item Currently cannot CREATE a dBase table - bug or limitation of the drivers used??
901\item Currently cannot insert rows that have integer columns - bug??
902\end{itemize}
903
904{\it SYBASE (all)}
905\begin{itemize}\itemsep=0pt
906\item To lock a record during QUERY functions, the reserved word 'HOLDLOCK' must be added after every table name involved in the query/join if that table's matching record(s) are to be locked
2564094b 907\item Ignores the keywords 'FOR UPDATE'. Use the HOLDLOCK functionality described above
b25ba5b7
GT
908\end{itemize}
909
910{\it SYBASE (Enterprise)}
911\begin{itemize}\itemsep=0pt
912\item If a column is part of the Primary Key, the column cannot be NULL
913\item Maximum row size is somewhere in the neighborhood of 1920 bytes
914\end{itemize}
915
509cd921 916{\it mySQL}
b25ba5b7
GT
917\begin{itemize}\itemsep=0pt
918\item If a column is part of the Primary Key, the column cannot be NULL.
2564094b
JS
919\item Cannot support selecting for update [\helpref{wxDbTable::CanSelectForUpdate}{wxdbtablecanselectforupdate}]. Always returns FALSE.
920\item Columns that are part of primary or secondary keys must be defined as being NOT NULL when they are created. Some code is added in \helpref{wxDbTable::CreateIndex}{wxdbtablecreateindex} to try to adjust the column definition if it is not defined correctly, but it is experimental (as of wxWindows v2.2.1)
b25ba5b7
GT
921\item Does not support sub-queries in SQL statements
922\end{itemize}
923
924{\it POSTGRES}
925\begin{itemize}\itemsep=0pt
926\item Does not support the keywords 'ASC' or 'DESC' as of release v6.5.0
927\item Does not support sub-queries in SQL statements
928\end{itemize}
929
930{\it DB2}
931\begin{itemize}\itemsep=0pt
932\item Columns which are part of a primary key must be declared as NOT NULL
933\end{itemize}
934
b25ba5b7
GT
935{\bf UNICODE with wxODBC classes}
936
509cd921
VZ
937The ODBC classes support for Unicode is yet in early experimental stage and
938hasn't been tested extensively. It might work for you or it might not: please
939report the bugs/problems you have encountered in the latter case.
b25ba5b7 940
7af3ca16 941\subsection{wxODBC - Sample Code {\tt\#}1}\label{wxodbcsamplecode1}
b25ba5b7
GT
942
943Simplest example of establishing/opening a connection to an ODBC datasource,
944binding variables to the columns for read/write usage, opening an
945existing table in the datasource, setting the query parameters
946(where/orderBy/from), querying the datasource, reading each row of the
947result set, then cleaning up.
948
949NOTE: Not all error trapping is shown here, to reduce the size of the
950code and to make it more easily readable.
951
952\begin{verbatim}
9fe17bd3 953wxDbConnectInf *DbConnectInf = NULL;
b25ba5b7
GT
954
955wxDb *db = NULL; // The database connection
956wxDbTable *table = NULL; // The data table to access
957
9fe17bd3
GT
958wxChar FirstName[50+1]; // buffer for data from column "FIRST_NAME"
959wxChar LastName[50+1]; // buffer for data from column "LAST_NAME"
b25ba5b7
GT
960
961bool errorOccured = FALSE;
962
9fe17bd3 963const wxChar tableName[] = "CONTACTS";
0715c838 964const UWORD numTableColumns = 2; // Number of bound columns
b25ba5b7
GT
965
966FirstName[0] = 0;
967LastName[0] = 0;
968
9fe17bd3
GT
969DbConnectInf = new wxDbConnectInf(NULL,"MyDSN","MyUserName", "MyPassword");
970
971if (!DbConnectInf || !DbConnectInf->GetHenv())
b25ba5b7 972{
9fe17bd3
GT
973 wxMessageBox("Unable to allocate an ODBC environment handle",
974 "DB CONNECTION ERROR", wxOK | wxICON_EXCLAMATION);
975 return;
b25ba5b7
GT
976}
977
b25ba5b7 978// Get a database connection from the cached connections
9fe17bd3 979db = wxDbGetConnection(DbConnectInf);
b25ba5b7
GT
980
981// Create the table connection
9fe17bd3
GT
982table = new wxDbTable(db, tableName, numTableColumns, "",
983 !wxDB_QUERY_ONLY, "");
b25ba5b7
GT
984
985//
2564094b 986// Bind the columns that you wish to retrieve. Note that there must be
b25ba5b7
GT
987// 'numTableColumns' calls to SetColDefs(), to match the wxDbTable definition
988//
989// Not all columns need to be bound, only columns whose values are to be
990// returned back to the client.
991//
992table->SetColDefs(0, "FIRST_NAME", DB_DATA_TYPE_VARCHAR, FirstName,
993 SQL_C_CHAR, sizeof(name), TRUE, TRUE);
994table->SetColDefs(1, "LAST_NAME", DB_DATA_TYPE_VARCHAR, LastName,
995 SQL_C_CHAR, sizeof(LastName), TRUE, TRUE);
996
997// Open the table for access
998table->Open();
999
1000// Set the WHERE clause to limit the result set to only
1001// return all rows that have a value of 'GEORGE' in the
1002// FIRST_NAME column of the table.
1003table->SetWhereClause("FIRST_NAME = 'GEORGE'");
1004
1005// Result set will be sorted in ascending alphabetical
1006// order on the data in the 'LAST_NAME' column of each row
1007table->SetOrderByClause("LAST_NAME");
1008
1009// No other tables (joins) are used for this query
1010table->SetFromClause("");
1011
1012// Instruct the datasource to perform a query based on the
1013// criteria specified above in the where/orderBy/from clauses.
1014if (!table->Query())
1015{
1016 wxMessageBox("Error on Query()","ERROR!",
1017 wxOK | wxICON_EXCLAMATION);
1018 errorOccured = TRUE;
1019}
1020
1021wxString msg;
1022
1023// Start and continue reading every record in the table
1024// displaying info about each record read.
1025while (table->GetNext())
1026{
1027 msg.Printf("Row #%lu -- First Name : %s Last Name is %s",
1028 table->GetRowNum(), FirstName, LastName);
1029 wxMessageBox(msg, "Data", wxOK | wxICON_INFORMATION, NULL);
1030}
1031
1032// If the wxDbTable instance was successfully created
1033// then delete it as I am done with it now.
1034if (table)
1035{
1036 delete table;
1037 table = NULL;
1038}
1039
1040// If we have a valid wxDb instance, then free the connection
1041// (meaning release it back in to the cache of datasource
1042// connections) for the next time a call to wxDbGetConnection()
1043// is made.
1044if (db)
1045{
1046 wxDbFreeConnection(db);
1047 db = NULL;
1048}
1049
1050// The program is now ending, so we need to close
1051// any cached connections that are still being
1052// maintained.
1053wxDbCloseConnections();
1054
1055// Release the environment handle that was created
1056// for use with the ODBC datasource connections
9fe17bd3 1057delete DbConnectInf;
b25ba5b7
GT
1058
1059\end{verbatim}
1060
a98f98ac 1061\subsection{wxDatabase ODBC class overview [DEPRECATED]}\label{oldwxodbcoverview}
b25ba5b7 1062
a660d684
KB
1063Classes: \helpref{wxDatabase}{wxdatabase}, \helpref{wxRecordSet}{wxrecordset}, \helpref{wxQueryCol}{wxquerycol},
1064\rtfsp\helpref{wxQueryField}{wxqueryfield}
1065
b25ba5b7 1066\normalboxd{The more sophisticated wxODBC classes (wxDb/wxDbTable) are the
2564094b 1067recommended classes for doing database/ODBC work with wxWindows. These new
b25ba5b7
GT
1068classes replace the wxWindows v1.6x classes wxDatabase.
1069
1070Documentation for the old wxDatabase class and its associated classes is still
1071included in the class documentation and in this overview section, but support
1072for these old classes has been phased out, and all future development work
1073is being done solely on the new wxDb/wxDbTable classes.}
a660d684
KB
1074
1075wxWindows provides a set of classes for accessing a subset of Microsoft's ODBC (Open Database Connectivity)
1076product. Currently, this wrapper is available under MS Windows only, although
1077ODBC may appear on other platforms, and a generic or product-specific SQL emulator for the ODBC
1078classes may be provided in wxWindows at a later date.
1079
1080ODBC presents a unified API (Application Programmer's Interface) to a
1081wide variety of databases, by interfacing indirectly to each database or
1082file via an ODBC driver. The language for most of the database
1083operations is SQL, so you need to learn a small amount of SQL as well as
1084the wxWindows ODBC wrapper API. Even though the databases may not be
1085SQL-based, the ODBC drivers translate SQL into appropriate operations
f6bcfd97 1086for the database or file: even text files have rudimentary ODBC support,
a660d684
KB
1087along with dBASE, Access, Excel and other file formats.
1088
1089The run-time files for ODBC are bundled with many existing database
1090packages, including MS Office. The required header files, sql.h and
1091sqlext.h, are bundled with several compilers including MS VC++ and
1092Watcom C++. The only other way to obtain these header files is from the
1093ODBC SDK, which is only available with the MS Developer Network CD-ROMs
1094-- at great expense. If you have odbc.dll, you can make the required
1095import library odbc.lib using the tool `implib'. You need to have odbc.lib
1096in your compiler library path.
1097
1098The minimum you need to distribute with your application is odbc.dll, which must
1099go in the Windows system directory. For the application to function correctly,
1100ODBC drivers must be installed on the user's machine. If you do not use the database
1101classes, odbc.dll will be loaded but not called (so ODBC does not need to be
1102setup fully if no ODBC calls will be made).
1103
1104A sample is distributed with wxWindows in {\tt samples/odbc}. You will need to install
1105the sample dbf file as a data source using the ODBC setup utility, available from
1106the control panel if ODBC has been fully installed.
1107
b25ba5b7 1108\subsection{Procedures for writing an ODBC application using wxDatabase [DEPRECATED]}
a660d684
KB
1109
1110You first need to create a wxDatabase object. If you want to get information
1111from the ODBC manager instead of from a particular database (for example
1112using \helpref{wxRecordSet::GetDataSources}{wxrecordsetgetdatasources}), then you
1113do not need to call \helpref{wxDatabase::Open}{wxdatabaseopen}.
1114If you do wish to connect to a datasource, then call wxDatabase::Open.
1115You can reuse your wxDatabase object, calling wxDatabase::Close and wxDatabase::Open
1116multiple times.
1117
1118Then, create a wxRecordSet object for retrieving or sending information.
1119For ODBC manager information retrieval, you can create it as a dynaset (retrieve the
1120information as needed) or a snapshot (get all the data at once).
1121If you are going to call \helpref{wxRecordSet::ExecuteSQL}{wxrecordsetexecutesql}, you need to create it as a snapshot.
1122Dynaset mode is not yet implemented for user data.
1123
1124Having called a function such as wxRecordSet::ExecuteSQL or
1125wxRecordSet::GetDataSources, you may have a number of records
1126associated with the recordset, if appropriate to the operation. You can
1127now retrieve information such as the number of records retrieved and the
1128actual data itself. Use \helpref{wxRecordSet::GetFieldData}{wxrecordsetgetfielddata} or
1129\helpref{wxRecordSet::GetFieldDataPtr}{wxrecordsetgetfielddataptr} to get the data or a pointer to it, passing
1130a column index or name. The data returned will be for the current
1131record. To move around the records, use \helpref{wxRecordSet::MoveNext}{wxrecordsetmovenext},
1132\rtfsp\helpref{wxRecordSet::MovePrev}{wxrecordsetmoveprev} and associated functions.
1133
1134You can use the same recordset for multiple operations, or delete
1135the recordset and create a new one.
1136
1137Note that when you delete a wxDatabase, any associated recordsets
1138also get deleted, so beware of holding onto invalid pointers.
1139
b25ba5b7
GT
1140\subsection{wxDatabase class overview [DEPRECATED]}\label{wxdatabaseoverview}
1141
1142Class: \helpref{wxDatabase}{wxdatabase}
a660d684 1143
b25ba5b7
GT
1144\wxheading{DEPRECATED}
1145
1146Use \helpref{wxDb}{wxdb} and \helpref{wxDbTable}{wxdbtable} instead.
a660d684
KB
1147
1148Every database object represents an ODBC connection. To do anything useful
1149with a database object you need to bind a wxRecordSet object to it. All you
1150can do with wxDatabase is opening/closing connections and getting some info
1151about it (users, passwords, and so on).
1152
fa482912 1153\wxheading{See also}
a660d684 1154
fa482912
JS
1155\helpref{Database classes overview}{odbcoverview}
1156
b25ba5b7 1157\subsection{wxQueryCol class overview [DEPRECATED]}\label{wxquerycoloverview}
a660d684
KB
1158
1159Class: \helpref{wxQueryCol}{wxquerycol}
1160
b25ba5b7
GT
1161\wxheading{DEPRECATED}
1162
1163Use \helpref{wxDb}{wxdb} and \helpref{wxDbTable}{wxdbtable} instead.
1164
a660d684
KB
1165Every data column is represented by an instance of this class.
1166It contains the name and type of a column and a list of wxQueryFields where
1167the real data is stored. The links to user-defined variables are stored
1168here, as well.
1169
fa482912 1170\wxheading{See also}
a660d684 1171
fa482912
JS
1172\helpref{Database classes overview}{odbcoverview}
1173
b25ba5b7 1174\subsection{wxQueryField class overview [DEPRECATED]}\label{wxqueryfieldoverview}
a660d684
KB
1175
1176Class: \helpref{wxQueryField}{wxqueryfield}
1177
b25ba5b7
GT
1178\wxheading{DEPRECATED}
1179
1180Use \helpref{wxDb}{wxdb} and \helpref{wxDbTable}{wxdbtable} instead.
1181
a660d684
KB
1182As every data column is represented by an instance of the class wxQueryCol,
1183every data item of a specific column is represented by an instance of
1184wxQueryField. Each column contains a list of wxQueryFields. If wxRecordSet is
1185of the type wxOPEN\_TYPE\_DYNASET, there will be only one field for each column,
1186which will be updated every time you call functions like wxRecordSet::Move
1187or wxRecordSet::GoTo. If wxRecordSet is of the type wxOPEN\_TYPE\_SNAPSHOT,
1188all data returned by an ODBC function will be loaded at once and the number
1189of wxQueryField instances for each column will depend on the number of records.
1190
fa482912 1191\wxheading{See also}
a660d684 1192
fa482912
JS
1193\helpref{Database classes overview}{odbcoverview}
1194
b25ba5b7 1195\subsection{wxRecordSet overview [DEPRECATED]}\label{wxrecordsetoverview}
a660d684
KB
1196
1197Class: \helpref{wxRecordSet}{wxrecordset}
1198
b25ba5b7
GT
1199\wxheading{DEPRECATED}
1200
1201Use \helpref{wxDb}{wxdb} and \helpref{wxDbTable}{wxdbtable} instead.
1202
a660d684
KB
1203Each wxRecordSet represents a database query. You can make multiple queries
1204at a time by using multiple wxRecordSets with a wxDatabase or you can make
1205your queries in sequential order using the same wxRecordSet.
1206
fa482912
JS
1207\wxheading{See also}
1208
1209\helpref{Database classes overview}{odbcoverview}
a660d684 1210
b25ba5b7 1211\subsection{ODBC SQL data types [DEPRECATED]}\label{sqltypes}
a660d684
KB
1212
1213These are the data types supported in ODBC SQL. Note that there are other, extended level conformance
1214types, not currently supported in wxWindows.
1215
1216\begin{twocollist}\itemsep=0pt
1217\twocolitem{CHAR(n)}{A character string of fixed length {\it n}.}
1218\twocolitem{VARCHAR(n)}{A varying length character string of maximum length {\it n}.}
1219\twocolitem{LONG VARCHAR(n)}{A varying length character string: equivalent to VARCHAR for the purposes
1220of ODBC.}
1221\twocolitem{DECIMAL(p, s)}{An exact numeric of precision {\it p} and scale {\it s}.}
1222\twocolitem{NUMERIC(p, s)}{Same as DECIMAL.}
1223\twocolitem{SMALLINT}{A 2 byte integer.}
1224\twocolitem{INTEGER}{A 4 byte integer.}
1225\twocolitem{REAL}{A 4 byte floating point number.}
1226\twocolitem{FLOAT}{An 8 byte floating point number.}
1227\twocolitem{DOUBLE PRECISION}{Same as FLOAT.}
1228\end{twocollist}
1229
1230These data types correspond to the following ODBC identifiers:
1231
1232\begin{twocollist}\itemsep=0pt
1233\twocolitem{SQL\_CHAR}{A character string of fixed length.}
1234\twocolitem{SQL\_VARCHAR}{A varying length character string.}
1235\twocolitem{SQL\_DECIMAL}{An exact numeric.}
1236\twocolitem{SQL\_NUMERIC}{Same as SQL\_DECIMAL.}
1237\twocolitem{SQL\_SMALLINT}{A 2 byte integer.}
1238\twocolitem{SQL\_INTEGER}{A 4 byte integer.}
1239\twocolitem{SQL\_REAL}{A 4 byte floating point number.}
1240\twocolitem{SQL\_FLOAT}{An 8 byte floating point number.}
1241\twocolitem{SQL\_DOUBLE}{Same as SQL\_FLOAT.}
1242\end{twocollist}
1243
fa482912
JS
1244\wxheading{See also}
1245
1246\helpref{Database classes overview}{odbcoverview}
a660d684 1247
b25ba5b7 1248\subsection{A selection of SQL commands [DEPRECATED]}\label{sqlcommands}
a660d684
KB
1249
1250The following is a very brief description of some common SQL commands, with
1251examples.
1252
fa482912
JS
1253\wxheading{See also}
1254
1255\helpref{Database classes overview}{odbcoverview}
1256
a660d684
KB
1257\subsubsection{Create}
1258
1259Creates a table.
1260
1261Example:
1262
1263\begin{verbatim}
1264CREATE TABLE Book
1265 (BookNumber INTEGER PRIMARY KEY
1266 , CategoryCode CHAR(2) DEFAULT 'RO' NOT NULL
1267 , Title VARCHAR(100) UNIQUE
1268 , NumberOfPages SMALLINT
1269 , RetailPriceAmount NUMERIC(5,2)
1270 )
1271\end{verbatim}
1272
1273\subsubsection{Insert}
1274
1275Inserts records into a table.
1276
1277Example:
1278
1279\begin{verbatim}
1280INSERT INTO Book
1281 (BookNumber, CategoryCode, Title)
1282 VALUES(5, 'HR', 'The Lark Ascending')
1283\end{verbatim}
1284
1285\subsubsection{Select}
1286
1287The Select operation retrieves rows and columns from a table. The criteria
1288for selection and the columns returned may be specified.
1289
1290Examples:
1291
7af3ca16 1292{\tt SELECT * FROM Book}
a660d684
KB
1293
1294Selects all rows and columns from table Book.
1295
7af3ca16 1296{\tt SELECT Title, RetailPriceAmount FROM Book WHERE RetailPriceAmount > 20.0}
a660d684
KB
1297
1298Selects columns Title and RetailPriceAmount from table Book, returning only
1299the rows that match the WHERE clause.
1300
7af3ca16 1301{\tt SELECT * FROM Book WHERE CatCode = 'LL' OR CatCode = 'RR'}
a660d684
KB
1302
1303Selects all columns from table Book, returning only
1304the rows that match the WHERE clause.
1305
7af3ca16 1306{\tt SELECT * FROM Book WHERE CatCode IS NULL}
a660d684
KB
1307
1308Selects all columns from table Book, returning only rows where the CatCode column
1309is NULL.
1310
7af3ca16 1311{\tt SELECT * FROM Book ORDER BY Title}
a660d684
KB
1312
1313Selects all columns from table Book, ordering by Title, in ascending order. To specify
1314descending order, add DESC after the ORDER BY Title clause.
1315
7af3ca16 1316{\tt SELECT Title FROM Book WHERE RetailPriceAmount >= 20.0 AND RetailPriceAmount <= 35.0}
a660d684
KB
1317
1318Selects records where RetailPriceAmount conforms to the WHERE expression.
1319
1320\subsubsection{Update}
1321
1322Updates records in a table.
1323
1324Example:
1325
7af3ca16 1326{\tt UPDATE Incident SET X = 123 WHERE ASSET = 'BD34'}
a660d684
KB
1327
1328This example sets a field in column `X' to the number 123, for the record
1329where the column ASSET has the value `BD34'.
1330