2 /* # line 3 "myingres.sc" */
7 extern IISQLCA sqlca; /* SQL Communications Area */
14 * ---Implementations---
18 return (sqlca.sqlcode < 0) ? sqlca.sqlcode : 0;
20 short INGgetCols(const char *stmt)
22 /* # line 23 "myingres.sc" */
25 /* # line 25 "myingres.sc" */
29 sqlda = (IISQLDA *)malloc(IISQDA_HEAD_SIZE + (number * IISQDA_VAR_SIZE));
30 memset(sqlda, 0, (IISQDA_HEAD_SIZE + (number * IISQDA_VAR_SIZE)));
32 stmtd = (char*)malloc(strlen(stmt)+1);
33 bstrncpy(stmtd,stmt,strlen(stmt)+1);
34 /* # line 38 "myingres.sc" */ /* prepare */
37 IIsqPrepare(0,(char *)"s1",(char *)0,0,stmtd);
39 /* # line 39 "myingres.sc" */ /* host code */
45 /* # line 44 "myingres.sc" */ /* describe */
48 IIsqDescribe(0,(char *)"s1",sqlda,0);
50 /* # line 45 "myingres.sc" */ /* host code */
61 IISQLDA *INGgetDescriptor(short numCols, const char *stmt)
63 /* # line 59 "myingres.sc" */
66 /* # line 61 "myingres.sc" */
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 */
78 IIsqPrepare(0,(char *)"s2",sqlda,0,stmtd);
80 /* # line 76 "myingres.sc" */ /* host code */
82 for (i = 0; i < sqlda->sqld; ++i) {
84 * Alloc space for variable like indicated in sqllen
85 * for date types sqllen is always 0 -> allocate by type
87 switch (abs(sqlda->sqlvar[i].sqltype)) {
89 sqlda->sqlvar[i].sqldata = (char *)malloc(IISQ_TSW_LEN);
92 sqlda->sqlvar[i].sqldata = (char *)malloc(IISQ_TSWO_LEN);
95 sqlda->sqlvar[i].sqldata = (char *)malloc(IISQ_TSTMP_LEN);
98 sqlda->sqlvar[i].sqldata = (char *)malloc(sqlda->sqlvar[i].sqllen);
104 void INGfreeDescriptor(IISQLDA *sqlda)
107 for (i = 0; i < sqlda->sqld; ++i) {
108 if (sqlda->sqlvar[i].sqldata) {
109 free(sqlda->sqlvar[i].sqldata);
111 if (sqlda->sqlvar[i].sqlind) {
112 free(sqlda->sqlvar[i].sqlind);
118 int INGgetTypeSize(IISQLVAR *ingvar)
122 * TODO: add date types (at least TSTMP,TSW TSWO)
124 switch (ingvar->sqltype) {
132 inglength = ingvar->sqllen;
137 INGresult *INGgetINGresult(IISQLDA *sqlda)
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;
163 void INGfreeINGresult(INGresult *ing_res)
168 * Free all rows and fields, then res, not descriptor!
170 if (ing_res != NULL) {
172 * Use of rows is a nasty workaround til I find the reason,
173 * why aggregates like max() don't work
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;
183 if (ing_res->fields) {
184 free(ing_res->fields);
190 ING_ROW *INGgetRowSpace(INGresult *ing_res)
193 unsigned short len; /* used for VARCHAR type length */
194 IISQLDA *sqlda = ing_res->sqlda;
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);
203 for (i = 0; i < sqlda->sqld; ++i) {
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)
208 switch (ing_res->fields[i].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';
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';
221 vars[i].sqldata = (char *)malloc(20);
222 memset(vars[i].sqldata, 0, 20);
223 switch (sqlda->sqlvar[i].sqllen) {
225 bsnprintf(vars[i].sqldata, 20, "%d",*(short*)sqlda->sqlvar[i].sqldata);
228 bsnprintf(vars[i].sqldata, 20, "%ld",*(int*)sqlda->sqlvar[i].sqldata);
231 bsnprintf(vars[i].sqldata, 20, "%lld",*(long*)sqlda->sqlvar[i].sqldata);
235 case IISQ_TSTMP_TYPE:
236 vars[i].sqldata = (char *)malloc(IISQ_TSTMP_LEN+1);
237 vars[i].sqldata[IISQ_TSTMP_LEN] = '\0';
240 vars[i].sqldata = (char *)malloc(IISQ_TSWO_LEN+1);
241 vars[i].sqldata[IISQ_TSWO_LEN] = '\0';
244 vars[i].sqldata = (char *)malloc(IISQ_TSW_LEN+1);
245 vars[i].sqldata[IISQ_TSW_LEN] = '\0';
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));
257 void INGfreeRowSpace(ING_ROW *row, IISQLDA *sqlda)
260 if (row == NULL || sqlda == NULL) {
263 for (i = 0; i < sqlda->sqld; ++i) {
264 if (row->sqlvar[i].sqldata) {
265 free(row->sqlvar[i].sqldata);
267 if (row->sqlvar[i].sqlind) {
268 free(row->sqlvar[i].sqlind);
274 int INGfetchAll(const char *stmt, INGresult *ing_res)
280 desc = ing_res->sqlda;
281 /* # line 305 "myingres.sc" */ /* host code */
282 if ((check = INGcheck()) < 0) {
285 /* # line 309 "myingres.sc" */ /* open */
288 IIcsOpen((char *)"c2",4824,17405);
289 IIwritio(0,(short *)0,1,32,0,(char *)"s2");
290 IIcsQuery((char *)"c2",4824,17405);
292 /* # line 310 "myingres.sc" */ /* host code */
293 if ((check = INGcheck()) < 0) {
296 /* for (linecount = 0; sqlca.sqlcode == 0; ++linecount) */
297 while(sqlca.sqlcode == 0) {
298 /* # line 316 "myingres.sc" */ /* fetch */
301 if (IIcsRetScroll((char *)"c2",4824,17405,-1,-1) != 0) {
306 /* # line 317 "myingres.sc" */ /* host code */
307 if ((check = INGcheck()) < 0) {
308 /* # line 318 "myingres.sc" */ /* close */
311 IIcsClose((char *)"c2",4824,17405);
313 /* # line 319 "myingres.sc" */ /* host code */
316 if (sqlca.sqlcode == 0) {
317 row = INGgetRowSpace(ing_res); /* alloc space for fetched row */
319 * Initialize list when encountered first time
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;
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;
332 /* # line 340 "myingres.sc" */ /* close */
335 IIcsClose((char *)"c2",4824,17405);
337 /* # line 342 "myingres.sc" */ /* host code */
338 ing_res->status = ING_COMMAND_OK;
339 ing_res->num_rows = linecount;
342 ING_STATUS INGresultStatus(INGresult *res)
344 if (res == NULL) {return ING_NO_RESULT;}
347 void INGrowSeek(INGresult *res, int row_number)
350 if (res->act_row->row_number == row_number) {
354 * TODO: real error handling
356 if (row_number<0 || row_number>res->num_rows) {
359 for (trow = res->first_row; trow->row_number != row_number; trow = trow->next) ;
362 * Note - can be null - if row_number not found, right?
365 char *INGgetvalue(INGresult *res, int row_number, int column_number)
367 if (row_number != res->act_row->row_number) {
368 INGrowSeek(res, row_number);
370 return res->act_row->sqlvar[column_number].sqldata;
372 int INGgetisnull(INGresult *res, int row_number, int column_number)
374 if (row_number != res->act_row->row_number) {
375 INGrowSeek(res, row_number);
377 return (short)*res->act_row->sqlvar[column_number].sqlind;
379 int INGntuples(const INGresult *res)
381 return res->num_rows;
383 int INGnfields(const INGresult *res)
385 return res->num_fields;
387 char *INGfname(const INGresult *res, int column_number)
389 if ((column_number > res->num_fields) || (column_number < 0)) {
392 return res->fields[column_number].name;
395 short INGftype(const INGresult *res, int column_number)
397 return res->fields[column_number].type;
399 int INGexec(INGconn *conn, const char *query)
402 /* # line 417 "myingres.sc" */
406 /* # line 420 "myingres.sc" */
408 stmt = (char *)malloc(strlen(query)+1);
409 bstrncpy(stmt,query,strlen(query)+1);
411 /* # line 426 "myingres.sc" */ /* execute */
415 IIsyncup((char *)0,0);
417 /* # line 427 "myingres.sc" */ /* host code */
419 if ((check = INGcheck()) < 0) {
422 /* # line 432 "myingres.sc" */ /* inquire_ingres */
424 IILQisInqSqlio((short *)0,1,30,sizeof(rowcount),&rowcount,8);
426 /* # line 433 "myingres.sc" */ /* host code */
427 if ((check = INGcheck()) < 0) {
432 INGresult *INGquery(INGconn *conn, const char *query)
435 * TODO: error handling
437 IISQLDA *desc = NULL;
438 INGresult *res = NULL;
440 int cols = INGgetCols(query);
441 desc = INGgetDescriptor(cols, query);
442 res = INGgetINGresult(desc);
443 rows = INGfetchAll(query, res);
445 INGfreeINGresult(res);
450 void INGclear(INGresult *res)
455 IISQLDA *desc = res->sqlda;
456 INGfreeINGresult(res);
457 INGfreeDescriptor(desc);
459 INGconn *INGconnectDB(char *dbname, char *user, char *passwd)
461 if (dbname == NULL || strlen(dbname) == 0) {
464 INGconn *dbconn = (INGconn *)malloc(sizeof(INGconn));
465 memset(dbconn, 0, sizeof(INGconn));
466 /* # line 480 "myingres.sc" */
473 /* # line 486 "myingres.sc" */
475 bstrncpy(ingdbname, dbname, sizeof(ingdbname));
477 bstrncpy(ingdbuser, user, sizeof(ingdbuser));
478 if (passwd != NULL) {
479 bstrncpy(ingdbpasw, passwd, sizeof(ingdbpasw));
481 memset(ingdbpasw, 0, sizeof(ingdbpasw));
483 /* # line 497 "myingres.sc" */ /* connect */
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);
491 /* # line 501 "myingres.sc" */ /* host code */
493 /* # line 502 "myingres.sc" */ /* connect */
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);
500 /* # line 503 "myingres.sc" */ /* host code */
502 /* # line 505 "myingres.sc" */ /* inquire_sql */
504 IILQisInqSqlio((short *)0,1,32,31,conn_name,13);
506 /* # line 506 "myingres.sc" */ /* inquire_sql */
508 IILQisInqSqlio((short *)0,1,30,sizeof(sess_id),&sess_id,11);
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);
520 void INGdisconnectDB(INGconn *dbconn)
523 * TODO: check for any real use of dbconn: maybe whenn multithreaded?
525 /* # line 524 "myingres.sc" */ /* disconnect */
530 /* # line 525 "myingres.sc" */ /* host code */
531 if (dbconn != NULL) {
536 char *INGerrorMessage(const INGconn *conn)
538 /* # line 533 "myingres.sc" */
541 /* # line 535 "myingres.sc" */
543 /* # line 537 "myingres.sc" */ /* inquire_ingres */
545 IILQisInqSqlio((short *)0,1,32,255,errbuf,63);
547 /* # line 538 "myingres.sc" */ /* host code */
548 memcpy(conn->msg,&errbuf,256);
551 char *INGcmdTuples(INGresult *res)
553 return res->numrowstring;
556 int INGputCopyEnd(INGconn *conn, const char *errormsg);
557 int INGputCopyData(INGconn *conn, const char *buffer, int nbytes);
559 /* # line 552 "myingres.sc" */