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