]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/cats/myingres.c
Lets generate ingres code by calling esqlcc and not esqlc as we want c++ code.
[bacula/bacula] / bacula / src / cats / myingres.c
1 #include "bacula.h"
2 /* # line 3 "myingres.sc" */    
3 #ifdef HAVE_INGRES
4 #include <eqpname.h>
5 #include <eqdefcc.h>
6 #include <eqsqlca.h>
7 extern IISQLCA sqlca;   /* SQL Communications Area */
8 #include <eqsqlda.h>
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include "myingres.h"
13 /*
14  * ---Implementations---
15  */
16 int INGcheck()
17 {
18    return (sqlca.sqlcode < 0) ? sqlca.sqlcode : 0;
19 }
20 short INGgetCols(const char *stmt)
21 {
22 /* # line 23 "myingres.sc" */   
23   
24   char *stmtd;
25 /* # line 25 "myingres.sc" */   
26   
27    short number = 1;
28    IISQLDA *sqlda;
29    sqlda = (IISQLDA *)malloc(IISQDA_HEAD_SIZE + (number * IISQDA_VAR_SIZE));
30    memset(sqlda, 0, (IISQDA_HEAD_SIZE + (number * IISQDA_VAR_SIZE)));
31    sqlda->sqln = number;
32    stmtd = (char*)malloc(strlen(stmt)+1);
33    bstrncpy(stmtd,stmt,strlen(stmt)+1);
34 /* # line 38 "myingres.sc" */   /* prepare */
35   {
36     IIsqInit(&sqlca);
37     IIsqPrepare(0,(char *)"s1",(char *)0,0,stmtd);
38   }
39 /* # line 39 "myingres.sc" */   /* host code */
40    if (INGcheck() < 0) {
41       free(stmtd);
42       free(sqlda);
43       return -1;
44    }
45 /* # line 44 "myingres.sc" */   /* describe */
46   {
47     IIsqInit(&sqlca);
48     IIsqDescribe(0,(char *)"s1",sqlda,0);
49   }
50 /* # line 45 "myingres.sc" */   /* host code */
51    if (INGcheck() < 0) {
52       free(stmtd);
53       free(sqlda);
54       return -1;
55    }
56    number = sqlda->sqld;
57    free(stmtd);
58    free(sqlda);
59    return number;
60 }
61 IISQLDA *INGgetDescriptor(short numCols, const char *stmt)
62 {
63 /* # line 59 "myingres.sc" */   
64   
65   char *stmtd;
66 /* # line 61 "myingres.sc" */   
67   
68    int i;
69    IISQLDA *sqlda;
70    sqlda = (IISQLDA *)malloc(IISQDA_HEAD_SIZE + (numCols * IISQDA_VAR_SIZE));
71    memset(sqlda, 0, (IISQDA_HEAD_SIZE + (numCols * IISQDA_VAR_SIZE)));
72    sqlda->sqln = numCols;
73    stmtd = (char *)malloc(strlen(stmt)+1);
74    bstrncpy(stmtd,stmt,strlen(stmt)+1);
75 /* # line 74 "myingres.sc" */   /* prepare */
76   {
77     IIsqInit(&sqlca);
78     IIsqPrepare(0,(char *)"s2",sqlda,0,stmtd);
79   }
80 /* # line 76 "myingres.sc" */   /* host code */
81    free(stmtd);
82    for (i = 0; i < sqlda->sqld; ++i) {
83       /*
84        * Alloc space for variable like indicated in sqllen
85        * for date types sqllen is always 0 -> allocate by type
86        */
87       switch (abs(sqlda->sqlvar[i].sqltype)) {
88       case IISQ_TSW_TYPE:
89          sqlda->sqlvar[i].sqldata = (char *)malloc(IISQ_TSW_LEN);
90          break;
91       case IISQ_TSWO_TYPE:
92          sqlda->sqlvar[i].sqldata = (char *)malloc(IISQ_TSWO_LEN);
93          break;
94       case IISQ_TSTMP_TYPE:
95          sqlda->sqlvar[i].sqldata = (char *)malloc(IISQ_TSTMP_LEN);
96          break;
97       default:
98          sqlda->sqlvar[i].sqldata = (char *)malloc(sqlda->sqlvar[i].sqllen);
99          break;
100       }
101    }
102    return sqlda;
103 }
104 void INGfreeDescriptor(IISQLDA *sqlda)
105 {
106    int i;
107    for (i = 0; i < sqlda->sqld; ++i) {
108       if (sqlda->sqlvar[i].sqldata) {
109          free(sqlda->sqlvar[i].sqldata);
110       }
111       if (sqlda->sqlvar[i].sqlind) {
112          free(sqlda->sqlvar[i].sqlind);
113       }
114    }
115    free(sqlda);
116    sqlda = NULL;
117 }
118 int INGgetTypeSize(IISQLVAR *ingvar)
119 {
120    int inglength = 0;
121    /*
122     * TODO: add date types (at least TSTMP,TSW TSWO)
123     */
124    switch (ingvar->sqltype) {
125    case IISQ_DTE_TYPE:
126       inglength = 25;
127       break;
128    case IISQ_MNY_TYPE:
129       inglength = 8;
130       break;
131    default:
132       inglength = ingvar->sqllen;
133       break;
134    }
135    return inglength;
136 }
137 INGresult *INGgetINGresult(IISQLDA *sqlda)
138 {
139    int i;
140    INGresult *result = NULL;
141    result = (INGresult *)malloc(sizeof(INGresult));
142    memset(result, 0, sizeof(INGresult));
143    result->sqlda = sqlda;
144    result->num_fields = sqlda->sqld;
145    result->num_rows = 0;
146    result->first_row = NULL;
147    result->status = ING_EMPTY_RESULT;
148    result->act_row = NULL;
149    memset(result->numrowstring, 0, sizeof(result->numrowstring));
150    if (result->num_fields) {
151       result->fields = (INGRES_FIELD *)malloc(sizeof(INGRES_FIELD) * result->num_fields);
152       memset(result->fields, 0, sizeof(INGRES_FIELD) * result->num_fields);
153       for (i = 0; i < result->num_fields; ++i) {
154          memset(result->fields[i].name, 0, 34);
155          bstrncpy(result->fields[i].name, sqlda->sqlvar[i].sqlname.sqlnamec, sqlda->sqlvar[i].sqlname.sqlnamel);
156          result->fields[i].max_length = INGgetTypeSize(&sqlda->sqlvar[i]);
157          result->fields[i].type = abs(sqlda->sqlvar[i].sqltype);
158          result->fields[i].flags = (abs(sqlda->sqlvar[i].sqltype)<0) ? 1 : 0;
159       }
160    }
161    return result;
162 }
163 void INGfreeINGresult(INGresult *ing_res)
164 {
165    int rows;
166    ING_ROW *rowtemp;
167    /*
168     * Free all rows and fields, then res, not descriptor!
169     */
170    if (ing_res != NULL) {
171       /*
172        * Use of rows is a nasty workaround til I find the reason,
173        * why aggregates like max() don't work
174        */
175       rows = ing_res->num_rows;
176       ing_res->act_row = ing_res->first_row;
177       while (ing_res->act_row != NULL && rows > 0) {
178          rowtemp = ing_res->act_row->next;
179          INGfreeRowSpace(ing_res->act_row, ing_res->sqlda);
180          ing_res->act_row = rowtemp;
181          --rows;
182       }
183       if (ing_res->fields) {
184          free(ing_res->fields);
185       }
186    }
187    free(ing_res);
188    ing_res = NULL;
189 }
190 ING_ROW *INGgetRowSpace(INGresult *ing_res)
191 {
192    int i;
193    unsigned short len; /* used for VARCHAR type length */
194    IISQLDA *sqlda = ing_res->sqlda;
195    ING_ROW *row = NULL;
196    IISQLVAR *vars = NULL;
197    row = (ING_ROW *)malloc(sizeof(ING_ROW));
198    memset(row, 0, sizeof(ING_ROW));
199    vars = (IISQLVAR *)malloc(sizeof(IISQLVAR) * sqlda->sqld);
200    memset(vars, 0, sizeof(IISQLVAR) * sqlda->sqld);
201    row->sqlvar = vars;
202    row->next = NULL;
203    for (i = 0; i < sqlda->sqld; ++i) {
204       /*
205        * Make strings out of the data, then the space and assign 
206        * (why string? at least it seems that way, looking into the sources)
207        */
208       switch (ing_res->fields[i].type) {
209       case IISQ_VCH_TYPE:
210          len = ((ING_VARCHAR *)sqlda->sqlvar[i].sqldata)->len;
211          vars[i].sqldata = (char *)malloc(len+1);
212          memcpy(vars[i].sqldata,sqlda->sqlvar[i].sqldata+2,len);
213          vars[i].sqldata[len] = '\0';
214          break;
215       case IISQ_CHA_TYPE:
216          vars[i].sqldata = (char *)malloc(ing_res->fields[i].max_length+1);
217          memcpy(vars[i].sqldata,sqlda->sqlvar[i].sqldata,sqlda->sqlvar[i].sqllen);
218          vars[i].sqldata[ing_res->fields[i].max_length] = '\0';
219          break;
220       case IISQ_INT_TYPE:
221          vars[i].sqldata = (char *)malloc(20);
222          memset(vars[i].sqldata, 0, 20);
223          switch (sqlda->sqlvar[i].sqllen) {
224          case 2:
225             bsnprintf(vars[i].sqldata, 20, "%d",*(short*)sqlda->sqlvar[i].sqldata);
226             break;
227          case 4:
228             bsnprintf(vars[i].sqldata, 20, "%ld",*(int*)sqlda->sqlvar[i].sqldata);
229             break;
230          case 8:
231             bsnprintf(vars[i].sqldata, 20, "%lld",*(long*)sqlda->sqlvar[i].sqldata);
232             break;
233          }
234          break;
235       case IISQ_TSTMP_TYPE:
236          vars[i].sqldata = (char *)malloc(IISQ_TSTMP_LEN+1);
237          vars[i].sqldata[IISQ_TSTMP_LEN] = '\0';
238          break;
239       case IISQ_TSWO_TYPE:
240          vars[i].sqldata = (char *)malloc(IISQ_TSWO_LEN+1);
241          vars[i].sqldata[IISQ_TSWO_LEN] = '\0';
242          break;
243       case IISQ_TSW_TYPE:
244          vars[i].sqldata = (char *)malloc(IISQ_TSW_LEN+1);
245          vars[i].sqldata[IISQ_TSW_LEN] = '\0';
246          break;
247       }
248       vars[i].sqlind = (short *)malloc(sizeof(short));
249       if (sqlda->sqlvar[i].sqlind) {
250          memcpy(vars[i].sqlind,sqlda->sqlvar[i].sqlind,sizeof(short));
251       } else {
252          *vars[i].sqlind = 0;
253       }
254    }
255    return row;
256 }
257 void INGfreeRowSpace(ING_ROW *row, IISQLDA *sqlda)
258 {
259    int i;
260    if (row == NULL || sqlda == NULL) {
261       return;
262    }
263    for (i = 0; i < sqlda->sqld; ++i) {
264       if (row->sqlvar[i].sqldata) {
265          free(row->sqlvar[i].sqldata);
266       }
267       if (row->sqlvar[i].sqlind) {
268          free(row->sqlvar[i].sqlind);
269       }
270    }
271    free(row->sqlvar);
272    free(row);
273 }
274 int INGfetchAll(const char *stmt, INGresult *ing_res)
275 {
276    int linecount = 0;
277    ING_ROW *row;
278    IISQLDA *desc;
279    int check = -1;
280    desc = ing_res->sqlda;
281 /* # line 305 "myingres.sc" */  /* host code */
282    if ((check = INGcheck()) < 0) {
283       return check;
284    }
285 /* # line 309 "myingres.sc" */  /* open */
286   {
287     IIsqInit(&sqlca);
288     IIcsOpen((char *)"c2",4824,17405);
289     IIwritio(0,(short *)0,1,32,0,(char *)"s2");
290     IIcsQuery((char *)"c2",4824,17405);
291   }
292 /* # line 310 "myingres.sc" */  /* host code */
293    if ((check = INGcheck()) < 0) {
294       return check;
295    }
296    /* for (linecount = 0; sqlca.sqlcode == 0; ++linecount) */
297    while(sqlca.sqlcode == 0) {
298 /* # line 316 "myingres.sc" */  /* fetch */
299   {
300     IIsqInit(&sqlca);
301     if (IIcsRetScroll((char *)"c2",4824,17405,-1,-1) != 0) {
302       IIcsDaGet(0,desc);
303       IIcsERetrieve();
304     } /* IIcsRetrieve */
305   }
306 /* # line 317 "myingres.sc" */  /* host code */
307       if ((check = INGcheck()) < 0) {
308 /* # line 318 "myingres.sc" */  /* close */
309   {
310     IIsqInit(&sqlca);
311     IIcsClose((char *)"c2",4824,17405);
312   }
313 /* # line 319 "myingres.sc" */  /* host code */
314          return check;
315       }
316       if (sqlca.sqlcode == 0) {
317          row = INGgetRowSpace(ing_res); /* alloc space for fetched row */
318          /*
319           * Initialize list when encountered first time
320           */
321          if (ing_res->first_row == 0) {
322             ing_res->first_row = row; /* head of the list */
323             ing_res->first_row->next = NULL;
324             ing_res->act_row = ing_res->first_row;
325          }      
326          ing_res->act_row->next = row; /* append row to old act_row */
327          ing_res->act_row = row; /* set row as act_row */
328          row->row_number = linecount;
329          ++linecount;
330       }
331    }
332 /* # line 340 "myingres.sc" */  /* close */
333   {
334     IIsqInit(&sqlca);
335     IIcsClose((char *)"c2",4824,17405);
336   }
337 /* # line 342 "myingres.sc" */  /* host code */
338    ing_res->status = ING_COMMAND_OK;
339    ing_res->num_rows = linecount;
340    return linecount;
341 }
342 ING_STATUS INGresultStatus(INGresult *res)
343 {
344    if (res == NULL) {return ING_NO_RESULT;}
345    return res->status;
346 }
347 void INGrowSeek(INGresult *res, int row_number)
348 {
349    ING_ROW *trow;
350    if (res->act_row->row_number == row_number) {
351       return;
352    }
353    /*
354     * TODO: real error handling
355     */
356    if (row_number<0 || row_number>res->num_rows) {
357       return;
358    }
359    for (trow = res->first_row; trow->row_number != row_number; trow = trow->next) ;
360    res->act_row = trow;
361    /*
362     * Note - can be null - if row_number not found, right?
363     */
364 }
365 char *INGgetvalue(INGresult *res, int row_number, int column_number)
366 {
367    if (row_number != res->act_row->row_number) {
368       INGrowSeek(res, row_number);
369    }
370    return res->act_row->sqlvar[column_number].sqldata;
371 }
372 int INGgetisnull(INGresult *res, int row_number, int column_number)
373 {
374    if (row_number != res->act_row->row_number) {
375       INGrowSeek(res, row_number);
376    }
377    return (short)*res->act_row->sqlvar[column_number].sqlind;
378 }
379 int INGntuples(const INGresult *res)
380 {
381    return res->num_rows;
382 }
383 int INGnfields(const INGresult *res)
384 {
385    return res->num_fields;
386 }
387 char *INGfname(const INGresult *res, int column_number)
388 {
389    if ((column_number > res->num_fields) || (column_number < 0)) {
390       return NULL;
391    } else {
392       return res->fields[column_number].name;
393    }
394 }
395 short INGftype(const INGresult *res, int column_number)
396 {
397    return res->fields[column_number].type;
398 }
399 int INGexec(INGconn *conn, const char *query)
400 {
401    int check;
402 /* # line 417 "myingres.sc" */  
403   
404   int rowcount;
405   char *stmt;
406 /* # line 420 "myingres.sc" */  
407   
408    stmt = (char *)malloc(strlen(query)+1);
409    bstrncpy(stmt,query,strlen(query)+1);
410    rowcount = -1;
411 /* # line 426 "myingres.sc" */  /* execute */
412   {
413     IIsqInit(&sqlca);
414     IIsqExImmed(stmt);
415     IIsyncup((char *)0,0);
416   }
417 /* # line 427 "myingres.sc" */  /* host code */
418    free(stmt);
419    if ((check = INGcheck()) < 0) {
420       return check;
421    }
422 /* # line 432 "myingres.sc" */  /* inquire_ingres */
423   {
424     IILQisInqSqlio((short *)0,1,30,sizeof(rowcount),&rowcount,8);
425   }
426 /* # line 433 "myingres.sc" */  /* host code */
427    if ((check = INGcheck()) < 0) {
428       return check;
429    }
430    return rowcount;
431 }
432 INGresult *INGquery(INGconn *conn, const char *query)
433 {
434    /*
435     * TODO: error handling
436     */
437    IISQLDA *desc = NULL;
438    INGresult *res = NULL;
439    int rows = -1;
440    int cols = INGgetCols(query);
441    desc = INGgetDescriptor(cols, query);
442    res = INGgetINGresult(desc);
443    rows = INGfetchAll(query, res);
444    if (rows < 0) {
445      INGfreeINGresult(res);
446      return NULL;
447    }
448    return res;
449 }
450 void INGclear(INGresult *res)
451 {
452    if (res == NULL) {
453       return;
454    }
455    IISQLDA *desc = res->sqlda;
456    INGfreeINGresult(res);
457    INGfreeDescriptor(desc);
458 }
459 INGconn *INGconnectDB(char *dbname, char *user, char *passwd)
460 {
461    if (dbname == NULL || strlen(dbname) == 0) {
462       return NULL;
463    }
464    INGconn *dbconn = (INGconn *)malloc(sizeof(INGconn));
465    memset(dbconn, 0, sizeof(INGconn));
466 /* # line 480 "myingres.sc" */  
467   
468   char ingdbname[24];
469   char ingdbuser[32];
470   char ingdbpasw[32];
471   char conn_name[32];
472   int sess_id;
473 /* # line 486 "myingres.sc" */  
474   
475    bstrncpy(ingdbname, dbname, sizeof(ingdbname));
476    if (user != NULL) {
477       bstrncpy(ingdbuser, user, sizeof(ingdbuser));
478       if (passwd != NULL) {
479          bstrncpy(ingdbpasw, passwd, sizeof(ingdbpasw));
480       } else {
481          memset(ingdbpasw, 0, sizeof(ingdbpasw));
482       }
483 /* # line 497 "myingres.sc" */  /* connect */
484   {
485     IIsqInit(&sqlca);
486     IIsqUser(ingdbuser);
487     IIsqConnect(0,ingdbname,(char *)"-dbms_password",ingdbpasw,(char *)0, 
488     (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, 
489     (char *)0, (char *)0, (char *)0, (char *)0);
490   }
491 /* # line 501 "myingres.sc" */  /* host code */
492    } else {
493 /* # line 502 "myingres.sc" */  /* connect */
494   {
495     IIsqInit(&sqlca);
496     IIsqConnect(0,ingdbname,(char *)0, (char *)0, (char *)0, (char *)0, 
497     (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, 
498     (char *)0, (char *)0, (char *)0);
499   }
500 /* # line 503 "myingres.sc" */  /* host code */
501    }   
502 /* # line 505 "myingres.sc" */  /* inquire_sql */
503   {
504     IILQisInqSqlio((short *)0,1,32,31,conn_name,13);
505   }
506 /* # line 506 "myingres.sc" */  /* inquire_sql */
507   {
508     IILQisInqSqlio((short *)0,1,30,sizeof(sess_id),&sess_id,11);
509   }
510 /* # line 508 "myingres.sc" */  /* host code */
511    bstrncpy(dbconn->dbname, ingdbname, sizeof(dbconn->dbname));
512    bstrncpy(dbconn->user, ingdbuser, sizeof(dbconn->user));
513    bstrncpy(dbconn->password, ingdbpasw, sizeof(dbconn->password));
514    bstrncpy(dbconn->connection_name, conn_name, sizeof(dbconn->connection_name));
515    dbconn->session_id = sess_id;
516    dbconn->msg = (char*)malloc(257);
517    memset(dbconn->msg, 0, 257);
518    return dbconn;
519 }
520 void INGdisconnectDB(INGconn *dbconn)
521 {
522    /*
523     * TODO: check for any real use of dbconn: maybe whenn multithreaded?
524     */
525 /* # line 524 "myingres.sc" */  /* disconnect */
526   {
527     IIsqInit(&sqlca);
528     IIsqDisconnect();
529   }
530 /* # line 525 "myingres.sc" */  /* host code */
531    if (dbconn != NULL) {
532       free(dbconn->msg);
533       free(dbconn);
534    }
535 }
536 char *INGerrorMessage(const INGconn *conn)
537 {
538 /* # line 533 "myingres.sc" */  
539   
540   char errbuf[256];
541 /* # line 535 "myingres.sc" */  
542   
543 /* # line 537 "myingres.sc" */  /* inquire_ingres */
544   {
545     IILQisInqSqlio((short *)0,1,32,255,errbuf,63);
546   }
547 /* # line 538 "myingres.sc" */  /* host code */
548    memcpy(conn->msg,&errbuf,256);
549    return conn->msg;
550 }
551 char *INGcmdTuples(INGresult *res)
552 {
553    return res->numrowstring;
554 }
555 /* TODO?
556 int INGputCopyEnd(INGconn *conn, const char *errormsg);
557 int INGputCopyData(INGconn *conn, const char *buffer, int nbytes);
558 */
559 /* # line 552 "myingres.sc" */  
560 #endif