2 /* # line 3 "myingres.sc" */
7 extern IISQLCA sqlca; /* SQL Communications Area */
9 /* # line 7 "myingres.sc" */ /* host code */
15 * ---Implementations---
19 return (sqlca.sqlcode < 0) ? sqlca.sqlcode : 0;
21 short INGgetCols(const char *stmt)
23 /* # line 23 "myingres.sc" */
26 /* # line 25 "myingres.sc" */
30 sqlda = (IISQLDA *)malloc(IISQDA_HEAD_SIZE + (number * IISQDA_VAR_SIZE));
31 memset(sqlda, 0, (IISQDA_HEAD_SIZE + (number * IISQDA_VAR_SIZE)));
33 stmtd = (char*)malloc(strlen(stmt)+1);
34 bstrncpy(stmtd,stmt,strlen(stmt)+1);
35 /* # line 38 "myingres.sc" */ /* prepare */
38 IIsqPrepare(0,(char *)"s1",(char *)0,0,stmtd);
40 /* # line 39 "myingres.sc" */ /* host code */
46 /* # line 44 "myingres.sc" */ /* describe */
49 IIsqDescribe(0,(char *)"s1",sqlda,0);
51 /* # line 45 "myingres.sc" */ /* host code */
62 IISQLDA *INGgetDescriptor(short numCols, const char *stmt)
64 /* # line 59 "myingres.sc" */
67 /* # line 61 "myingres.sc" */
71 sqlda = (IISQLDA *)malloc(IISQDA_HEAD_SIZE + (numCols * IISQDA_VAR_SIZE));
72 memset(sqlda, 0, (IISQDA_HEAD_SIZE + (numCols * IISQDA_VAR_SIZE)));
73 sqlda->sqln = numCols;
74 stmtd = (char *)malloc(strlen(stmt)+1);
75 bstrncpy(stmtd,stmt,strlen(stmt)+1);
76 /* # line 74 "myingres.sc" */ /* prepare */
79 IIsqPrepare(0,(char *)"s2",sqlda,0,stmtd);
81 /* # line 76 "myingres.sc" */ /* host code */
83 for (i = 0; i < sqlda->sqld; ++i) {
85 * Negative type indicates nullable coulumns, so an indicator
86 * is allocated, otherwise it's null
88 if (sqlda->sqlvar[i].sqltype > 0) {
89 sqlda->sqlvar[i].sqlind = NULL;
91 sqlda->sqlvar[i].sqlind = (short *)malloc(sizeof(short));
94 * Alloc space for variable like indicated in sqllen
95 * for date types sqllen is always 0 -> allocate by type
97 switch (abs(sqlda->sqlvar[i].sqltype)) {
99 sqlda->sqlvar[i].sqldata = (char *)malloc(IISQ_TSW_LEN);
102 sqlda->sqlvar[i].sqldata = (char *)malloc(IISQ_TSWO_LEN);
104 case IISQ_TSTMP_TYPE:
105 sqlda->sqlvar[i].sqldata = (char *)malloc(IISQ_TSTMP_LEN);
109 * plus one to avoid zero mem allocs
111 sqlda->sqlvar[i].sqldata = (char *)malloc(sqlda->sqlvar[i].sqllen+1);
117 void INGfreeDescriptor(IISQLDA *sqlda)
123 for (i = 0; i < sqlda->sqld; ++i) {
124 if (sqlda->sqlvar[i].sqldata) {
125 free(sqlda->sqlvar[i].sqldata);
127 if (sqlda->sqlvar[i].sqlind) {
128 free(sqlda->sqlvar[i].sqlind);
134 int INGgetTypeSize(IISQLVAR *ingvar)
138 * TODO: add date types (at least TSTMP,TSW TSWO)
140 switch (ingvar->sqltype) {
148 inglength = ingvar->sqllen;
153 INGresult *INGgetINGresult(IISQLDA *sqlda)
159 INGresult *result = NULL;
160 result = (INGresult *)malloc(sizeof(INGresult));
161 memset(result, 0, sizeof(INGresult));
162 result->sqlda = sqlda;
163 result->num_fields = sqlda->sqld;
164 result->num_rows = 0;
165 result->first_row = NULL;
166 result->status = ING_EMPTY_RESULT;
167 result->act_row = NULL;
168 memset(result->numrowstring, 0, sizeof(result->numrowstring));
169 if (result->num_fields) {
170 result->fields = (INGRES_FIELD *)malloc(sizeof(INGRES_FIELD) * result->num_fields);
171 memset(result->fields, 0, sizeof(INGRES_FIELD) * result->num_fields);
172 for (i = 0; i < result->num_fields; ++i) {
173 memset(result->fields[i].name, 0, 34);
174 bstrncpy(result->fields[i].name, sqlda->sqlvar[i].sqlname.sqlnamec, sqlda->sqlvar[i].sqlname.sqlnamel);
175 result->fields[i].max_length = INGgetTypeSize(&sqlda->sqlvar[i]);
176 result->fields[i].type = abs(sqlda->sqlvar[i].sqltype);
177 result->fields[i].flags = (sqlda->sqlvar[i].sqltype < 0) ? 1 : 0;
182 void INGfreeINGresult(INGresult *ing_res)
190 * Free all rows and fields, then res, not descriptor!
192 if (ing_res != NULL) {
194 * Use of rows is a nasty workaround til I find the reason,
195 * why aggregates like max() don't work
197 rows = ing_res->num_rows;
198 ing_res->act_row = ing_res->first_row;
199 while (ing_res->act_row != NULL && rows > 0) {
200 rowtemp = ing_res->act_row->next;
201 INGfreeRowSpace(ing_res->act_row, ing_res->sqlda);
202 ing_res->act_row = rowtemp;
205 if (ing_res->fields) {
206 free(ing_res->fields);
212 ING_ROW *INGgetRowSpace(INGresult *ing_res)
215 unsigned short len; /* used for VARCHAR type length */
216 IISQLDA *sqlda = ing_res->sqlda;
218 IISQLVAR *vars = NULL;
219 row = (ING_ROW *)malloc(sizeof(ING_ROW));
220 memset(row, 0, sizeof(ING_ROW));
221 vars = (IISQLVAR *)malloc(sizeof(IISQLVAR) * sqlda->sqld);
222 memset(vars, 0, sizeof(IISQLVAR) * sqlda->sqld);
225 for (i = 0; i < sqlda->sqld; ++i) {
227 * Make strings out of the data, then the space and assign
228 * (why string? at least it seems that way, looking into the sources)
230 vars[i].sqlind = (short *)malloc(sizeof(short));
231 if (sqlda->sqlvar[i].sqlind) {
232 memcpy(vars[i].sqlind,sqlda->sqlvar[i].sqlind,sizeof(short));
234 *vars[i].sqlind = NULL;
237 * if sqlind pointer exists AND points to -1 -> column is 'null'
239 if ( *vars[i].sqlind && (*vars[i].sqlind == -1)) {
240 vars[i].sqldata = NULL;
242 switch (ing_res->fields[i].type) {
244 len = ((ING_VARCHAR *)sqlda->sqlvar[i].sqldata)->len;
245 vars[i].sqldata = (char *)malloc(len+1);
246 memcpy(vars[i].sqldata,sqlda->sqlvar[i].sqldata+2,len);
247 vars[i].sqldata[len] = '\0';
250 vars[i].sqldata = (char *)malloc(ing_res->fields[i].max_length+1);
251 memcpy(vars[i].sqldata,sqlda->sqlvar[i].sqldata,sqlda->sqlvar[i].sqllen);
252 vars[i].sqldata[ing_res->fields[i].max_length] = '\0';
255 vars[i].sqldata = (char *)malloc(20);
256 memset(vars[i].sqldata, 0, 20);
257 switch (sqlda->sqlvar[i].sqllen) {
260 bsnprintf(vars[i].sqldata, 20, "%hd",*(signed short*)sqlda->sqlvar[i].sqldata);
263 bsnprintf(vars[i].sqldata, 20, "%d",*(signed int*)sqlda->sqlvar[i].sqldata);
266 bsnprintf(vars[i].sqldata, 20, "%ld",*(signed long*)sqlda->sqlvar[i].sqldata);
270 case IISQ_TSTMP_TYPE:
271 vars[i].sqldata = (char *)malloc(IISQ_TSTMP_LEN+1);
272 vars[i].sqldata[IISQ_TSTMP_LEN] = '\0';
275 vars[i].sqldata = (char *)malloc(IISQ_TSWO_LEN+1);
276 vars[i].sqldata[IISQ_TSWO_LEN] = '\0';
279 vars[i].sqldata = (char *)malloc(IISQ_TSW_LEN+1);
280 vars[i].sqldata[IISQ_TSW_LEN] = '\0';
287 void INGfreeRowSpace(ING_ROW *row, IISQLDA *sqlda)
290 if (row == NULL || sqlda == NULL) {
293 for (i = 0; i < sqlda->sqld; ++i) {
294 if (row->sqlvar[i].sqldata) {
295 free(row->sqlvar[i].sqldata);
297 if (row->sqlvar[i].sqlind) {
298 free(row->sqlvar[i].sqlind);
304 int INGfetchAll(const char *stmt, INGresult *ing_res)
310 desc = ing_res->sqlda;
311 /* # line 335 "myingres.sc" */ /* host code */
312 if ((check = INGcheck()) < 0) {
315 /* # line 339 "myingres.sc" */ /* open */
318 IIcsOpen((char *)"c2",10703,7614);
319 IIwritio(0,(short *)0,1,32,0,(char *)"s2");
320 IIcsQuery((char *)"c2",10703,7614);
322 /* # line 340 "myingres.sc" */ /* host code */
323 if ((check = INGcheck()) < 0) {
326 /* for (linecount = 0; sqlca.sqlcode == 0; ++linecount) */
328 /* # line 346 "myingres.sc" */ /* fetch */
331 if (IIcsRetScroll((char *)"c2",10703,7614,-1,-1) != 0) {
336 /* # line 348 "myingres.sc" */ /* host code */
337 if ( (sqlca.sqlcode == 0) || (sqlca.sqlcode == -40202) ) {
338 row = INGgetRowSpace(ing_res); /* alloc space for fetched row */
340 * Initialize list when encountered first time
342 if (ing_res->first_row == 0) {
343 ing_res->first_row = row; /* head of the list */
344 ing_res->first_row->next = NULL;
345 ing_res->act_row = ing_res->first_row;
347 ing_res->act_row->next = row; /* append row to old act_row */
348 ing_res->act_row = row; /* set row as act_row */
349 row->row_number = linecount;
352 } while ( (sqlca.sqlcode == 0) || (sqlca.sqlcode == -40202) );
353 /* # line 366 "myingres.sc" */ /* close */
356 IIcsClose((char *)"c2",10703,7614);
358 /* # line 368 "myingres.sc" */ /* host code */
359 ing_res->status = ING_COMMAND_OK;
360 ing_res->num_rows = linecount;
363 ING_STATUS INGresultStatus(INGresult *res)
365 if (res == NULL) {return ING_NO_RESULT;}
368 void INGrowSeek(INGresult *res, int row_number)
370 ING_ROW *trow = NULL;
371 if (res->act_row->row_number == row_number) {
375 * TODO: real error handling
377 if (row_number<0 || row_number>res->num_rows) {
380 for (trow = res->first_row ; trow->row_number != row_number ; trow = trow->next );
383 * Note - can be null - if row_number not found, right?
386 char *INGgetvalue(INGresult *res, int row_number, int column_number)
388 if (row_number != res->act_row->row_number) {
389 INGrowSeek(res, row_number);
391 return res->act_row->sqlvar[column_number].sqldata;
393 int INGgetisnull(INGresult *res, int row_number, int column_number)
395 if (row_number != res->act_row->row_number) {
396 INGrowSeek(res, row_number);
398 return (*res->act_row->sqlvar[column_number].sqlind == -1) ? 1 : 0;
400 int INGntuples(const INGresult *res)
402 return res->num_rows;
404 int INGnfields(const INGresult *res)
406 return res->num_fields;
408 char *INGfname(const INGresult *res, int column_number)
410 if ((column_number > res->num_fields) || (column_number < 0)) {
413 return res->fields[column_number].name;
416 short INGftype(const INGresult *res, int column_number)
418 return res->fields[column_number].type;
420 int INGexec(INGconn *conn, const char *query)
423 /* # line 443 "myingres.sc" */
427 /* # line 446 "myingres.sc" */
429 stmt = (char *)malloc(strlen(query)+1);
430 bstrncpy(stmt,query,strlen(query)+1);
432 /* # line 452 "myingres.sc" */ /* execute */
436 IIsyncup((char *)0,0);
438 /* # line 453 "myingres.sc" */ /* host code */
440 if ((check = INGcheck()) < 0) {
443 /* # line 458 "myingres.sc" */ /* inquire_ingres */
445 IILQisInqSqlio((short *)0,1,30,sizeof(rowcount),&rowcount,8);
447 /* # line 459 "myingres.sc" */ /* host code */
448 if ((check = INGcheck()) < 0) {
453 INGresult *INGquery(INGconn *conn, const char *query)
456 * TODO: error handling
458 IISQLDA *desc = NULL;
459 INGresult *res = NULL;
461 int cols = INGgetCols(query);
462 desc = INGgetDescriptor(cols, query);
466 res = INGgetINGresult(desc);
470 rows = INGfetchAll(query, res);
472 INGfreeINGresult(res);
473 INGfreeDescriptor(desc);
478 void INGclear(INGresult *res)
483 IISQLDA *desc = res->sqlda;
484 INGfreeINGresult(res);
485 INGfreeDescriptor(desc);
487 INGconn *INGconnectDB(char *dbname, char *user, char *passwd)
489 if (dbname == NULL || strlen(dbname) == 0) {
492 INGconn *dbconn = (INGconn *)malloc(sizeof(INGconn));
493 memset(dbconn, 0, sizeof(INGconn));
494 /* # line 513 "myingres.sc" */
501 /* # line 519 "myingres.sc" */
503 bstrncpy(ingdbname, dbname, sizeof(ingdbname));
505 bstrncpy(ingdbuser, user, sizeof(ingdbuser));
506 if (passwd != NULL) {
507 bstrncpy(ingdbpasw, passwd, sizeof(ingdbpasw));
509 memset(ingdbpasw, 0, sizeof(ingdbpasw));
511 /* # line 530 "myingres.sc" */ /* connect */
515 IIsqConnect(0,ingdbname,(char *)"-dbms_password",ingdbpasw,(char *)0,
516 (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0,
517 (char *)0, (char *)0, (char *)0, (char *)0);
519 /* # line 534 "myingres.sc" */ /* host code */
521 /* # line 535 "myingres.sc" */ /* connect */
524 IIsqConnect(0,ingdbname,(char *)0, (char *)0, (char *)0, (char *)0,
525 (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0,
526 (char *)0, (char *)0, (char *)0);
528 /* # line 536 "myingres.sc" */ /* host code */
530 /* # line 538 "myingres.sc" */ /* inquire_sql */
532 IILQisInqSqlio((short *)0,1,32,31,conn_name,13);
534 /* # line 539 "myingres.sc" */ /* inquire_sql */
536 IILQisInqSqlio((short *)0,1,30,sizeof(sess_id),&sess_id,11);
538 /* # line 541 "myingres.sc" */ /* host code */
539 bstrncpy(dbconn->dbname, ingdbname, sizeof(dbconn->dbname));
540 bstrncpy(dbconn->user, ingdbuser, sizeof(dbconn->user));
541 bstrncpy(dbconn->password, ingdbpasw, sizeof(dbconn->password));
542 bstrncpy(dbconn->connection_name, conn_name, sizeof(dbconn->connection_name));
543 dbconn->session_id = sess_id;
544 dbconn->msg = (char*)malloc(257);
545 memset(dbconn->msg, 0, 257);
548 void INGdisconnectDB(INGconn *dbconn)
551 * TODO: check for any real use of dbconn: maybe whenn multithreaded?
553 /* # line 557 "myingres.sc" */ /* disconnect */
558 /* # line 558 "myingres.sc" */ /* host code */
559 if (dbconn != NULL) {
564 char *INGerrorMessage(const INGconn *conn)
566 /* # line 566 "myingres.sc" */
569 /* # line 568 "myingres.sc" */
571 /* # line 570 "myingres.sc" */ /* inquire_ingres */
573 IILQisInqSqlio((short *)0,1,32,255,errbuf,63);
575 /* # line 571 "myingres.sc" */ /* host code */
576 memcpy(conn->msg,&errbuf,256);
579 char *INGcmdTuples(INGresult *res)
581 return res->numrowstring;
584 int INGputCopyEnd(INGconn *conn, const char *errormsg);
585 int INGputCopyData(INGconn *conn, const char *buffer, int nbytes);
587 /* # line 585 "myingres.sc" */