There are no available options for this view.

Parent Directory Parent Directory | Revision <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Log">Log</a> Revision <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Log">Log</a>

Revision 1.2 - (show annotations) (download) (as text)
Sun Jun 20 15:54:01 2004 UTC (7 years, 11 months ago) by seryakov
Branch: MAIN
CVS Tags: aolserver_v45_r0, HEAD
Branch point for: aolserver_v45_r1, aolserver_v45_r2, aolserver_v45_bp
Changes since 1.1: +2 -1 lines
File MIME type: text/x-chdr
<a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbSelect">Ns_DbSelect</a> changed to allow propagate errors from low-level drivers instead of
returning "Query was not a statement returning rows" all the time.
1 /*
2 * The contents of this file are subject to the AOLserver Public License
3 * Version 1.1 (the "License"); you may not use this file except in
4 * compliance with the License. You may obtain a copy of the License at
5 * http://aolserver.com/.
6 *
7 * Software distributed under the License is distributed on an "AS IS"
8 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
9 * the License for the specific language governing rights and limitations
10 * under the License.
11 *
12 * The Original Code is AOLserver Code and related documentation
13 * distributed by AOL.
14 *
15 * The Initial Developer of the Original Code is America Online,
16 * Inc. Portions created by AOL are Copyright (C) 1999 America Online,
17 * Inc. All Rights Reserved.
18 *
19 * Alternatively, the contents of this file may be used under the terms
20 * of the GNU General Public License (the "GPL"), in which case the
21 * provisions of GPL are applicable instead of those above. If you wish
22 * to allow use of your version of this file only under the terms of the
23 * GPL and not to allow others to use your version of this file under the
24 * License, indicate your decision by deleting the provisions above and
25 * replace them with the notice and other provisions required by the GPL.
26 * If you do not delete the provisions above, a recipient may use your
27 * version of this file under either the License or the GPL.
28 */
29
30
31 /*
32 * dbdrv.c --
33 *
34 * Routines for handling the loadable db driver interface.
35 */
36
37 static const char *RCSID = "@(#) $Header: /cvsroot-fuse/aolserver/aolserver/nsdb/dbdrv.c,v 1.2 2004/06/20 15:54:01 seryakov Exp $, compiled: " __DATE__ " " __TIME__;
38
39 #include "db.h"
40
41 /*
42 * The following typedefs define the functions provided by
43 * loadable drivers.
44 */
45
46 typedef int (InitProc) (char *server, char *module, char *driver);
47 typedef char *(NameProc) (Ns_DbHandle *);
48 typedef char *(TypeProc) (Ns_DbHandle *);
49 typedef int (OpenProc) (Ns_DbHandle *);
50 typedef void (CloseProc) (Ns_DbHandle *);
51 typedef int (DMLProc) (Ns_DbHandle *, char *sql);
52 typedef Ns_Set *(SelectProc) (Ns_DbHandle *, char *sql);
53 typedef int (<a href="/cvs/aolserver/aolserver/nsd/exec.c#A_ExecProc">ExecProc</a>) (Ns_DbHandle *, char *sql);
54 typedef Ns_Set *(BindProc) (Ns_DbHandle *);
55 typedef int (GetProc) (Ns_DbHandle *, Ns_Set *);
56 typedef int (FlushProc) (Ns_DbHandle *);
57 typedef int (CancelProc) (Ns_DbHandle *);
58 typedef int (ResetProc) (Ns_DbHandle *);
59 typedef int (SpStartProc) (Ns_DbHandle *handle, char *procname);
60 typedef int (SpSetParamProc) (Ns_DbHandle *handle, char *args);
61 typedef int (SpExecProc) (Ns_DbHandle *handle);
62 typedef int (SpReturnCodeProc) (Ns_DbHandle *dbhandle, char *returnCode,
63 int bufsize);
64 typedef Ns_Set *(SpGetParamsProc) (Ns_DbHandle *handle);
65
66 /*
67 * The following structure specifies the driver-specific functions
68 * to call for each Ns_Db routine.
69 */
70
71 typedef struct DbDriver {
72 char *name;
73 int registered;
74 InitProc *initProc;
75 NameProc *nameProc;
76 TypeProc *typeProc;
77 OpenProc *openProc;
78 CloseProc *closeProc;
79 DMLProc *dmlProc;
80 SelectProc *selectProc;
81 <a href="/cvs/aolserver/aolserver/nsd/exec.c#A_ExecProc">ExecProc</a> *execProc;
82 BindProc *bindProc;
83 GetProc *getProc;
84 FlushProc *flushProc;
85 CancelProc *cancelProc;
86 ResetProc *resetProc;
87 SpStartProc *spstartProc;
88 SpSetParamProc *spsetparamProc;
89 SpExecProc *spexecProc;
90 SpReturnCodeProc *spreturncodeProc;
91 SpGetParamsProc *spgetparamsProc;
92 } DbDriver;
93
94 /*
95 * Static variables defined in this file
96 */
97
98 static Tcl_HashTable driversTable;
99
100
101 /*
102 *----------------------------------------------------------------------
103 *
104 * <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbRegisterDriver">Ns_DbRegisterDriver</a> --
105 *
106 * Register db procs for a driver. This routine is called by
107 * driver modules when loaded.
108 *
109 * Results:
110 * NS_OK if procs registered, NS_ERROR otherwise.
111 *
112 * Side effects:
113 * Driver structure is allocated and function pointers are set
114 * to the given array of procs.
115 *
116 *----------------------------------------------------------------------
117 */
118
119 static void
120 <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_UnsupProcId">UnsupProcId</a>(char *name)
121 {
122 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Warning, "dbdrv: unsupported function id '%s'", name);
123 }
124
125 int
126 <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbRegisterDriver">Ns_DbRegisterDriver</a>(char *driver, Ns_DbProc *procs)
127 {
128 Tcl_HashEntry *hPtr;
129 DbDriver *driverPtr = NULL;
130
131 hPtr = Tcl_FindHashEntry(&driversTable, driver);
132 if (hPtr == NULL) {
133 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Error, "dbdrv: no such driver '%s'", driver);
134 return NS_ERROR;
135 }
136 driverPtr = (DbDriver *) Tcl_GetHashValue(hPtr);
137 if (driverPtr->registered) {
138 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Error, "dbdrv: a driver is already registered as '%s'",
139 driver);
140 return NS_ERROR;
141 }
142 driverPtr->registered = 1;
143
144 while (procs->func != NULL) {
145 switch (procs->id) {
146 case DbFn_ServerInit:
147 driverPtr->initProc = (InitProc *) procs->func;
148 break;
149 case DbFn_Name:
150 driverPtr->nameProc = (NameProc *) procs->func;
151 break;
152 case DbFn_DbType:
153 driverPtr->typeProc = (TypeProc *) procs->func;
154 break;
155 case DbFn_OpenDb:
156 driverPtr->openProc = (OpenProc *) procs->func;
157 break;
158 case DbFn_CloseDb:
159 driverPtr->closeProc = (CloseProc *) procs->func;
160 break;
161 case DbFn_DML:
162 driverPtr->dmlProc = (DMLProc *) procs->func;
163 break;
164 case DbFn_Select:
165 driverPtr->selectProc = (SelectProc *) procs->func;
166 break;
167 case DbFn_GetRow:
168 driverPtr->getProc = (GetProc *) procs->func;
169 break;
170 case DbFn_Flush:
171 driverPtr->flushProc = (FlushProc *) procs->func;
172 break;
173 case DbFn_Cancel:
174 driverPtr->cancelProc = (CancelProc *) procs->func;
175 break;
176 case DbFn_Exec:
177 driverPtr->execProc = (<a href="/cvs/aolserver/aolserver/nsd/exec.c#A_ExecProc">ExecProc</a> *) procs->func;
178 break;
179 case DbFn_BindRow:
180 driverPtr->bindProc = (BindProc *) procs->func;
181 break;
182 case DbFn_ResetHandle:
183 driverPtr->resetProc = (ResetProc *) procs->func;
184 break;
185
186 case DbFn_SpStart:
187 driverPtr->spstartProc = (SpStartProc *) procs->func;
188 break;
189
190 case DbFn_SpSetParam:
191 driverPtr->spsetparamProc = (SpSetParamProc *) procs->func;
192 break;
193
194 case DbFn_SpExec:
195 driverPtr->spexecProc = (SpExecProc *) procs->func;
196 break;
197
198 case DbFn_SpReturnCode:
199 driverPtr->spreturncodeProc = (SpReturnCodeProc *) procs->func;
200 break;
201
202 case DbFn_SpGetParams:
203 driverPtr->spgetparamsProc = (SpGetParamsProc *) procs->func;
204 break;
205
206 /*
207 * The following functions are no longer supported.
208 */
209
210 case DbFn_End:
211 <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_UnsupProcId">UnsupProcId</a>("End");
212 break;
213
214 case DbFn_GetTableInfo:
215 <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_UnsupProcId">UnsupProcId</a>("GetTableInfo");
216 break;
217
218 case DbFn_TableList:
219 <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_UnsupProcId">UnsupProcId</a>("TableList");
220 break;
221
222 case DbFn_BestRowId:
223 <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_UnsupProcId">UnsupProcId</a>("BestRowId");
224 break;
225
226 default:
227 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Error, "dbdrv: unknown driver id '%d'", procs->id);
228 return NS_ERROR;
229 break;
230 }
231 ++procs;
232 }
233
234 return NS_OK;
235 }
236
237
238 /*
239 *----------------------------------------------------------------------
240 *
241 * <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbDriverName">Ns_DbDriverName</a> --
242 *
243 * Return the string name of the driver.
244 *
245 * Results:
246 * String name.
247 *
248 * Side effects:
249 * None.
250 *
251 *----------------------------------------------------------------------
252 */
253
254 char *
255 <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbDriverName">Ns_DbDriverName</a>(Ns_DbHandle *handle)
256 {
257 DbDriver *driverPtr = <a href="/cvs/aolserver/aolserver/nsdb/dbinit.c#A_NsDbGetDriver">NsDbGetDriver</a>(handle);
258 char *name = NULL;
259
260 if (driverPtr != NULL && driverPtr->nameProc != NULL) {
261
262 name = (*driverPtr->nameProc)(handle);
263 }
264
265 return name;
266 }
267
268
269 /*
270 *----------------------------------------------------------------------
271 *
272 * Ns_DbDriverType --
273 *
274 * Return the string name of the database type (e.g., "sybase").
275 *
276 * Results:
277 * String name.
278 *
279 * Side effects:
280 * None.
281 *
282 *----------------------------------------------------------------------
283 */
284
285 char *
286 <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbDriverDbType">Ns_DbDriverDbType</a>(Ns_DbHandle *handle)
287 {
288 DbDriver *driverPtr = <a href="/cvs/aolserver/aolserver/nsdb/dbinit.c#A_NsDbGetDriver">NsDbGetDriver</a>(handle);
289
290 if (driverPtr == NULL ||
291 driverPtr->typeProc == NULL ||
292 handle->connected == NS_FALSE) {
293
294 return NULL;
295 }
296
297 return (*driverPtr->typeProc)(handle);
298 }
299
300
301 /*
302 *----------------------------------------------------------------------
303 *
304 * <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbDML">Ns_DbDML</a> --
305 *
306 * Execute an SQL statement which is expected to be DML.
307 *
308 * Results:
309 * NS_OK or NS_ERROR.
310 *
311 * Side effects:
312 * SQL is sent to database for evaluation.
313 *
314 *----------------------------------------------------------------------
315 */
316
317 int
318 <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbDML">Ns_DbDML</a>(Ns_DbHandle *handle, char *sql)
319 {
320 DbDriver *driverPtr = <a href="/cvs/aolserver/aolserver/nsdb/dbinit.c#A_NsDbGetDriver">NsDbGetDriver</a>(handle);
321 int status = NS_ERROR;
322
323 if (driverPtr != NULL && handle->connected) {
324
325 if (driverPtr->execProc != NULL) {
326 status = <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbExec">Ns_DbExec</a>(handle, sql);
327 if (status == NS_DML) {
328 status = NS_OK;
329 } else {
330 if (status == NS_ROWS) {
331 <a href="/cvs/aolserver/aolserver/nsdb/dbutil.c#A_Ns_DbSetException">Ns_DbSetException</a>(handle, "NSDB",
332 "Query was not a DML or DDL command.");
333 <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbFlush">Ns_DbFlush</a>(handle);
334 }
335 status = NS_ERROR;
336 }
337 } else if (driverPtr->dmlProc != NULL) {
338 status = (*driverPtr->dmlProc)(handle, sql);
339 <a href="/cvs/aolserver/aolserver/nsdb/dbinit.c#A_NsDbLogSql">NsDbLogSql</a>(handle, sql);
340 }
341 }
342
343 return status;
344 }
345
346
347 /*
348 *----------------------------------------------------------------------
349 *
350 * <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbSelect">Ns_DbSelect</a> --
351 *
352 * Execute an SQL statement which is expected to return rows.
353 *
354 * Results:
355 * Pointer to Ns_Set of selected columns or NULL on error.
356 *
357 * Side effects:
358 * SQL is sent to database for evaluation.
359 *
360 *----------------------------------------------------------------------
361 */
362
363 Ns_Set *
364 <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbSelect">Ns_DbSelect</a>(Ns_DbHandle *handle, char *sql)
365 {
366 DbDriver *driverPtr = <a href="/cvs/aolserver/aolserver/nsdb/dbinit.c#A_NsDbGetDriver">NsDbGetDriver</a>(handle);
367 Ns_Set *setPtr = NULL;
368
369 if (driverPtr != NULL && handle->connected) {
370
371 if (driverPtr->execProc != NULL) {
372 if (<a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbExec">Ns_DbExec</a>(handle, sql) == NS_ROWS) {
373 setPtr = <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbBindRow">Ns_DbBindRow</a>(handle);
374 } else {
375 if(!handle->dsExceptionMsg.length)
376 <a href="/cvs/aolserver/aolserver/nsdb/dbutil.c#A_Ns_DbSetException">Ns_DbSetException</a>(handle, "NSDB",
377 "Query was not a statement returning rows.");
378 }
379 } else if (driverPtr->selectProc != NULL) {
380 <a href="/cvs/aolserver/aolserver/nsd/set.c#A_Ns_SetTrunc">Ns_SetTrunc</a>(handle->row, 0);
381 setPtr = (*driverPtr->selectProc)(handle, sql);
382 <a href="/cvs/aolserver/aolserver/nsdb/dbinit.c#A_NsDbLogSql">NsDbLogSql</a>(handle, sql);
383 }
384 }
385
386 return setPtr;
387 }
388
389
390 /*
391 *----------------------------------------------------------------------
392 *
393 * <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbExec">Ns_DbExec</a> --
394 *
395 * Execute an SQL statement.
396 *
397 * Results:
398 * NS_DML, NS_ROWS, or NS_ERROR.
399 *
400 * Side effects:
401 * SQL is sent to database for evaluation.
402 *
403 *----------------------------------------------------------------------
404 */
405
406 int
407 <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbExec">Ns_DbExec</a>(Ns_DbHandle *handle, char *sql)
408 {
409 DbDriver *driverPtr = <a href="/cvs/aolserver/aolserver/nsdb/dbinit.c#A_NsDbGetDriver">NsDbGetDriver</a>(handle);
410 int status = NS_ERROR;
411
412 if (handle->connected &&
413 driverPtr != NULL &&
414 driverPtr->execProc != NULL) {
415
416 status = (*driverPtr->execProc)(handle, sql);
417 <a href="/cvs/aolserver/aolserver/nsdb/dbinit.c#A_NsDbLogSql">NsDbLogSql</a>(handle, sql);
418 }
419
420 return status;
421 }
422
423
424 /*
425 *----------------------------------------------------------------------
426 *
427 * <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbBindRow">Ns_DbBindRow</a> --
428 *
429 * Bind the column names from a pending result set. This routine
430 * is normally called right after an <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbExec">Ns_DbExec</a> if the result
431 * was NS_ROWS.
432 *
433 * Results:
434 * Pointer to Ns_Set.
435 *
436 * Side effects:
437 * Column names of result rows are set in the Ns_Set.
438 *
439 *----------------------------------------------------------------------
440 */
441
442 Ns_Set *
443 <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbBindRow">Ns_DbBindRow</a>(Ns_DbHandle *handle)
444 {
445 DbDriver *driverPtr = <a href="/cvs/aolserver/aolserver/nsdb/dbinit.c#A_NsDbGetDriver">NsDbGetDriver</a>(handle);
446 Ns_Set *setPtr = NULL;
447
448 if (handle->connected &&
449 driverPtr != NULL &&
450 driverPtr->bindProc != NULL) {
451
452 <a href="/cvs/aolserver/aolserver/nsd/set.c#A_Ns_SetTrunc">Ns_SetTrunc</a>(handle->row, 0);
453 setPtr = (*driverPtr->bindProc)(handle);
454 }
455
456 return setPtr;
457 }
458
459
460 /*
461 *----------------------------------------------------------------------
462 *
463 * <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbGetRow">Ns_DbGetRow</a> --
464 *
465 * Fetch the next row waiting in a result set. This routine
466 * is normally called repeatedly after an <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbSelect">Ns_DbSelect</a> or
467 * an <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbExec">Ns_DbExec</a> and <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbBindRow">Ns_DbBindRow</a>.
468 *
469 * Results:
470 * NS_END_DATA if there are no more rows, NS_OK or NS_ERROR
471 * otherwise.
472 *
473 * Side effects:
474 * The values of the given set are filled in with those of the
475 * next row.
476 *
477 *----------------------------------------------------------------------
478 */
479 int
480 <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbGetRow">Ns_DbGetRow</a>(Ns_DbHandle *handle, Ns_Set *row)
481 {
482 DbDriver *driverPtr = <a href="/cvs/aolserver/aolserver/nsdb/dbinit.c#A_NsDbGetDriver">NsDbGetDriver</a>(handle);
483 int status = NS_ERROR;
484
485 if (handle->connected &&
486 driverPtr != NULL &&
487 driverPtr->getProc != NULL) {
488
489 status = (*driverPtr->getProc)(handle, row);
490 }
491
492 return status;
493 }
494
495
496 /*
497 *----------------------------------------------------------------------
498 *
499 * <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbFlush">Ns_DbFlush</a> --
500 *
501 * Flush rows pending in a result set.
502 *
503 * Results:
504 * NS_OK or NS_ERROR.
505 *
506 * Side effects:
507 * Rows waiting in the result set are dumped, perhaps by simply
508 * fetching them over one by one.
509 *
510 *----------------------------------------------------------------------
511 */
512
513 int
514 <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbFlush">Ns_DbFlush</a>(Ns_DbHandle *handle)
515 {
516 DbDriver *driverPtr = <a href="/cvs/aolserver/aolserver/nsdb/dbinit.c#A_NsDbGetDriver">NsDbGetDriver</a>(handle);
517 int status = NS_ERROR;
518
519 if (handle->connected &&
520 driverPtr != NULL &&
521 driverPtr->flushProc != NULL) {
522
523 status = (*driverPtr->flushProc)(handle);
524 }
525
526 return status;
527 }
528
529
530 /*
531 *----------------------------------------------------------------------
532 *
533 * <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbCancel">Ns_DbCancel</a> --
534 *
535 * Cancel the execution of a select and dump pending rows.
536 *
537 * Results:
538 * NS_OK or NS_ERROR.
539 *
540 * Side effects:
541 * Depending on the driver, a running select call which executes
542 * as rows are fetched may be interrupted.
543 *
544 *----------------------------------------------------------------------
545 */
546
547 int
548 <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbCancel">Ns_DbCancel</a>(Ns_DbHandle *handle)
549 {
550 DbDriver *driverPtr = <a href="/cvs/aolserver/aolserver/nsdb/dbinit.c#A_NsDbGetDriver">NsDbGetDriver</a>(handle);
551 int status = NS_ERROR;
552
553 if (handle->connected &&
554 driverPtr != NULL &&
555 driverPtr->cancelProc != NULL) {
556
557 status = (*driverPtr->cancelProc)(handle);
558 }
559
560 return status;
561 }
562
563
564 /*
565 *----------------------------------------------------------------------
566 *
567 * <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbResetHandle">Ns_DbResetHandle</a> --
568 *
569 * Reset a handle after a cancel operation.
570 *
571 * Results:
572 * NS_OK or NS_ERROR.
573 *
574 * Side effects:
575 * Handle is available for new commands.
576 *
577 *----------------------------------------------------------------------
578 */
579
580 int
581 <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbResetHandle">Ns_DbResetHandle</a> (Ns_DbHandle *handle)
582 {
583 DbDriver *driverPtr = <a href="/cvs/aolserver/aolserver/nsdb/dbinit.c#A_NsDbGetDriver">NsDbGetDriver</a>(handle);
584 int status = NS_ERROR;
585
586 if (handle->connected &&
587 driverPtr != NULL &&
588 driverPtr->resetProc != NULL) {
589
590 status = (*driverPtr->resetProc)(handle);
591 }
592
593 return status;
594 }
595
596
597 /*
598 *----------------------------------------------------------------------
599 *
600 * <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_NsDbLoadDriver">NsDbLoadDriver</a> --
601 *
602 * Load a database driver for one or more pools.
603 *
604 * Results:
605 * Pointer to driver structure or NULL on error.
606 *
607 * Side effects:
608 * Driver module file may be mapped into the process.
609 *
610 *----------------------------------------------------------------------
611 */
612
613 struct DbDriver *
614 <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_NsDbLoadDriver">NsDbLoadDriver</a>(char *driver)
615 {
616 Tcl_HashEntry *hPtr;
617 char *module, *path;
618 int new;
619 DbDriver *driverPtr;
620 static int initialized = NS_FALSE;
621
622 if (initialized == NS_FALSE) {
623 Tcl_InitHashTable(&driversTable, TCL_STRING_KEYS);
624 initialized = NS_TRUE;
625 }
626
627 hPtr = Tcl_CreateHashEntry(&driversTable, driver, &new);
628 if (new == 0) {
629 driverPtr = (DbDriver *) Tcl_GetHashValue(hPtr);
630 } else {
631 driverPtr = ns_malloc(sizeof(DbDriver));
632 memset(driverPtr, 0, sizeof(DbDriver));
633 driverPtr->name = Tcl_GetHashKey(&driversTable, hPtr);
634 Tcl_SetHashValue(hPtr, driverPtr);
635 module = <a href="/cvs/aolserver/aolserver/nsd/config.c#A_Ns_ConfigGetValue">Ns_ConfigGetValue</a>("ns/db/drivers", driver);
636 if (module == NULL) {
637 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Error, "dbdrv: no such driver '%s'", driver);
638 } else {
639 path = <a href="/cvs/aolserver/aolserver/nsd/config.c#A_Ns_ConfigGetPath">Ns_ConfigGetPath</a>(NULL, NULL, "db", "driver", driver, NULL);
640 if (<a href="/cvs/aolserver/aolserver/nsd/modload.c#A_Ns_ModuleLoad">Ns_ModuleLoad</a>(driver, path, module, "<a href="/cvs/aolserver/nsodbc/nsodbc.c#A_Ns_DbDriverInit">Ns_DbDriverInit</a>")
641 != NS_OK) {
642 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Error, "dbdrv: failed to load driver '%s'",
643 driver);
644 }
645 }
646 }
647 if (driverPtr->registered == 0) {
648 return NULL;
649 }
650
651 return driverPtr;
652 }
653
654
655 /*
656 *----------------------------------------------------------------------
657 *
658 * NsDbServerInit --
659 *
660 * Invoke driver provided server init proc (e.g., to add driver
661 * specific Tcl commands).
662 *
663 * Results:
664 * None.
665 *
666 * Side effects:
667 * None.
668 *
669 *----------------------------------------------------------------------
670 */
671
672 void
673 <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_NsDbDriverInit">NsDbDriverInit</a>(char *server, DbDriver *driverPtr)
674 {
675 if (driverPtr->initProc != NULL &&
676 ((*driverPtr->initProc) (server, "db", driverPtr->name)) != NS_OK) {
677
678 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Warning, "dbdrv: init proc failed for driver '%s'",
679 driverPtr->name);
680 }
681 }
682
683
684 /*
685 *----------------------------------------------------------------------
686 *
687 * <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_NsDbOpen">NsDbOpen</a> --
688 *
689 * Open a connection to the database. This routine is called
690 * from the pool routines in dbinit.c.
691 *
692 * Results:
693 * NS_OK or NS_ERROR.
694 *
695 * Side effects:
696 * Database may be connected by driver specific routine.
697 *
698 *----------------------------------------------------------------------
699 */
700
701 int
702 <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_NsDbOpen">NsDbOpen</a>(Ns_DbHandle *handle)
703 {
704 DbDriver *driverPtr = <a href="/cvs/aolserver/aolserver/nsdb/dbinit.c#A_NsDbGetDriver">NsDbGetDriver</a>(handle);
705
706 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Notice, "dbdrv: opening database '%s:%s'", handle->driver,
707 handle->datasource);
708 if (driverPtr == NULL ||
709 driverPtr->openProc == NULL ||
710 (*driverPtr->openProc) (handle) != NS_OK) {
711
712 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Error, "dbdrv: failed to open database '%s:%s'",
713 handle->driver, handle->datasource);
714 handle->connected = NS_FALSE;
715 return NS_ERROR;
716 }
717
718 return NS_OK;
719 }
720
721
722 /*
723 *----------------------------------------------------------------------
724 *
725 * <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_NsDbClose">NsDbClose</a> --
726 *
727 * Close a connection to the database. This routine is called
728 * from the pool routines in dbinit.c
729 *
730 * Results:
731 * None.
732 *
733 * Side effects:
734 * None.
735 *
736 *----------------------------------------------------------------------
737 */
738
739 void
740 <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_NsDbClose">NsDbClose</a>(Ns_DbHandle *handle)
741 {
742 DbDriver *driverPtr = <a href="/cvs/aolserver/aolserver/nsdb/dbinit.c#A_NsDbGetDriver">NsDbGetDriver</a>(handle);
743
744 if (handle->connected &&
745 driverPtr != NULL &&
746 driverPtr->closeProc != NULL) {
747
748 (*driverPtr->closeProc)(handle);
749 }
750 }
751
752
753 /*
754 *----------------------------------------------------------------------
755 *
756 * <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbSpStart">Ns_DbSpStart</a> --
757 *
758 * Start execution of a stored procedure.
759 *
760 * Results:
761 * NS_OK/NS_ERROR.
762 *
763 * Side effects:
764 * Begins an SP; see <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbSpExec">Ns_DbSpExec</a>.
765 *
766 *----------------------------------------------------------------------
767 */
768
769 int
770 <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbSpStart">Ns_DbSpStart</a>(Ns_DbHandle *handle, char *procname)
771 {
772 DbDriver *driverPtr = <a href="/cvs/aolserver/aolserver/nsdb/dbinit.c#A_NsDbGetDriver">NsDbGetDriver</a>(handle);
773 int status = NS_ERROR;
774
775 if (handle->connected &&
776 driverPtr != NULL &&
777 driverPtr->spstartProc != NULL) {
778
779 status = (*driverPtr->spstartProc)(handle, procname);
780 }
781
782 return status;
783 }
784
785
786 /*
787 *----------------------------------------------------------------------
788 *
789 * <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbSpSetParam">Ns_DbSpSetParam</a> --
790 *
791 * Set a parameter in a store procedure; must have executed
792 * <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbSpStart">Ns_DbSpStart</a> first. paramname looks like "@x", paramtype is
793 * like "int" or "varchar", inout is "in" or "out", value is
794 * like "123".
795 *
796 * Results:
797 * NS_OK/NS_ERROR
798 *
799 * Side effects:
800 * None.
801 *
802 *----------------------------------------------------------------------
803 */
804
805 int
806 <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbSpSetParam">Ns_DbSpSetParam</a>(Ns_DbHandle *handle, char *paramname, char *paramtype,
807 char *inout, char *value)
808 {
809 DbDriver *driverPtr = <a href="/cvs/aolserver/aolserver/nsdb/dbinit.c#A_NsDbGetDriver">NsDbGetDriver</a>(handle);
810 int status = NS_ERROR;
811 Ns_DString args;
812
813 if (handle->connected &&
814 driverPtr != NULL &&
815 driverPtr->spsetparamProc != NULL) {
816
817 <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringInit">Ns_DStringInit</a>(&args);
818 <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringVarAppend">Ns_DStringVarAppend</a>(&args, paramname, " ", paramtype, " ", inout, " ",
819 value, NULL);
820 status = (*driverPtr->spsetparamProc)(handle, args.string);
821 <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringFree">Ns_DStringFree</a>(&args);
822 }
823
824 return status;
825 }
826
827
828 /*
829 *----------------------------------------------------------------------
830 *
831 * <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbSpExec">Ns_DbSpExec</a> --
832 *
833 * Run an Sp begun with <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbSpStart">Ns_DbSpStart</a>
834 *
835 * Results:
836 * NS_OK/NS_ERROR
837 *
838 * Side effects:
839 * None.
840 *
841 *----------------------------------------------------------------------
842 */
843
844 int
845 <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbSpExec">Ns_DbSpExec</a>(Ns_DbHandle *handle)
846 {
847 DbDriver *driverPtr = <a href="/cvs/aolserver/aolserver/nsdb/dbinit.c#A_NsDbGetDriver">NsDbGetDriver</a>(handle);
848 int status = NS_ERROR;
849
850 if (handle->connected &&
851 driverPtr != NULL &&
852 driverPtr->spexecProc != NULL) {
853
854 status = (*driverPtr->spexecProc)(handle);
855 }
856
857 return status;
858 }
859
860
861 /*
862 *----------------------------------------------------------------------
863 *
864 * <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbSpReturnCode">Ns_DbSpReturnCode</a> --
865 *
866 * Get the return code from an SP after <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbSpExec">Ns_DbSpExec</a>
867 *
868 * Results:
869 * NS_OK/NSERROR
870 *
871 * Side effects:
872 * The return code is put into the passed-in buffer, which must
873 * be at least bufsize in length.
874 *
875 *----------------------------------------------------------------------
876 */
877
878 int
879 <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbSpReturnCode">Ns_DbSpReturnCode</a>(Ns_DbHandle *handle, char *returnCode, int bufsize)
880 {
881 DbDriver *driverPtr = <a href="/cvs/aolserver/aolserver/nsdb/dbinit.c#A_NsDbGetDriver">NsDbGetDriver</a>(handle);
882 int status = NS_ERROR;
883
884 if (handle->connected &&
885 driverPtr != NULL &&
886 driverPtr->spreturncodeProc != NULL) {
887
888 status = (*driverPtr->spreturncodeProc)(handle, returnCode, bufsize);
889 }
890
891 return status;
892 }
893
894
895 /*
896 *----------------------------------------------------------------------
897 *
898 * <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbSpGetParams">Ns_DbSpGetParams</a> --
899 *
900 * Get output parameters after running an SP w/ <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbSpExec">Ns_DbSpExec</a>.
901 *
902 * Results:
903 * NULL or a newly allocated set with output params in it.
904 *
905 * Side effects:
906 * Allocs its return value and its members.
907 *
908 *----------------------------------------------------------------------
909 */
910
911 Ns_Set *
912 <a href="/cvs/aolserver/aolserver/nsdb/dbdrv.c#A_Ns_DbSpGetParams">Ns_DbSpGetParams</a>(Ns_DbHandle *handle)
913 {
914 DbDriver *driverPtr = <a href="/cvs/aolserver/aolserver/nsdb/dbinit.c#A_NsDbGetDriver">NsDbGetDriver</a>(handle);
915 Ns_Set *aset = NULL;
916
917 <a href="/cvs/aolserver/aolserver/nsd/set.c#A_Ns_SetTrunc">Ns_SetTrunc</a>(handle->row, 0);
918 if (handle->connected &&
919 driverPtr != NULL &&
920 driverPtr->spgetparamsProc != NULL) {
921
922 aset = (*driverPtr->spgetparamsProc)(handle);
923 }
924
925 return aset;
926 }