~ubuntu-branches/ubuntu/quantal/wxwidgets2.8/quantal

« back to all changes in this revision

Viewing changes to src/iodbc/connect.c

  • Committer: Package Import Robot
  • Author(s): Stéphane Graber
  • Date: 2012-01-07 13:59:25 UTC
  • mfrom: (1.1.9) (5.1.10 sid)
  • Revision ID: package-import@ubuntu.com-20120107135925-2601miy9ullcon9j
Tags: 2.8.12.1-6ubuntu1
* Resync from Debian, changes that were kept:
  - debian/rules: re-enable mediactrl. This allows libwx_gtk2u_media-2.8 to be
    built, as this is required by some applications (LP: #632984)
  - debian/control: Build-dep on libxt-dev for mediactrl.
  - Patches
    + fix-bashism-in-example
* Add conflict on python-wxgtk2.8 (<< 2.8.12.1-6ubuntu1~) to python-wxversion
  to guarantee upgrade ordering when moving from pycentral to dh_python2.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *  connect.c
3
 
 *
4
 
 *  $Id: connect.c 5545 2000-01-20 13:19:20Z GT $
5
 
 *
6
 
 *  Connect (load) driver
7
 
 *
8
 
 *  The iODBC driver manager.
9
 
 *  
10
 
 *  Copyright (C) 1995 by Ke Jin <kejin@empress.com> 
11
 
 *
12
 
 *  This library is free software; you can redistribute it and/or
13
 
 *  modify it under the terms of the GNU Library General Public
14
 
 *  License as published by the Free Software Foundation; either
15
 
 *  version 2 of the License, or (at your option) any later version.
16
 
 *
17
 
 *  This library is distributed in the hope that it will be useful,
18
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20
 
 *  Library General Public License for more details.
21
 
 *
22
 
 *  You should have received a copy of the GNU Library General Public
23
 
 *  License along with this library; if not, write to the Free
24
 
 *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
 
 */
26
 
 
27
 
#include        "config.h"
28
 
 
29
 
#include        "isql.h"
30
 
#include        "isqlext.h"
31
 
 
32
 
#include        "dlproc.h"
33
 
 
34
 
#include        "herr.h"
35
 
#include        "henv.h"
36
 
#include        "hdbc.h"
37
 
#include        "hstmt.h"
38
 
 
39
 
#include        "itrace.h"
40
 
 
41
 
extern  char*   _iodbcdm_getkeyvalbydsn();
42
 
extern  char*   _iodbcdm_getkeyvalinstr();
43
 
extern  RETCODE _iodbcdm_driverunload();
44
 
 
45
 
/*
46
 
 *   Following id string is a copyright mark. Removing(i.e. use 
47
 
 *   souce code of this package without it or make it not appear 
48
 
 *   in the final object file) or modifing it without permission 
49
 
 *   from original author(kejin@empress.com) are copyright 
50
 
 *   violation.
51
 
 */
52
 
static  char sccsid[] 
53
 
        = "@(#)iODBC driver manager 2.5, Copyright(c) 1995 by Ke Jin";
54
 
 
55
 
/* - Load driver share library( or increase its reference count 
56
 
 *   if it has already been loaded by another active connection)
57
 
 * - Call driver's SQLAllocEnv() (for the first reference only)
58
 
 * - Call driver's SQLAllocConnect()
59
 
 * - Call driver's SQLSetConnectOption() (set login time out)
60
 
 * - Increase the bookkeeping reference count
61
 
 */
62
 
static RETCODE 
63
 
_iodbcdm_driverload (
64
 
    char FAR * path,
65
 
    HDBC hdbc)
66
 
{
67
 
  DBC_t FAR *pdbc = (DBC_t FAR *) hdbc;
68
 
  GENV_t FAR *genv;
69
 
  ENV_t FAR *penv = NULL;
70
 
  HDLL hdll;
71
 
  HPROC hproc;
72
 
  RETCODE retcode = SQL_SUCCESS;
73
 
  int sqlstat = en_00000;
74
 
 
75
 
  if (path == NULL || path[0] == '\0')
76
 
    {
77
 
      PUSHSQLERR (pdbc->herr, en_IM002);
78
 
 
79
 
      return SQL_ERROR;
80
 
    }
81
 
 
82
 
  if (hdbc == SQL_NULL_HDBC || pdbc->genv == SQL_NULL_HENV)
83
 
    {
84
 
      return SQL_INVALID_HANDLE;
85
 
    }
86
 
 
87
 
  genv = (GENV_t FAR *) pdbc->genv;
88
 
 
89
 
  /* This will either load the driver dll or increase its reference count */
90
 
  hdll = _iodbcdm_dllopen ((char FAR *) path);
91
 
 
92
 
  if (hdll == SQL_NULL_HDLL)
93
 
    {
94
 
      PUSHSYSERR (pdbc->herr, _iodbcdm_dllerror ());
95
 
      PUSHSQLERR (pdbc->herr, en_IM003);
96
 
      return SQL_ERROR;
97
 
    }
98
 
 
99
 
  penv = (ENV_t FAR *) (pdbc->henv);
100
 
 
101
 
  if (penv != NULL)
102
 
    {
103
 
      if (penv->hdll != hdll)
104
 
        {
105
 
          _iodbcdm_driverunload (hdbc);
106
 
        }
107
 
      else
108
 
        {
109
 
          /* 
110
 
           * this will not unload the driver but only decrease its internal
111
 
           * reference count 
112
 
           */
113
 
          _iodbcdm_dllclose (hdll);
114
 
        }
115
 
    }
116
 
 
117
 
  if (penv == NULL)
118
 
    {
119
 
      /* 
120
 
       * find out whether this dll has already been loaded on another 
121
 
       * connection 
122
 
       */
123
 
      for (penv = (ENV_t FAR *) genv->henv; 
124
 
          penv != NULL;
125
 
          penv = (ENV_t FAR *) penv->next)
126
 
        {
127
 
          if (penv->hdll == hdll)
128
 
            {
129
 
              /* 
130
 
               * this will not unload the driver but only decrease its internal
131
 
               * reference count 
132
 
               */
133
 
              _iodbcdm_dllclose (hdll);
134
 
              break;
135
 
            }
136
 
        }
137
 
 
138
 
      if (penv == NULL)
139
 
        /* no connection attaching with this dll */
140
 
        {
141
 
          int i;
142
 
 
143
 
          /* create a new dll env instance */
144
 
          penv = (ENV_t FAR *) MEM_ALLOC (sizeof (ENV_t));
145
 
 
146
 
          if (penv == NULL)
147
 
            {
148
 
              _iodbcdm_dllclose (hdll);
149
 
 
150
 
              PUSHSQLERR (pdbc->herr, en_S1001);
151
 
 
152
 
              return SQL_ERROR;
153
 
            }
154
 
 
155
 
          for (i = 0; i < SQL_EXT_API_LAST + 1; i++)
156
 
            {
157
 
              (penv->dllproc_tab)[i] = SQL_NULL_HPROC;
158
 
            }
159
 
 
160
 
          pdbc->henv = penv;
161
 
          penv->hdll = hdll;
162
 
 
163
 
          /* call driver's SQLAllocHandle() or SQLAllocEnv() */
164
 
 
165
 
#if (ODBCVER >= 0x0300)
166
 
          hproc = _iodbcdm_getproc (hdbc, en_AllocHandle);
167
 
 
168
 
          if (hproc)
169
 
            {
170
 
              CALL_DRIVER (hdbc, retcode, hproc, en_AllocHandle,
171
 
                  (SQL_HANDLE_ENV, SQL_NULL_HANDLE, &(penv->dhenv)))
172
 
            }
173
 
          else                  /* try driver's SQLAllocEnv() */
174
 
#endif
175
 
            {
176
 
              hproc = _iodbcdm_getproc (hdbc, en_AllocEnv);
177
 
 
178
 
              if (hproc == SQL_NULL_HPROC)
179
 
                {
180
 
                  sqlstat = en_IM004;
181
 
                }
182
 
              else
183
 
                {
184
 
                  CALL_DRIVER (hdbc, retcode, hproc,
185
 
                      en_AllocEnv, (&(penv->dhenv)))
186
 
                }
187
 
            }
188
 
 
189
 
          if (retcode == SQL_ERROR)
190
 
            {
191
 
              sqlstat = en_IM004;
192
 
            }
193
 
 
194
 
          if (sqlstat != en_00000)
195
 
            {
196
 
              _iodbcdm_dllclose (hdll);
197
 
              MEM_FREE (penv);
198
 
              PUSHSQLERR (pdbc->herr, en_IM004);
199
 
 
200
 
              return SQL_ERROR;
201
 
            }
202
 
 
203
 
          /* insert into dll env list */
204
 
          penv->next = (ENV_t FAR *) genv->henv;
205
 
          genv->henv = penv;
206
 
 
207
 
          /* initiate this new env entry */
208
 
          penv->refcount = 0;   /* we will increase it after
209
 
                                 * driver's SQLAllocConnect()
210
 
                                 * success
211
 
                                 */
212
 
        }
213
 
 
214
 
      pdbc->henv = penv;
215
 
 
216
 
      if (pdbc->dhdbc == SQL_NULL_HDBC)
217
 
        {
218
 
 
219
 
#if (ODBCVER >= 0x0300)
220
 
          hproc = _iodbcdm_getproc (hdbc, en_AllocHandle);
221
 
 
222
 
          if (hproc)
223
 
            {
224
 
              CALL_DRIVER (hdbc, retcode, hproc, en_AllocHandle,
225
 
                  (SQL_HANDLE_DBC, penv->dhenv, &(pdbc->dhdbc)))
226
 
            }
227
 
          else
228
 
#endif
229
 
 
230
 
            {
231
 
              hproc = _iodbcdm_getproc (hdbc, en_AllocConnect);
232
 
 
233
 
              if (hproc == SQL_NULL_HPROC)
234
 
                {
235
 
                  sqlstat = en_IM005;
236
 
                }
237
 
              else
238
 
                {
239
 
                  CALL_DRIVER (hdbc, retcode, hproc,
240
 
                      en_AllocConnect, (penv->dhenv, &(pdbc->dhdbc)))
241
 
                }
242
 
            }
243
 
 
244
 
          if (retcode == SQL_ERROR)
245
 
            {
246
 
              sqlstat = en_IM005;
247
 
            }
248
 
 
249
 
          if (sqlstat != en_00000)
250
 
            {
251
 
              _iodbcdm_driverunload (hdbc);
252
 
 
253
 
              pdbc->dhdbc = SQL_NULL_HDBC;
254
 
              PUSHSQLERR (pdbc->herr, en_IM005);
255
 
 
256
 
              return SQL_ERROR;
257
 
            }
258
 
        }
259
 
 
260
 
      pdbc->henv = penv;
261
 
      penv->refcount++;         /* bookkeeping reference count on this driver */
262
 
    }
263
 
 
264
 
  /* driver's login timeout option must been set before 
265
 
   * its SQLConnect() call */
266
 
  if (pdbc->login_timeout != 0UL)
267
 
    {
268
 
      hproc = _iodbcdm_getproc (hdbc, en_SetConnectOption);
269
 
 
270
 
      if (hproc == SQL_NULL_HPROC)
271
 
        {
272
 
          sqlstat = en_IM004;
273
 
        }
274
 
      else
275
 
        {
276
 
          CALL_DRIVER (hdbc, retcode, hproc,
277
 
              en_SetConnectOption, (
278
 
                  pdbc->dhdbc,
279
 
                  SQL_LOGIN_TIMEOUT,
280
 
                  pdbc->login_timeout))
281
 
 
282
 
              if (retcode == SQL_ERROR)
283
 
            {
284
 
              PUSHSQLERR (pdbc->herr, en_IM006);
285
 
 
286
 
              return SQL_SUCCESS_WITH_INFO;
287
 
            }
288
 
        }
289
 
    }
290
 
 
291
 
  return SQL_SUCCESS;
292
 
}
293
 
 
294
 
 
295
 
/* - Call driver's SQLFreeConnect()
296
 
 * - Call driver's SQLFreeEnv() ( for the last reference only)
297
 
 * - Unload the share library( or decrease its reference
298
 
 *   count if it is not the last referenct )
299
 
 * - decrease bookkeeping reference count
300
 
 * - state transition to allocated
301
 
 */
302
 
RETCODE 
303
 
_iodbcdm_driverunload (HDBC hdbc)
304
 
{
305
 
  DBC_t FAR *pdbc = (DBC_t FAR *) hdbc;
306
 
  ENV_t FAR *penv;
307
 
  ENV_t FAR *tpenv;
308
 
  GENV_t FAR *genv;
309
 
  HPROC hproc;
310
 
  RETCODE retcode = SQL_SUCCESS;
311
 
 
312
 
  if (hdbc == SQL_NULL_HDBC)
313
 
    {
314
 
      return SQL_INVALID_HANDLE;
315
 
    }
316
 
 
317
 
  /* no pointer check will be performed in this function */
318
 
  penv = (ENV_t FAR *) pdbc->henv;
319
 
  genv = (GENV_t FAR *) pdbc->genv;
320
 
 
321
 
  if (penv == NULL || penv->hdll == SQL_NULL_HDLL)
322
 
    {
323
 
      return SQL_SUCCESS;
324
 
    }
325
 
 
326
 
#if (ODBCVER >= 0x0300)
327
 
  hproc = _iodbcdm_getproc (hdbc, en_FreeHandle);
328
 
 
329
 
  if (hproc)
330
 
    {
331
 
      CALL_DRIVER (hdbc, retcode, hproc, en_FreeHandle,
332
 
          (SQL_HANDLE_DBC, pdbc->dhdbc))
333
 
    }
334
 
  else
335
 
#endif
336
 
 
337
 
    {
338
 
      hproc = _iodbcdm_getproc (hdbc, en_FreeConnect);
339
 
 
340
 
      if (hproc != SQL_NULL_HPROC)
341
 
        {
342
 
          CALL_DRIVER (hdbc, retcode, hproc,
343
 
              en_FreeConnect, (pdbc->dhdbc))
344
 
 
345
 
              pdbc->dhdbc = SQL_NULL_HDBC;
346
 
        }
347
 
    }
348
 
 
349
 
  penv->refcount--;
350
 
 
351
 
  if (!penv->refcount)
352
 
    /* no other connections still attaching with this driver */
353
 
    {
354
 
 
355
 
#if (ODBCVER >= 0x0300)
356
 
      hproc = _iodbcdm_getproc (hdbc, en_FreeHandle);
357
 
 
358
 
      if (hproc)
359
 
        {
360
 
          CALL_DRIVER (hdbc, retcode, hproc, en_FreeHandle,
361
 
              (SQL_HANDLE_ENV, penv->dhenv))
362
 
        }
363
 
      else
364
 
#endif
365
 
 
366
 
        {
367
 
          hproc = _iodbcdm_getproc (hdbc, en_FreeEnv);
368
 
 
369
 
          if (hproc != SQL_NULL_HPROC)
370
 
            {
371
 
              CALL_DRIVER (hdbc, retcode, hproc, en_FreeEnv,
372
 
                  (penv->dhenv))
373
 
 
374
 
                  penv->dhenv = SQL_NULL_HENV;
375
 
            }
376
 
        }
377
 
 
378
 
      _iodbcdm_dllclose (penv->hdll);
379
 
 
380
 
      penv->hdll = SQL_NULL_HDLL;
381
 
 
382
 
      for (tpenv = (ENV_t FAR *) genv->henv;
383
 
          tpenv != NULL;
384
 
          tpenv = (ENV_t FAR *) penv->next)
385
 
        {
386
 
          if (tpenv == penv)
387
 
            {
388
 
              genv->henv = penv->next;
389
 
              break;
390
 
            }
391
 
 
392
 
          if (tpenv->next == penv)
393
 
            {
394
 
              tpenv->next = penv->next;
395
 
              break;
396
 
            }
397
 
        }
398
 
 
399
 
      MEM_FREE (penv);
400
 
    }
401
 
 
402
 
  pdbc->henv = SQL_NULL_HENV;
403
 
  pdbc->hstmt = SQL_NULL_HSTMT;
404
 
  /* pdbc->herr = SQL_NULL_HERR; 
405
 
     -- delay to DM's SQLFreeConnect() */
406
 
  pdbc->dhdbc = SQL_NULL_HDBC;
407
 
  pdbc->state = en_dbc_allocated;
408
 
 
409
 
  /* set connect options to default values */
410
 
        /**********
411
 
        pdbc->access_mode       = SQL_MODE_DEFAULT;
412
 
        pdbc->autocommit        = SQL_AUTOCOMMIT_DEFAULT;
413
 
        pdbc->login_timeout     = 0UL;
414
 
        **********/
415
 
  pdbc->odbc_cursors = SQL_CUR_DEFAULT;
416
 
  pdbc->packet_size = 0UL;
417
 
  pdbc->quiet_mode = (UDWORD) NULL;
418
 
  pdbc->txn_isolation = SQL_TXN_READ_UNCOMMITTED;
419
 
 
420
 
  if (pdbc->current_qualifier != NULL)
421
 
    {
422
 
      MEM_FREE (pdbc->current_qualifier);
423
 
      pdbc->current_qualifier = NULL;
424
 
    }
425
 
 
426
 
  return SQL_SUCCESS;
427
 
}
428
 
 
429
 
 
430
 
static RETCODE 
431
 
_iodbcdm_dbcdelayset (HDBC hdbc)
432
 
{
433
 
  DBC_t FAR *pdbc = (DBC_t FAR *) hdbc;
434
 
  ENV_t FAR *penv;
435
 
  HPROC hproc;
436
 
  RETCODE retcode = SQL_SUCCESS;
437
 
  RETCODE ret;
438
 
 
439
 
  penv = pdbc->henv;
440
 
 
441
 
  hproc = _iodbcdm_getproc (hdbc, en_SetConnectOption);
442
 
 
443
 
  if (hproc == SQL_NULL_HPROC)
444
 
    {
445
 
      PUSHSQLERR (pdbc->herr, en_IM006);
446
 
 
447
 
      return SQL_SUCCESS_WITH_INFO;
448
 
    }
449
 
 
450
 
  if (pdbc->access_mode != SQL_MODE_DEFAULT)
451
 
    {
452
 
      CALL_DRIVER (hdbc, ret, hproc,
453
 
          en_SetConnectOption, (
454
 
              SQL_ACCESS_MODE,
455
 
              pdbc->access_mode))
456
 
 
457
 
          retcode |= ret;
458
 
    }
459
 
 
460
 
  if (pdbc->autocommit != SQL_AUTOCOMMIT_DEFAULT)
461
 
    {
462
 
      CALL_DRIVER (hdbc, ret, hproc,
463
 
          en_SetConnectOption, (
464
 
              pdbc->dhdbc,
465
 
              SQL_AUTOCOMMIT,
466
 
              pdbc->autocommit))
467
 
 
468
 
          retcode |= ret;
469
 
    }
470
 
 
471
 
  if (pdbc->current_qualifier != NULL)
472
 
    {
473
 
      CALL_DRIVER (hdbc, ret, hproc,
474
 
          en_SetConnectOption, (
475
 
              pdbc->dhdbc,
476
 
              SQL_CURRENT_QUALIFIER,
477
 
              pdbc->current_qualifier))
478
 
 
479
 
          retcode |= ret;
480
 
    }
481
 
 
482
 
  if (pdbc->packet_size != 0UL)
483
 
    {
484
 
      CALL_DRIVER (hdbc, ret, hproc,
485
 
          en_SetConnectOption, (
486
 
              pdbc->dhdbc,
487
 
              SQL_PACKET_SIZE,
488
 
              pdbc->packet_size))
489
 
 
490
 
          retcode |= ret;
491
 
    }
492
 
 
493
 
  if (pdbc->quiet_mode != (UDWORD) NULL)
494
 
    {
495
 
      CALL_DRIVER (hdbc, ret, hproc,
496
 
          en_SetConnectOption, (
497
 
              pdbc->dhdbc,
498
 
              SQL_QUIET_MODE,
499
 
              pdbc->quiet_mode))
500
 
 
501
 
          retcode |= ret;
502
 
    }
503
 
 
504
 
  if (pdbc->txn_isolation != SQL_TXN_READ_UNCOMMITTED)
505
 
    {
506
 
      CALL_DRIVER (hdbc, ret, hproc,
507
 
          en_SetConnectOption, (
508
 
              pdbc->dhdbc,
509
 
              SQL_TXN_ISOLATION,
510
 
              pdbc->txn_isolation))
511
 
    }
512
 
 
513
 
  /* check error code for driver's SQLSetConnectOption() call */
514
 
  if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
515
 
    {
516
 
      PUSHSQLERR (pdbc->herr, en_IM006);
517
 
 
518
 
      retcode = SQL_ERROR;
519
 
    }
520
 
 
521
 
  /* get cursor behavior on transaction commit or rollback */
522
 
  hproc = _iodbcdm_getproc (hdbc, en_GetInfo);
523
 
 
524
 
  if (hproc == SQL_NULL_HPROC)
525
 
    {
526
 
      PUSHSQLERR (pdbc->herr, en_01000);
527
 
 
528
 
      return retcode;
529
 
    }
530
 
 
531
 
  CALL_DRIVER (hdbc, ret, hproc,
532
 
      en_GetInfo, (
533
 
          pdbc->dhdbc,
534
 
          SQL_CURSOR_COMMIT_BEHAVIOR,
535
 
          (PTR) & (pdbc->cb_commit),
536
 
          sizeof (pdbc->cb_commit),
537
 
          NULL))
538
 
 
539
 
      retcode |= ret;
540
 
 
541
 
  CALL_DRIVER (hdbc, ret, hproc,
542
 
      en_GetInfo, (
543
 
          pdbc->dhdbc,
544
 
          SQL_CURSOR_ROLLBACK_BEHAVIOR,
545
 
          (PTR) & (pdbc->cb_rollback),
546
 
          sizeof (pdbc->cb_rollback),
547
 
          NULL))
548
 
 
549
 
      retcode |= ret;
550
 
 
551
 
  if (retcode != SQL_SUCCESS
552
 
      && retcode != SQL_SUCCESS_WITH_INFO)
553
 
    {
554
 
      return SQL_ERROR;
555
 
    }
556
 
 
557
 
  return retcode;
558
 
}
559
 
 
560
 
 
561
 
static RETCODE 
562
 
_iodbcdm_settracing (HDBC hdbc, char *dsn, int dsnlen)
563
 
{
564
 
  char buf[256];
565
 
  char *ptr;
566
 
  RETCODE setopterr = SQL_SUCCESS;
567
 
 
568
 
  /* Get Driver's DLL path from specificed or default dsn section */
569
 
  ptr = _iodbcdm_getkeyvalbydsn (dsn, dsnlen, "TraceFile",
570
 
      (char FAR *) buf, sizeof (buf));
571
 
 
572
 
  if (ptr == NULL || ptr[0] == '\0')
573
 
    {
574
 
      ptr = (char FAR *) (SQL_OPT_TRACE_FILE_DEFAULT);
575
 
    }
576
 
 
577
 
  setopterr |= SQLSetConnectOption (hdbc, SQL_OPT_TRACEFILE, (UDWORD) (ptr));
578
 
 
579
 
  ptr = _iodbcdm_getkeyvalbydsn (dsn, dsnlen, "Trace",
580
 
      (char FAR *) buf, sizeof (buf));
581
 
 
582
 
  if (ptr != NULL)
583
 
    {
584
 
      UDWORD opt = (UDWORD) (-1L);
585
 
 
586
 
      if (STREQ (ptr, "ON")
587
 
          || STREQ (ptr, "On")
588
 
          || STREQ (ptr, "on")
589
 
          || STREQ (ptr, "1"))
590
 
        {
591
 
          opt = SQL_OPT_TRACE_ON;
592
 
        }
593
 
 
594
 
      if (STREQ (ptr, "OFF")
595
 
          || STREQ (ptr, "Off")
596
 
          || STREQ (ptr, "off")
597
 
          || STREQ (ptr, "0"))
598
 
        {
599
 
          opt = SQL_OPT_TRACE_OFF;
600
 
        }
601
 
 
602
 
      if (opt != (UDWORD) (-1L))
603
 
        {
604
 
          setopterr |= SQLSetConnectOption (hdbc,
605
 
              SQL_OPT_TRACE, opt);
606
 
        }
607
 
    }
608
 
 
609
 
  return setopterr;
610
 
}
611
 
 
612
 
 
613
 
RETCODE SQL_API 
614
 
SQLConnect (
615
 
    HDBC hdbc,
616
 
    UCHAR FAR * szDSN,
617
 
    SWORD cbDSN,
618
 
    UCHAR FAR * szUID,
619
 
    SWORD cbUID,
620
 
    UCHAR FAR * szAuthStr,
621
 
    SWORD cbAuthStr)
622
 
{
623
 
  DBC_t FAR *pdbc = (DBC_t FAR *) hdbc;
624
 
  RETCODE retcode = SQL_SUCCESS;
625
 
  RETCODE setopterr = SQL_SUCCESS;
626
 
  char driver[1024] = {'\0'};   /* MS SDK Guide 
627
 
                                 * specifies driver
628
 
                                 * path can't longer
629
 
                                 * than 255. */
630
 
  char *ptr;
631
 
  HPROC hproc;
632
 
 
633
 
  if (hdbc == SQL_NULL_HDBC)
634
 
    {
635
 
      return SQL_INVALID_HANDLE;
636
 
    }
637
 
 
638
 
  /* check arguments */
639
 
  if ((cbDSN < 0 && cbDSN != SQL_NTS)
640
 
      || (cbUID < 0 && cbUID != SQL_NTS)
641
 
      || (cbAuthStr < 0 && cbAuthStr != SQL_NTS)
642
 
      || (cbDSN > SQL_MAX_DSN_LENGTH))
643
 
    {
644
 
      PUSHSQLERR (pdbc->herr, en_S1090);
645
 
 
646
 
      return SQL_ERROR;
647
 
    }
648
 
 
649
 
  if (szDSN == NULL || cbDSN == 0)
650
 
    {
651
 
      PUSHSQLERR (pdbc->herr, en_IM002);
652
 
 
653
 
      return SQL_ERROR;
654
 
    }
655
 
 
656
 
  /* check state */
657
 
  if (pdbc->state != en_dbc_allocated)
658
 
    {
659
 
      PUSHSQLERR (pdbc->herr, en_08002);
660
 
 
661
 
      return SQL_ERROR;
662
 
    }
663
 
 
664
 
  setopterr |= _iodbcdm_settracing (hdbc,
665
 
      (char *) szDSN, cbDSN);
666
 
 
667
 
  ptr = _iodbcdm_getkeyvalbydsn (szDSN, cbDSN, "Driver",
668
 
      (char FAR *) driver, sizeof (driver));
669
 
 
670
 
  if (ptr == NULL)
671
 
    /* No specified or default dsn section or
672
 
     * no driver specification in this dsn section */
673
 
    {
674
 
      PUSHSQLERR (pdbc->herr, en_IM002);
675
 
 
676
 
      return SQL_ERROR;
677
 
    }
678
 
 
679
 
  retcode = _iodbcdm_driverload (driver, hdbc);
680
 
 
681
 
  switch (retcode)
682
 
     {
683
 
     case SQL_SUCCESS:
684
 
       break;
685
 
 
686
 
     case SQL_SUCCESS_WITH_INFO:
687
 
       setopterr = SQL_ERROR;
688
 
       /* unsuccessed in calling driver's 
689
 
        * SQLSetConnectOption() to set login
690
 
        * timeout.
691
 
        */
692
 
       break;
693
 
 
694
 
     default:
695
 
       return retcode;
696
 
     }
697
 
 
698
 
  hproc = _iodbcdm_getproc (hdbc, en_Connect);
699
 
 
700
 
  if (hproc == SQL_NULL_HPROC)
701
 
    {
702
 
      _iodbcdm_driverunload (hdbc);
703
 
 
704
 
      PUSHSQLERR (pdbc->herr, en_IM001);
705
 
 
706
 
      return SQL_ERROR;
707
 
    }
708
 
 
709
 
  CALL_DRIVER (hdbc, retcode, hproc, en_Connect, (
710
 
          pdbc->dhdbc,
711
 
          szDSN, cbDSN,
712
 
          szUID, cbUID,
713
 
          szAuthStr, cbAuthStr))
714
 
 
715
 
  if (retcode != SQL_SUCCESS
716
 
      && retcode != SQL_SUCCESS_WITH_INFO)
717
 
    {
718
 
      /* not unload driver for retrive error 
719
 
       * messge from driver */
720
 
                /*********
721
 
                _iodbcdm_driverunload( hdbc );
722
 
                **********/
723
 
 
724
 
      return retcode;
725
 
    }
726
 
 
727
 
  /* state transition */
728
 
  pdbc->state = en_dbc_connected;
729
 
 
730
 
  /* do delaid option setting */
731
 
  setopterr |= _iodbcdm_dbcdelayset (hdbc);
732
 
 
733
 
  if (setopterr != SQL_SUCCESS)
734
 
    {
735
 
      return SQL_SUCCESS_WITH_INFO;
736
 
    }
737
 
 
738
 
  return retcode;
739
 
}
740
 
 
741
 
 
742
 
RETCODE SQL_API 
743
 
SQLDriverConnect (
744
 
    HDBC hdbc,
745
 
    SQLHWND hwnd,
746
 
    UCHAR FAR * szConnStrIn,
747
 
    SWORD cbConnStrIn,
748
 
    UCHAR FAR * szConnStrOut,
749
 
    SWORD cbConnStrOutMax,
750
 
    SWORD FAR * pcbConnStrOut,
751
 
    UWORD fDriverCompletion)
752
 
{
753
 
  DBC_t FAR *pdbc = (DBC_t FAR *) hdbc;
754
 
  HDLL hdll;
755
 
  char FAR *drv;
756
 
  char drvbuf[1024];
757
 
  char FAR *dsn;
758
 
  char dsnbuf[SQL_MAX_DSN_LENGTH + 1];
759
 
  UCHAR cnstr2drv[1024];
760
 
 
761
 
  HPROC hproc;
762
 
  HPROC dialproc;
763
 
 
764
 
  int sqlstat = en_00000;
765
 
  RETCODE retcode = SQL_SUCCESS;
766
 
  RETCODE setopterr = SQL_SUCCESS;
767
 
 
768
 
  if (hdbc == SQL_NULL_HDBC)
769
 
    {
770
 
      return SQL_INVALID_HANDLE;
771
 
    }
772
 
 
773
 
  /* check arguments */
774
 
  if ((cbConnStrIn < 0 && cbConnStrIn != SQL_NTS)
775
 
      || cbConnStrOutMax < 0)
776
 
    {
777
 
      PUSHSQLERR (pdbc->herr, en_S1090);
778
 
 
779
 
      return SQL_ERROR;
780
 
    }
781
 
 
782
 
  /* check state */
783
 
  if (pdbc->state != en_dbc_allocated)
784
 
    {
785
 
      PUSHSQLERR (pdbc->herr, en_08002);
786
 
 
787
 
      return SQL_ERROR;
788
 
    }
789
 
 
790
 
  drv = _iodbcdm_getkeyvalinstr (szConnStrIn, cbConnStrIn,
791
 
      "DRIVER", drvbuf, sizeof (drvbuf));
792
 
 
793
 
  dsn = _iodbcdm_getkeyvalinstr (szConnStrIn, cbConnStrIn,
794
 
      "DSN", dsnbuf, sizeof (dsnbuf));
795
 
 
796
 
  switch (fDriverCompletion)
797
 
     {
798
 
     case SQL_DRIVER_NOPROMPT:
799
 
       break;
800
 
 
801
 
     case SQL_DRIVER_COMPLETE:
802
 
     case SQL_DRIVER_COMPLETE_REQUIRED:
803
 
       if (dsn != NULL || drv != NULL)
804
 
         {
805
 
           break;
806
 
         }
807
 
       /* fall to next case */
808
 
     case SQL_DRIVER_PROMPT:
809
 
       /* Get data source dialog box function from
810
 
        * current executable */
811
 
       hdll = _iodbcdm_dllopen ((char FAR *) NULL);
812
 
       dialproc = _iodbcdm_dllproc (hdll,
813
 
           "_iodbcdm_drvconn_dialbox");
814
 
 
815
 
       if (dialproc == SQL_NULL_HPROC)
816
 
         {
817
 
           sqlstat = en_IM008;
818
 
           break;
819
 
         }
820
 
 
821
 
       retcode = dialproc (
822
 
           hwnd,                /* window or display handle */
823
 
           dsnbuf,              /* input/output dsn buf */
824
 
           sizeof (dsnbuf),     /* buf size */
825
 
           &sqlstat);           /* error code */
826
 
 
827
 
       if (retcode != SQL_SUCCESS)
828
 
         {
829
 
           break;
830
 
         }
831
 
 
832
 
       if (cbConnStrIn == SQL_NTS)
833
 
         {
834
 
           cbConnStrIn = STRLEN (szConnStrIn);
835
 
         }
836
 
 
837
 
       dsn = dsnbuf;
838
 
 
839
 
       if (dsn[0] == '\0')
840
 
         {
841
 
           dsn = "default";
842
 
         }
843
 
 
844
 
       if (cbConnStrIn > sizeof (cnstr2drv)
845
 
           - STRLEN (dsn) - STRLEN ("DSN=;") - 1)
846
 
         {
847
 
           sqlstat = en_S1001;  /* a lazy way to avoid
848
 
                                 * using heap memory */
849
 
           break;
850
 
         }
851
 
 
852
 
       sprintf ((char*)cnstr2drv, "DSN=%s;", dsn);
853
 
       cbConnStrIn += STRLEN (cnstr2drv);
854
 
       STRNCAT (cnstr2drv, szConnStrIn, cbConnStrIn);
855
 
       szConnStrIn = cnstr2drv;
856
 
       break;
857
 
 
858
 
     default:
859
 
       sqlstat = en_S1110;
860
 
       break;
861
 
     }
862
 
 
863
 
  if (sqlstat != en_00000)
864
 
    {
865
 
      PUSHSQLERR (pdbc->herr, sqlstat);
866
 
 
867
 
      return SQL_ERROR;
868
 
    }
869
 
 
870
 
  if (dsn == NULL || dsn[0] == '\0')
871
 
    {
872
 
      dsn = "default";
873
 
    }
874
 
  else
875
 
    /* if you want tracing, you must use a DSN */
876
 
    {
877
 
      setopterr |= _iodbcdm_settracing (hdbc,
878
 
          (char *) dsn, SQL_NTS);
879
 
    }
880
 
 
881
 
  if (drv == NULL || drv[0] == '\0')
882
 
    {
883
 
      drv = _iodbcdm_getkeyvalbydsn (dsn, SQL_NTS, "Driver",
884
 
          drvbuf, sizeof (drvbuf));
885
 
    }
886
 
 
887
 
  if (drv == NULL)
888
 
    {
889
 
      PUSHSQLERR (pdbc->herr, en_IM002);
890
 
 
891
 
      return SQL_ERROR;
892
 
    }
893
 
 
894
 
  retcode = _iodbcdm_driverload (drv, hdbc);
895
 
 
896
 
  switch (retcode)
897
 
     {
898
 
     case SQL_SUCCESS:
899
 
       break;
900
 
 
901
 
     case SQL_SUCCESS_WITH_INFO:
902
 
       setopterr = SQL_ERROR;
903
 
       /* unsuccessed in calling driver's 
904
 
        * SQLSetConnectOption() to set login
905
 
        * timeout.
906
 
        */
907
 
       break;
908
 
 
909
 
     default:
910
 
       return retcode;
911
 
     }
912
 
 
913
 
  hproc = _iodbcdm_getproc (hdbc, en_DriverConnect);
914
 
 
915
 
  if (hproc == SQL_NULL_HPROC)
916
 
    {
917
 
      _iodbcdm_driverunload (hdbc);
918
 
 
919
 
      PUSHSQLERR (pdbc->herr, en_IM001);
920
 
 
921
 
      return SQL_ERROR;
922
 
    }
923
 
 
924
 
  CALL_DRIVER (hdbc, retcode, hproc, en_DriverConnect, (
925
 
          pdbc->dhdbc, hwnd,
926
 
          szConnStrIn, cbConnStrIn,
927
 
          szConnStrOut, cbConnStrOutMax,
928
 
          pcbConnStrOut, fDriverCompletion))
929
 
 
930
 
  if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
931
 
    {
932
 
      /* don't unload driver here for retrive 
933
 
       * error message from driver */
934
 
                /********
935
 
                _iodbcdm_driverunload( hdbc );
936
 
                *********/
937
 
 
938
 
      return retcode;
939
 
    }
940
 
 
941
 
  /* state transition */
942
 
  pdbc->state = en_dbc_connected;
943
 
 
944
 
  /* do delaid option setting */
945
 
  setopterr |= _iodbcdm_dbcdelayset (hdbc);
946
 
 
947
 
  if (setopterr != SQL_SUCCESS)
948
 
    {
949
 
      return SQL_SUCCESS_WITH_INFO;
950
 
    }
951
 
 
952
 
  return retcode;
953
 
}
954
 
 
955
 
 
956
 
RETCODE SQL_API 
957
 
SQLBrowseConnect (
958
 
    HDBC hdbc,
959
 
    UCHAR FAR * szConnStrIn,
960
 
    SWORD cbConnStrIn,
961
 
    UCHAR FAR * szConnStrOut,
962
 
    SWORD cbConnStrOutMax,
963
 
    SWORD FAR * pcbConnStrOut)
964
 
{
965
 
  DBC_t FAR *pdbc = (DBC_t FAR *) hdbc;
966
 
  char FAR *drv;
967
 
  char drvbuf[1024];
968
 
  char FAR *dsn;
969
 
  char dsnbuf[SQL_MAX_DSN_LENGTH + 1];
970
 
 
971
 
  HPROC hproc;
972
 
 
973
 
  RETCODE retcode = SQL_SUCCESS;
974
 
  RETCODE setopterr = SQL_SUCCESS;
975
 
 
976
 
  if (hdbc == SQL_NULL_HDBC)
977
 
    {
978
 
      return SQL_INVALID_HANDLE;
979
 
    }
980
 
 
981
 
  /* check arguments */
982
 
  if ((cbConnStrIn < 0 && cbConnStrIn != SQL_NTS) || cbConnStrOutMax < 0)
983
 
    {
984
 
      PUSHSQLERR (pdbc->herr, en_S1090);
985
 
 
986
 
      return SQL_ERROR;
987
 
    }
988
 
 
989
 
  if (pdbc->state == en_dbc_allocated)
990
 
    {
991
 
      drv = _iodbcdm_getkeyvalinstr (szConnStrIn, cbConnStrIn,
992
 
          "DRIVER", drvbuf, sizeof (drvbuf));
993
 
 
994
 
      dsn = _iodbcdm_getkeyvalinstr (szConnStrIn, cbConnStrIn,
995
 
          "DSN", dsnbuf, sizeof (dsnbuf));
996
 
 
997
 
      if (dsn == NULL || dsn[0] == '\0')
998
 
        {
999
 
          dsn = "default";
1000
 
        }
1001
 
      else
1002
 
        /* if you want tracing, you must use a DSN */
1003
 
        {
1004
 
          setopterr |= _iodbcdm_settracing (hdbc,
1005
 
              (char *) dsn, SQL_NTS);
1006
 
        }
1007
 
 
1008
 
      if (drv == NULL || drv[0] == '\0')
1009
 
        {
1010
 
          drv = _iodbcdm_getkeyvalbydsn (dsn, SQL_NTS, "Driver",
1011
 
              drvbuf, sizeof (drvbuf));
1012
 
        }
1013
 
 
1014
 
      if (drv == NULL)
1015
 
        {
1016
 
          PUSHSQLERR (pdbc->herr, en_IM002);
1017
 
 
1018
 
          return SQL_ERROR;
1019
 
        }
1020
 
 
1021
 
      retcode = _iodbcdm_driverload (drv, hdbc);
1022
 
 
1023
 
      switch (retcode)
1024
 
         {
1025
 
         case SQL_SUCCESS:
1026
 
           break;
1027
 
 
1028
 
         case SQL_SUCCESS_WITH_INFO:
1029
 
           setopterr = SQL_ERROR;
1030
 
           /* unsuccessed in calling driver's 
1031
 
            * SQLSetConnectOption() to set login
1032
 
            * timeout.
1033
 
            */
1034
 
           break;
1035
 
 
1036
 
         default:
1037
 
           return retcode;
1038
 
         }
1039
 
    }
1040
 
  else if (pdbc->state != en_dbc_needdata)
1041
 
    {
1042
 
      PUSHSQLERR (pdbc->herr, en_08002);
1043
 
 
1044
 
      return SQL_ERROR;
1045
 
    }
1046
 
 
1047
 
  hproc = _iodbcdm_getproc (hdbc, en_BrowseConnect);
1048
 
 
1049
 
  if (hproc == SQL_NULL_HPROC)
1050
 
    {
1051
 
      _iodbcdm_driverunload (hdbc);
1052
 
 
1053
 
      pdbc->state = en_dbc_allocated;
1054
 
 
1055
 
      PUSHSQLERR (pdbc->herr, en_IM001);
1056
 
 
1057
 
      return SQL_ERROR;
1058
 
    }
1059
 
 
1060
 
  CALL_DRIVER (hdbc, retcode, hproc, en_BrowseConnect, (
1061
 
          pdbc->dhdbc, 
1062
 
          szConnStrIn, cbConnStrIn, 
1063
 
          szConnStrOut, cbConnStrOutMax,
1064
 
          pcbConnStrOut))
1065
 
 
1066
 
  switch (retcode)
1067
 
     {
1068
 
     case SQL_SUCCESS:
1069
 
     case SQL_SUCCESS_WITH_INFO:
1070
 
       pdbc->state = en_dbc_connected;
1071
 
       setopterr |= _iodbcdm_dbcdelayset (hdbc);
1072
 
       if (setopterr != SQL_SUCCESS)
1073
 
         {
1074
 
           retcode = SQL_SUCCESS_WITH_INFO;
1075
 
         }
1076
 
       break;
1077
 
 
1078
 
     case SQL_NEED_DATA:
1079
 
       pdbc->state = en_dbc_needdata;
1080
 
       break;
1081
 
 
1082
 
     case SQL_ERROR:
1083
 
       pdbc->state = en_dbc_allocated;
1084
 
       /* but the driver will not unloaded 
1085
 
        * to allow application retrive err
1086
 
        * message from driver 
1087
 
        */
1088
 
       break;
1089
 
 
1090
 
     default:
1091
 
       break;
1092
 
     }
1093
 
 
1094
 
  return retcode;
1095
 
}
1096
 
 
1097
 
 
1098
 
RETCODE SQL_API 
1099
 
SQLDisconnect (HDBC hdbc)
1100
 
{
1101
 
  DBC_t FAR *pdbc = (DBC_t *) hdbc;
1102
 
  STMT_t FAR *pstmt;
1103
 
  RETCODE retcode;
1104
 
  HPROC hproc;
1105
 
 
1106
 
  int sqlstat = en_00000;
1107
 
 
1108
 
  if (hdbc == SQL_NULL_HDBC)
1109
 
    {
1110
 
      return SQL_INVALID_HANDLE;
1111
 
    }
1112
 
 
1113
 
  /* check hdbc state */
1114
 
  if (pdbc->state == en_dbc_allocated)
1115
 
    {
1116
 
      sqlstat = en_08003;
1117
 
    }
1118
 
 
1119
 
  /* check stmt(s) state */
1120
 
  for (pstmt = (STMT_t FAR *) pdbc->hstmt;
1121
 
      pstmt != NULL && sqlstat == en_00000;
1122
 
      pstmt = (STMT_t FAR *) pstmt->next)
1123
 
    {
1124
 
      if (pstmt->state >= en_stmt_needdata
1125
 
          || pstmt->asyn_on != en_NullProc)
1126
 
        /* In this case one need to call 
1127
 
         * SQLCancel() first */
1128
 
        {
1129
 
          sqlstat = en_S1010;
1130
 
        }
1131
 
    }
1132
 
 
1133
 
  if (sqlstat == en_00000)
1134
 
    {
1135
 
      hproc = _iodbcdm_getproc (hdbc, en_Disconnect);
1136
 
 
1137
 
      if (hproc == SQL_NULL_HPROC)
1138
 
        {
1139
 
          sqlstat = en_IM001;
1140
 
        }
1141
 
    }
1142
 
 
1143
 
  if (sqlstat != en_00000)
1144
 
    {
1145
 
      PUSHSQLERR (pdbc->herr, sqlstat);
1146
 
 
1147
 
      return SQL_ERROR;
1148
 
    }
1149
 
 
1150
 
  CALL_DRIVER (hdbc, retcode, hproc, en_Disconnect, (
1151
 
          pdbc->dhdbc))
1152
 
 
1153
 
  if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
1154
 
    {
1155
 
      /* diff from MS specs. We disallow
1156
 
       * driver SQLDisconnect() return
1157
 
       * SQL_SUCCESS_WITH_INFO and post
1158
 
       * error message.
1159
 
       */
1160
 
      retcode = SQL_SUCCESS;
1161
 
    }
1162
 
  else
1163
 
    {
1164
 
      return retcode;
1165
 
    }
1166
 
 
1167
 
  /* free all statement handle(s) on this connection */
1168
 
  for (; pdbc->hstmt;)
1169
 
    {
1170
 
      _iodbcdm_dropstmt (pdbc->hstmt);
1171
 
    }
1172
 
 
1173
 
  /* state transition */
1174
 
  if (retcode == SQL_SUCCESS)
1175
 
    {
1176
 
      pdbc->state = en_dbc_allocated;
1177
 
    }
1178
 
 
1179
 
  return retcode;
1180
 
}
1181
 
 
1182
 
 
1183
 
RETCODE SQL_API 
1184
 
SQLNativeSql (
1185
 
    HDBC hdbc,
1186
 
    UCHAR FAR * szSqlStrIn,
1187
 
    SDWORD cbSqlStrIn,
1188
 
    UCHAR FAR * szSqlStr,
1189
 
    SDWORD cbSqlStrMax,
1190
 
    SDWORD FAR * pcbSqlStr)
1191
 
{
1192
 
  DBC_t FAR *pdbc = (DBC_t FAR *) hdbc;
1193
 
  HPROC hproc;
1194
 
  int sqlstat = en_00000;
1195
 
  RETCODE retcode;
1196
 
 
1197
 
  if (hdbc == SQL_NULL_HDBC)
1198
 
    {
1199
 
      return SQL_INVALID_HANDLE;
1200
 
    }
1201
 
 
1202
 
  /* check argument */
1203
 
  if (szSqlStrIn == NULL)
1204
 
    {
1205
 
      sqlstat = en_S1009;
1206
 
    }
1207
 
  else if (cbSqlStrIn < 0 && cbSqlStrIn != SQL_NTS)
1208
 
    {
1209
 
      sqlstat = en_S1090;
1210
 
    }
1211
 
 
1212
 
  if (sqlstat != en_00000)
1213
 
    {
1214
 
      PUSHSQLERR (pdbc->herr, sqlstat);
1215
 
 
1216
 
      return SQL_ERROR;
1217
 
    }
1218
 
 
1219
 
  /* check state */
1220
 
  if (pdbc->state <= en_dbc_needdata)
1221
 
    {
1222
 
      PUSHSQLERR (pdbc->herr, en_08003);
1223
 
 
1224
 
      return SQL_ERROR;
1225
 
    }
1226
 
 
1227
 
  /* call driver */
1228
 
  hproc = _iodbcdm_getproc (hdbc, en_NativeSql);
1229
 
 
1230
 
  if (hproc == SQL_NULL_HPROC)
1231
 
    {
1232
 
      PUSHSQLERR (pdbc->herr, en_IM001);
1233
 
 
1234
 
      return SQL_ERROR;
1235
 
    }
1236
 
 
1237
 
  CALL_DRIVER (hdbc, retcode, hproc, en_NativeSql,
1238
 
    (pdbc->dhdbc, szSqlStrIn, cbSqlStrIn, szSqlStr, cbSqlStrMax, pcbSqlStr))
1239
 
 
1240
 
  return retcode;
1241
 
}