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