]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/cats/myingres.c
adf367db14ef3d11f1b284987dfa80562e7271e5
[bacula/bacula] / bacula / src / cats / myingres.c
1 /*
2    Bacula® - The Network Backup Solution
3    Copyright (C) 2009-2010 Free Software Foundation Europe e.V.
4    The main author of Bacula is Kern Sibbald, with contributions from
5    many others, a complete list can be found in the file AUTHORS.
6    This program is Free Software; you can redistribute it and/or
7    modify it under the terms of version two of the GNU General Public
8    License as published by the Free Software Foundation and included
9    in the file LICENSE.
10    This program is distributed in the hope that it will be useful, but
11    WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    General Public License for more details.
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17    02110-1301, USA.
18    Bacula® is a registered trademark of Kern Sibbald.
19    The licensor of Bacula is the Free Software Foundation Europe
20    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
21    Switzerland, email:ftf@fsfeurope.org.
22 */
23 /*
24  * Bacula Catalog Database routines specific to Ingres
25  *   These are Ingres specific routines
26  *
27  *    Stefan Reddig, June 2009 with help of Marco van Wieringen April 2010
28  */
29 #include "bacula.h"
30 /* # line 37 "myingres.sc" */   
31 #ifdef HAVE_INGRES
32 #include <eqpname.h>
33 #include <eqdefcc.h>
34 #include <eqsqlca.h>
35 #include <eqsqlda.h>
36 #include <stdlib.h>
37 #include <stdio.h>
38 #include <string.h>
39 #include "myingres.h"
40
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44 IISQLCA *IIsqlca();
45 #ifdef __cplusplus
46 }
47 #endif
48 #define sqlca (*(IIsqlca()))
49
50 /*
51  * ---Implementations---
52  */
53 short INGgetCols(INGconn *conn, const char *query, bool transaction)
54 {
55 /* # line 52 "myingres.sc" */   
56   
57   int sess_id;
58   char *stmt;
59 /* # line 55 "myingres.sc" */   
60   
61    short number = -1;
62    IISQLDA *sqlda;
63    sqlda = (IISQLDA *)malloc(IISQDA_HEAD_SIZE + (number * IISQDA_VAR_SIZE));
64    memset(sqlda, 0, (IISQDA_HEAD_SIZE + (number * IISQDA_VAR_SIZE)));
65    sqlda->sqln = number;
66    stmt = bstrdup(query);
67    /*
68     * Switch to the correct default session for this thread.
69     */
70    sess_id = conn->session_id;
71 /* # line 71 "myingres.sc" */   /* set_sql */
72   {
73     IILQssSetSqlio(11,(short *)0,1,30,sizeof(sess_id),&sess_id);
74   }
75 /* # line 75 "myingres.sc" */   /* prepare */
76   {
77     IIsqInit(&sqlca);
78     IIsqPrepare(0,(char *)"s1",(char *)0,0,stmt);
79     if (sqlca.sqlcode < 0) 
80       goto bail_out;
81   }
82 /* # line 76 "myingres.sc" */   /* describe */
83   {
84     IIsqInit(&sqlca);
85     IIsqDescribe(0,(char *)"s1",sqlda,0);
86     if (sqlca.sqlcode < 0) 
87       goto bail_out;
88   }
89 /* # line 80 "myingres.sc" */   /* host code */
90    number = sqlda->sqld;
91    /*
92     * If we are not in a transaction we commit our work now.
93     */
94    if (!transaction) {
95 /* # line 86 "myingres.sc" */   /* commit */
96   {
97     IIsqInit(&sqlca);
98     IIxact(3);
99   }
100 /* # line 87 "myingres.sc" */   /* host code */
101    }
102 bail_out:
103    /*
104     * Switch to no default session for this thread.
105     */
106 /* # line 93 "myingres.sc" */   /* set_sql */
107   {
108     IILQssSetSqlio(11,(short *)0,1,30,sizeof(-97),(void *)IILQint(-97));
109   }
110 /* # line 94 "myingres.sc" */   /* host code */
111    free(stmt);
112    free(sqlda);
113    return number;
114 }
115 static inline IISQLDA *INGgetDescriptor(short numCols, const char *query)
116 {
117 /* # line 101 "myingres.sc" */  
118   
119   char *stmt;
120 /* # line 103 "myingres.sc" */  
121   
122    int i;
123    IISQLDA *sqlda;
124    sqlda = (IISQLDA *)malloc(IISQDA_HEAD_SIZE + (numCols * IISQDA_VAR_SIZE));
125    memset(sqlda, 0, (IISQDA_HEAD_SIZE + (numCols * IISQDA_VAR_SIZE)));
126    sqlda->sqln = numCols;
127    stmt = bstrdup(query);
128 /* # line 115 "myingres.sc" */  /* prepare */
129   {
130     IIsqInit(&sqlca);
131     IIsqPrepare(0,(char *)"s2",sqlda,0,stmt);
132   }
133 /* # line 117 "myingres.sc" */  /* host code */
134    for (i = 0; i < sqlda->sqld; ++i) {
135       /*
136        * Negative type indicates nullable columns, so an indicator
137        * is allocated, otherwise it's null
138        */
139       if (sqlda->sqlvar[i].sqltype > 0) {
140          sqlda->sqlvar[i].sqlind = NULL;
141       } else {
142          sqlda->sqlvar[i].sqlind = (short *)malloc(sizeof(short));
143       }
144       /*
145        * Alloc space for variable like indicated in sqllen
146        * for date types sqllen is always 0 -> allocate by type
147        */
148       switch (abs(sqlda->sqlvar[i].sqltype)) {
149       case IISQ_TSW_TYPE:
150          sqlda->sqlvar[i].sqldata = (char *)malloc(IISQ_TSW_LEN);
151          break;
152       case IISQ_TSWO_TYPE:
153          sqlda->sqlvar[i].sqldata = (char *)malloc(IISQ_TSWO_LEN);
154          break;
155       case IISQ_TSTMP_TYPE:
156          sqlda->sqlvar[i].sqldata = (char *)malloc(IISQ_TSTMP_LEN);
157          break;
158       default:
159          /*
160           * plus one to avoid zero mem allocs
161           */
162          sqlda->sqlvar[i].sqldata = (char *)malloc(sqlda->sqlvar[i].sqllen+1);
163          break;
164       }
165    }
166    free(stmt);
167    return sqlda;
168 }
169 static void INGfreeDescriptor(IISQLDA *sqlda)
170 {
171    int i;
172    if (!sqlda) {
173       return;
174    }
175    for (i = 0; i < sqlda->sqld; ++i) {
176       if (sqlda->sqlvar[i].sqldata) {
177          free(sqlda->sqlvar[i].sqldata);
178       }
179       if (sqlda->sqlvar[i].sqlind) {
180          free(sqlda->sqlvar[i].sqlind);
181       }
182    }
183    free(sqlda);
184    sqlda = NULL;
185 }
186 static inline int INGgetTypeSize(IISQLVAR *ingvar)
187 {
188    int inglength = 0;
189    /*
190     * TODO: add date types (at least TSTMP,TSW TSWO)
191     */
192    switch (ingvar->sqltype) {
193    case IISQ_DTE_TYPE:
194       inglength = 25;
195       break;
196    case IISQ_MNY_TYPE:
197       inglength = 8;
198       break;
199    default:
200       inglength = ingvar->sqllen;
201       break;
202    }
203    return inglength;
204 }
205 static inline INGresult *INGgetINGresult(IISQLDA *sqlda)
206 {
207    int i;
208    INGresult *result = NULL;
209    if (!sqlda) {
210       return NULL;
211    }
212    result = (INGresult *)malloc(sizeof(INGresult));
213    memset(result, 0, sizeof(INGresult));
214    result->sqlda = sqlda;
215    result->num_fields = sqlda->sqld;
216    result->num_rows = 0;
217    result->first_row = NULL;
218    result->status = ING_EMPTY_RESULT;
219    result->act_row = NULL;
220    memset(result->numrowstring, 0, sizeof(result->numrowstring));
221    if (result->num_fields) {
222       result->fields = (INGRES_FIELD *)malloc(sizeof(INGRES_FIELD) * result->num_fields);
223       memset(result->fields, 0, sizeof(INGRES_FIELD) * result->num_fields);
224       for (i = 0; i < result->num_fields; ++i) {
225          memset(result->fields[i].name, 0, 34);
226          bstrncpy(result->fields[i].name, sqlda->sqlvar[i].sqlname.sqlnamec, sqlda->sqlvar[i].sqlname.sqlnamel);
227          result->fields[i].max_length = INGgetTypeSize(&sqlda->sqlvar[i]);
228          result->fields[i].type = abs(sqlda->sqlvar[i].sqltype);
229          result->fields[i].flags = (sqlda->sqlvar[i].sqltype < 0) ? 1 : 0;
230       }
231    }
232    return result;
233 }
234 static inline void INGfreeRowSpace(ING_ROW *row, IISQLDA *sqlda)
235 {
236    int i;
237    if (row == NULL || sqlda == NULL) {
238       return;
239    }
240    for (i = 0; i < sqlda->sqld; ++i) {
241       if (row->sqlvar[i].sqldata) {
242          free(row->sqlvar[i].sqldata);
243       }
244       if (row->sqlvar[i].sqlind) {
245          free(row->sqlvar[i].sqlind);
246       }
247    }
248    free(row->sqlvar);
249    free(row);
250 }
251 static void INGfreeINGresult(INGresult *ing_res)
252 {
253    int rows;
254    ING_ROW *rowtemp;
255    if (!ing_res) {
256       return;
257    }
258    /*
259     * Free all rows and fields, then res, not descriptor!
260     *
261     * Use of rows is a nasty workaround til I find the reason,
262     * why aggregates like max() don't work
263     */
264    rows = ing_res->num_rows;
265    ing_res->act_row = ing_res->first_row;
266    while (ing_res->act_row != NULL && rows > 0) {
267       rowtemp = ing_res->act_row->next;
268       INGfreeRowSpace(ing_res->act_row, ing_res->sqlda);
269       ing_res->act_row = rowtemp;
270       --rows;
271    }
272    if (ing_res->fields) {
273       free(ing_res->fields);
274    }
275    free(ing_res);
276 }
277 static inline ING_ROW *INGgetRowSpace(INGresult *ing_res)
278 {
279    int i;
280    unsigned short len; /* used for VARCHAR type length */
281    IISQLDA *sqlda = ing_res->sqlda;
282    ING_ROW *row = NULL;
283    IISQLVAR *vars = NULL;
284    row = (ING_ROW *)malloc(sizeof(ING_ROW));
285    memset(row, 0, sizeof(ING_ROW));
286    vars = (IISQLVAR *)malloc(sizeof(IISQLVAR) * sqlda->sqld);
287    memset(vars, 0, sizeof(IISQLVAR) * sqlda->sqld);
288    row->sqlvar = vars;
289    row->next = NULL;
290    for (i = 0; i < sqlda->sqld; ++i) {
291       /*
292        * Make strings out of the data, then the space and assign 
293        * (why string? at least it seems that way, looking into the sources)
294        */
295       vars[i].sqlind = (short *)malloc(sizeof(short));
296       if (sqlda->sqlvar[i].sqlind) {
297          memcpy(vars[i].sqlind,sqlda->sqlvar[i].sqlind,sizeof(short));
298       } else {
299          *vars[i].sqlind = NULL;
300       }
301       /*
302        * if sqlind pointer exists AND points to -1 -> column is 'null'
303        */
304       if ( *vars[i].sqlind && (*vars[i].sqlind == -1)) {
305          vars[i].sqldata = NULL;
306       } else {
307          switch (ing_res->fields[i].type) {
308          case IISQ_VCH_TYPE:
309             len = ((ING_VARCHAR *)sqlda->sqlvar[i].sqldata)->len;
310             vars[i].sqldata = (char *)malloc(len+1);
311             memcpy(vars[i].sqldata,sqlda->sqlvar[i].sqldata+2,len);
312             vars[i].sqldata[len] = '\0';
313             break;
314          case IISQ_CHA_TYPE:
315             vars[i].sqldata = (char *)malloc(ing_res->fields[i].max_length+1);
316             memcpy(vars[i].sqldata,sqlda->sqlvar[i].sqldata,sqlda->sqlvar[i].sqllen);
317             vars[i].sqldata[ing_res->fields[i].max_length] = '\0';
318             break;
319          case IISQ_INT_TYPE:
320             vars[i].sqldata = (char *)malloc(20);
321             memset(vars[i].sqldata, 0, 20);
322             switch (sqlda->sqlvar[i].sqllen) {
323             case 2:
324                bsnprintf(vars[i].sqldata, 20, "%d",*(short*)sqlda->sqlvar[i].sqldata);
325                break;
326             case 4:
327                bsnprintf(vars[i].sqldata, 20, "%ld",*(int*)sqlda->sqlvar[i].sqldata);
328                break;
329             case 8:
330                bsnprintf(vars[i].sqldata, 20, "%lld",*(long*)sqlda->sqlvar[i].sqldata);
331                break;
332             }
333             break;
334          case IISQ_TSTMP_TYPE:
335             vars[i].sqldata = (char *)malloc(IISQ_TSTMP_LEN+1);
336             vars[i].sqldata[IISQ_TSTMP_LEN] = '\0';
337             break;
338          case IISQ_TSWO_TYPE:
339             vars[i].sqldata = (char *)malloc(IISQ_TSWO_LEN+1);
340             vars[i].sqldata[IISQ_TSWO_LEN] = '\0';
341             break;
342          case IISQ_TSW_TYPE:
343             vars[i].sqldata = (char *)malloc(IISQ_TSW_LEN+1);
344             vars[i].sqldata[IISQ_TSW_LEN] = '\0';
345             break;
346          }
347       }
348    }
349    return row;
350 }
351 static inline int INGfetchAll(const char *query, INGresult *ing_res)
352 {
353    ING_ROW *row;
354    IISQLDA *desc;
355    int linecount = -1;
356    desc = ing_res->sqlda;
357 /* # line 371 "myingres.sc" */  /* open */
358   {
359     IIsqInit(&sqlca);
360     IIcsOpen((char *)"c2",14614,8429);
361     IIwritio(0,(short *)0,1,32,0,(char *)"s2");
362     IIcsQuery((char *)"c2",14614,8429);
363     if (sqlca.sqlcode < 0) 
364       goto bail_out;
365   }
366 /* # line 375 "myingres.sc" */  /* host code */
367    linecount = 0;
368    do {
369 /* # line 377 "myingres.sc" */  /* fetch */
370   {
371     IIsqInit(&sqlca);
372     if (IIcsRetScroll((char *)"c2",14614,8429,-1,-1) != 0) {
373       IIcsDaGet(0,desc);
374       IIcsERetrieve();
375     } /* IIcsRetrieve */
376   }
377 /* # line 379 "myingres.sc" */  /* host code */
378       if (sqlca.sqlcode == 0 || sqlca.sqlcode == -40202) {
379          /*
380           * Allocate space for fetched row
381           */
382          row = INGgetRowSpace(ing_res);
383          /*
384           * Initialize list when encountered first time
385           */
386          if (ing_res->first_row == 0) {
387             ing_res->first_row = row; /* head of the list */
388             ing_res->first_row->next = NULL;
389             ing_res->act_row = ing_res->first_row;
390          }      
391          ing_res->act_row->next = row; /* append row to old act_row */
392          ing_res->act_row = row; /* set row as act_row */
393          row->row_number = linecount++;
394       }
395    } while ( (sqlca.sqlcode == 0) || (sqlca.sqlcode == -40202) );
396 /* # line 400 "myingres.sc" */  /* close */
397   {
398     IIsqInit(&sqlca);
399     IIcsClose((char *)"c2",14614,8429);
400   }
401 /* # line 402 "myingres.sc" */  /* host code */
402    ing_res->status = ING_COMMAND_OK;
403    ing_res->num_rows = linecount;
404 bail_out:
405    return linecount;
406 }
407 static inline ING_STATUS INGresultStatus(INGresult *res)
408 {
409    if (res == NULL) {
410       return ING_NO_RESULT;
411    } else {
412       return res->status;
413    }
414 }
415 static void INGrowSeek(INGresult *res, int row_number)
416 {
417    ING_ROW *trow = NULL;
418    if (res->act_row->row_number == row_number) {
419       return;
420    }
421    /*
422     * TODO: real error handling
423     */
424    if (row_number<0 || row_number>res->num_rows) {
425       return;
426    }
427    for (trow = res->first_row; trow->row_number != row_number; trow = trow->next) ;
428    res->act_row = trow;
429    /*
430     * Note - can be null - if row_number not found, right?
431     */
432 }
433 char *INGgetvalue(INGresult *res, int row_number, int column_number)
434 {
435    if (row_number != res->act_row->row_number) {
436       INGrowSeek(res, row_number);
437    }
438    return res->act_row->sqlvar[column_number].sqldata;
439 }
440 bool INGgetisnull(INGresult *res, int row_number, int column_number)
441 {
442    if (row_number != res->act_row->row_number) {
443       INGrowSeek(res, row_number);
444    }
445    return (*res->act_row->sqlvar[column_number].sqlind == -1) ? true : false;
446 }
447 int INGntuples(const INGresult *res)
448 {
449    return res->num_rows;
450 }
451 int INGnfields(const INGresult *res)
452 {
453    return res->num_fields;
454 }
455 char *INGfname(const INGresult *res, int column_number)
456 {
457    if ((column_number > res->num_fields) || (column_number < 0)) {
458       return NULL;
459    } else {
460       return res->fields[column_number].name;
461    }
462 }
463 short INGftype(const INGresult *res, int column_number)
464 {
465    return res->fields[column_number].type;
466 }
467 int INGexec(INGconn *conn, const char *query, bool transaction)
468 {
469    int check;
470 /* # line 485 "myingres.sc" */  
471   
472   int sess_id;
473   int rowcount;
474   char *stmt;
475 /* # line 489 "myingres.sc" */  
476   
477    rowcount = -1;
478    stmt = bstrdup(query);
479    /*
480     * Switch to the correct default session for this thread.
481     */
482    sess_id = conn->session_id;
483 /* # line 498 "myingres.sc" */  /* set_sql */
484   {
485     IILQssSetSqlio(11,(short *)0,1,30,sizeof(sess_id),&sess_id);
486   }
487 /* # line 502 "myingres.sc" */  /* execute */
488   {
489     IIsqInit(&sqlca);
490     IIsqExImmed(stmt);
491     IIsyncup((char *)0,0);
492     if (sqlca.sqlcode < 0) 
493       goto bail_out;
494   }
495 /* # line 503 "myingres.sc" */  /* inquire_ingres */
496   {
497     IILQisInqSqlio((short *)0,1,30,sizeof(rowcount),&rowcount,8);
498   }
499 /* # line 507 "myingres.sc" */  /* host code */
500    /*
501     * If we are not in a transaction we commit our work now.
502     */
503    if (!transaction) {
504 /* # line 511 "myingres.sc" */  /* commit */
505   {
506     IIsqInit(&sqlca);
507     IIxact(3);
508   }
509 /* # line 512 "myingres.sc" */  /* host code */
510    }
511 bail_out:
512    /*
513     * Switch to no default session for this thread.
514     */
515 /* # line 518 "myingres.sc" */  /* set_sql */
516   {
517     IILQssSetSqlio(11,(short *)0,1,30,sizeof(-97),(void *)IILQint(-97));
518   }
519 /* # line 519 "myingres.sc" */  /* host code */
520    free(stmt);
521    return rowcount;
522 }
523 INGresult *INGquery(INGconn *conn, const char *query, bool transaction)
524 {
525    /*
526     * TODO: error handling
527     */
528    IISQLDA *desc = NULL;
529    INGresult *res = NULL;
530    int rows = -1;
531    int cols = INGgetCols(conn, query, transaction);
532 /* # line 532 "myingres.sc" */  
533   
534   int sess_id;
535 /* # line 534 "myingres.sc" */  
536   
537    /*
538     * Switch to the correct default session for this thread.
539     */
540    sess_id = conn->session_id;
541 /* # line 540 "myingres.sc" */  /* set_sql */
542   {
543     IILQssSetSqlio(11,(short *)0,1,30,sizeof(sess_id),&sess_id);
544   }
545 /* # line 542 "myingres.sc" */  /* host code */
546    desc = INGgetDescriptor(cols, query);
547    if (!desc) {
548       goto bail_out;
549    }
550    res = INGgetINGresult(desc);
551    if (!res) {
552       goto bail_out;
553    }
554    rows = INGfetchAll(query, res);
555    if (rows < 0) {
556       INGfreeDescriptor(desc);
557       INGfreeINGresult(res);
558       res = NULL;
559       goto bail_out;
560    }
561 bail_out:
562    /*
563     * If we are not in a transaction we commit our work now.
564     */
565    if (!transaction) {
566 /* # line 566 "myingres.sc" */  /* commit */
567   {
568     IIsqInit(&sqlca);
569     IIxact(3);
570   }
571 /* # line 567 "myingres.sc" */  /* host code */
572    }
573    /*
574     * Switch to no default session for this thread.
575     */
576 /* # line 571 "myingres.sc" */  /* set_sql */
577   {
578     IILQssSetSqlio(11,(short *)0,1,30,sizeof(-97),(void *)IILQint(-97));
579   }
580 /* # line 572 "myingres.sc" */  /* host code */
581    return res;
582 }
583 void INGclear(INGresult *res)
584 {
585    if (res == NULL) {
586       return;
587    }
588    INGfreeDescriptor(res->sqlda);
589    INGfreeINGresult(res);
590 }
591 void INGcommit(const INGconn *conn)
592 {
593 /* # line 587 "myingres.sc" */  
594   
595   int sess_id;
596 /* # line 589 "myingres.sc" */  
597   
598    if (dbconn != NULL) {
599       sess_id = dbconn->session_id;
600 /* # line 593 "myingres.sc" */  /* disconnect */
601   {
602     IIsqInit(&sqlca);
603     IILQsidSessID(sess_id);
604     IIsqDisconnect();
605   }
606 /* # line 595 "myingres.sc" */  /* host code */
607       /*
608        * Commit our work.
609        */
610 /* # line 598 "myingres.sc" */  /* commit */
611   {
612     IIsqInit(&sqlca);
613     IIxact(3);
614   }
615 /* # line 600 "myingres.sc" */  /* host code */
616       /*
617        * Switch to no default session for this thread.
618        */
619 /* # line 603 "myingres.sc" */  /* set_sql */
620   {
621     IILQssSetSqlio(11,(short *)0,1,30,sizeof(-97),(void *)IILQint(-97));
622   }
623 /* # line 604 "myingres.sc" */  /* host code */
624    }
625 }
626 INGconn *INGconnectDB(char *dbname, char *user, char *passwd, int session_id)
627 {
628 /* # line 609 "myingres.sc" */  
629   
630   char ingdbname[24];
631   char ingdbuser[32];
632   char ingdbpasswd[32];
633   int sess_id;
634 /* # line 614 "myingres.sc" */  
635   
636    INGconn *dbconn;
637    if (dbname == NULL || strlen(dbname) == 0) {
638       return NULL;
639    }
640    sess_id = session_id;
641    bstrncpy(ingdbname, dbname, sizeof(ingdbname));
642 /* # line 626 "myingres.sc" */  /* host code */
643    if (user != NULL) {
644       bstrncpy(ingdbuser, user, sizeof(ingdbuser));
645       if (passwd != NULL) {
646          bstrncpy(ingdbpasswd, passwd, sizeof(ingdbpasswd));
647       } else {
648          memset(ingdbpasswd, 0, sizeof(ingdbpasswd));
649       }
650 /* # line 633 "myingres.sc" */  /* connect */
651   {
652     IIsqInit(&sqlca);
653     IILQsidSessID(sess_id);
654     IIsqUser(ingdbuser);
655     IIsqConnect(0,ingdbname,(char *)"-dbms_password",ingdbpasswd,(char *)0, 
656     (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, 
657     (char *)0, (char *)0, (char *)0, (char *)0);
658     if (sqlca.sqlcode < 0) 
659       goto bail_out;
660   }
661 /* # line 638 "myingres.sc" */  /* host code */
662    } else {
663 /* # line 639 "myingres.sc" */  /* connect */
664   {
665     IIsqInit(&sqlca);
666     IILQsidSessID(sess_id);
667     IIsqConnect(0,ingdbname,(char *)0, (char *)0, (char *)0, (char *)0, 
668     (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, 
669     (char *)0, (char *)0, (char *)0);
670     if (sqlca.sqlcode < 0) 
671       goto bail_out;
672   }
673 /* # line 642 "myingres.sc" */  /* host code */
674    }   
675 /* # line 646 "myingres.sc" */  /* host code */
676    dbconn = (INGconn *)malloc(sizeof(INGconn));
677    memset(dbconn, 0, sizeof(INGconn));
678    bstrncpy(dbconn->dbname, ingdbname, sizeof(dbconn->dbname));
679    bstrncpy(dbconn->user, ingdbuser, sizeof(dbconn->user));
680    bstrncpy(dbconn->password, ingdbpasswd, sizeof(dbconn->password));
681    dbconn->session_id = sess_id;
682    dbconn->msg = (char *)malloc(257);
683    memset(dbconn->msg, 0, 257);
684    /*
685     * Switch to no default session for this thread undo default settings from SQL CONNECT.
686     */
687 /* # line 659 "myingres.sc" */  /* set_sql */
688   {
689     IILQssSetSqlio(11,(short *)0,1,30,sizeof(-97),(void *)IILQint(-97));
690   }
691 /* # line 661 "myingres.sc" */  /* host code */
692 bail_out:
693    return dbconn;
694 }
695 void INGdisconnectDB(INGconn *dbconn)
696 {
697 /* # line 667 "myingres.sc" */  
698   
699   int sess_id;
700 /* # line 669 "myingres.sc" */  
701   
702    if (dbconn != NULL) {
703       sess_id = dbconn->session_id;
704 /* # line 673 "myingres.sc" */  /* disconnect */
705   {
706     IIsqInit(&sqlca);
707     IILQsidSessID(sess_id);
708     IIsqDisconnect();
709   }
710 /* # line 675 "myingres.sc" */  /* host code */
711       free(dbconn->msg);
712       free(dbconn);
713    }
714 }
715 char *INGerrorMessage(const INGconn *conn)
716 {
717 /* # line 682 "myingres.sc" */  
718   
719   char errbuf[256];
720 /* # line 684 "myingres.sc" */  
721   
722 /* # line 686 "myingres.sc" */  /* inquire_ingres */
723   {
724     IILQisInqSqlio((short *)0,1,32,255,errbuf,63);
725   }
726 /* # line 687 "myingres.sc" */  /* host code */
727    strncpy(conn->msg, errbuf, sizeof(conn->msg));
728    return conn->msg;
729 }
730 char *INGcmdTuples(INGresult *res)
731 {
732    return res->numrowstring;
733 }
734 /* TODO?
735 int INGputCopyEnd(INGconn *conn, const char *errormsg);
736 int INGputCopyData(INGconn *conn, const char *buffer, int nbytes);
737 */
738 /* # line 701 "myingres.sc" */  
739 #endif