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