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