2 /* # line 3 "myingres.sc" */
5 extern IISQLCA sqlca; /* SQL Communications Area */
12 * ---Implementations---
16 return (sqlca.sqlcode < 0) ? sqlca.sqlcode : 0;
18 short INGgetCols(const char *stmt)
20 /* # line 23 "myingres.sc" */
23 /* # line 25 "myingres.sc" */
27 sqlda = (IISQLDA *)malloc(IISQDA_HEAD_SIZE + (number * IISQDA_VAR_SIZE));
28 memset(sqlda, 0, (IISQDA_HEAD_SIZE + (number * IISQDA_VAR_SIZE)));
30 stmtd = (char*)malloc(strlen(stmt)+1);
31 strncpy(stmtd,stmt,strlen(stmt)+1);
32 /* # line 38 "myingres.sc" */ /* prepare */
35 IIsqPrepare(0,(char *)"s1",(char *)0,0,stmtd);
37 /* # line 39 "myingres.sc" */ /* host code */
43 /* # line 44 "myingres.sc" */ /* describe */
46 IIsqDescribe(0,(char *)"s1",sqlda,0);
48 /* # line 45 "myingres.sc" */ /* host code */
55 free(stmtd); free(sqlda);
58 IISQLDA *INGgetDescriptor(short numCols, const char *stmt)
60 /* # line 58 "myingres.sc" */
63 /* # line 60 "myingres.sc" */
67 sqlda = (IISQLDA *)malloc(IISQDA_HEAD_SIZE + (numCols * IISQDA_VAR_SIZE));
68 memset(sqlda, 0, (IISQDA_HEAD_SIZE + (numCols * IISQDA_VAR_SIZE)));
69 sqlda->sqln = numCols;
70 stmtd = (char *)malloc(strlen(stmt)+1);
71 strncpy(stmtd,stmt,strlen(stmt)+1);
72 /* # line 73 "myingres.sc" */ /* prepare */
75 IIsqPrepare(0,(char *)"s2",sqlda,0,stmtd);
77 /* # line 75 "myingres.sc" */ /* host code */
79 for (i = 0; i < sqlda->sqld; ++i) {
81 * Alloc space for variable like indicated in sqllen
82 * for date types sqllen is always 0 -> allocate by type
84 switch (abs(sqlda->sqlvar[i].sqltype)) {
86 sqlda->sqlvar[i].sqldata = (char *)malloc(IISQ_TSW_LEN);
89 sqlda->sqlvar[i].sqldata = (char *)malloc(IISQ_TSWO_LEN);
92 sqlda->sqlvar[i].sqldata = (char *)malloc(IISQ_TSTMP_LEN);
95 sqlda->sqlvar[i].sqldata = (char *)malloc(sqlda->sqlvar[i].sqllen);
101 void INGfreeDescriptor(IISQLDA *sqlda)
104 for (i = 0; i < sqlda->sqld; ++i) {
105 free(sqlda->sqlvar[i].sqldata);
106 free(sqlda->sqlvar[i].sqlind);
111 int INGgetTypeSize(IISQLVAR *ingvar)
115 * TODO: add date types (at least TSTMP,TSW TSWO)
117 switch (ingvar->sqltype) {
125 inglength = ingvar->sqllen;
130 INGresult *INGgetINGresult(IISQLDA *sqlda)
133 INGresult *result = NULL;
134 result = (INGresult *)malloc(sizeof(INGresult));
135 memset(result, 0, sizeof(INGresult));
136 result->sqlda = sqlda;
137 result->num_fields = sqlda->sqld;
138 result->num_rows = 0;
139 result->first_row = NULL;
140 result->status = ING_EMPTY_RESULT;
141 result->act_row = NULL;
142 strcpy(result->numrowstring,"");
143 if (result->num_fields) {
144 result->fields = (INGRES_FIELD *)malloc(sizeof(INGRES_FIELD) * result->num_fields);
145 memset(result->fields, 0, sizeof(INGRES_FIELD) * result->num_fields);
146 for (i = 0; i < result->num_fields; ++i) {
147 memset(result->fields[i].name, 0, 34);
148 strncpy(result->fields[i].name, sqlda->sqlvar[i].sqlname.sqlnamec, sqlda->sqlvar[i].sqlname.sqlnamel);
149 result->fields[i].max_length = INGgetTypeSize(&sqlda->sqlvar[i]);
150 result->fields[i].type = abs(sqlda->sqlvar[i].sqltype);
151 result->fields[i].flags = (abs(sqlda->sqlvar[i].sqltype)<0) ? 1 : 0;
156 void INGfreeINGresult(INGresult *ing_res)
161 * Free all rows and fields, then res, not descriptor!
163 if (ing_res != NULL) {
165 * Use of rows is a nasty workaround til I find the reason,
166 * why aggregates like max() don't work
168 rows = ing_res->num_rows;
169 ing_res->act_row = ing_res->first_row;
170 while (ing_res->act_row != NULL && rows > 0) {
171 rowtemp = ing_res->act_row->next;
172 INGfreeRowSpace(ing_res->act_row, ing_res->sqlda);
173 ing_res->act_row = rowtemp;
176 if (ing_res->fields) {
177 free(ing_res->fields);
183 ING_ROW *INGgetRowSpace(INGresult *ing_res)
186 unsigned short len; /* used for VARCHAR type length */
187 IISQLDA *sqlda = ing_res->sqlda;
189 IISQLVAR *vars = NULL;
190 row = (ING_ROW *)malloc(sizeof(ING_ROW));
191 memset(row, 0, sizeof(ING_ROW));
192 vars = (IISQLVAR *)malloc(sizeof(IISQLVAR) * sqlda->sqld);
193 memset(vars, 0, sizeof(IISQLVAR) * sqlda->sqld);
196 for (i = 0; i < sqlda->sqld; ++i) {
198 * Make strings out of the data, then the space and assign
199 * (why string? at least it seems that way, looking into the sources)
201 switch (ing_res->fields[i].type) {
203 len = ((ING_VARCHAR *)sqlda->sqlvar[i].sqldata)->len;
204 vars[i].sqldata = (char *)malloc(len+1);
205 memcpy(vars[i].sqldata,sqlda->sqlvar[i].sqldata+2,len);
206 vars[i].sqldata[len] = '\0';
209 vars[i].sqldata = (char *)malloc(ing_res->fields[i].max_length+1);
210 memcpy(vars[i].sqldata,sqlda->sqlvar[i].sqldata,sqlda->sqlvar[i].sqllen);
211 vars[i].sqldata[ing_res->fields[i].max_length] = '\0';
214 vars[i].sqldata = (char *)malloc(20);
215 memset(vars[i].sqldata, 0, 20);
216 switch (sqlda->sqlvar[i].sqllen) {
218 snprintf(vars[i].sqldata, 20, "%d",*(short*)sqlda->sqlvar[i].sqldata);
221 snprintf(vars[i].sqldata, 20, "%d",*(int*)sqlda->sqlvar[i].sqldata);
224 snprintf(vars[i].sqldata, 20, "%d",*(long*)sqlda->sqlvar[i].sqldata);
228 case IISQ_TSTMP_TYPE:
229 vars[i].sqldata = (char *)malloc(IISQ_TSTMP_LEN+1);
230 vars[i].sqldata[IISQ_TSTMP_LEN] = '\0';
233 vars[i].sqldata = (char *)malloc(IISQ_TSWO_LEN+1);
234 vars[i].sqldata[IISQ_TSWO_LEN] = '\0';
237 vars[i].sqldata = (char *)malloc(IISQ_TSW_LEN+1);
238 vars[i].sqldata[IISQ_TSW_LEN] = '\0';
241 vars[i].sqlind = (short *)malloc(sizeof(short));
242 memcpy(vars[i].sqlind,sqlda->sqlvar[i].sqlind,sizeof(short));
246 void INGfreeRowSpace(ING_ROW *row, IISQLDA *sqlda)
249 if (row == NULL || sqlda == NULL) {
252 for (i = 0; i < sqlda->sqld; ++i) {
253 free(row->sqlvar[i].sqldata);
254 free(row->sqlvar[i].sqlind);
259 int INGfetchAll(const char *stmt, INGresult *ing_res)
265 desc = ing_res->sqlda;
266 /* # line 292 "myingres.sc" */ /* host code */
267 if ((check = INGcheck()) < 0) {
270 /* # line 296 "myingres.sc" */ /* open */
273 IIcsOpen((char *)"c2",1824,27390);
274 IIwritio(0,(short *)0,1,32,0,(char *)"s2");
275 IIcsQuery((char *)"c2",1824,27390);
277 /* # line 297 "myingres.sc" */ /* host code */
278 if ((check = INGcheck()) < 0) {
281 /* for (linecount = 0; sqlca.sqlcode == 0; ++linecount) */
282 while(sqlca.sqlcode == 0) {
283 /* # line 303 "myingres.sc" */ /* fetch */
286 if (IIcsRetScroll((char *)"c2",1824,27390,-1,-1) != 0) {
291 /* # line 304 "myingres.sc" */ /* host code */
292 if ((check = INGcheck()) < 0) { return check;}
293 if (sqlca.sqlcode == 0)
295 row = INGgetRowSpace(ing_res); /* alloc space for fetched row */
297 * Initialize list when encountered first time
299 if (ing_res->first_row == 0) {
300 ing_res->first_row = row; /* head of the list */
301 ing_res->first_row->next = NULL;
302 ing_res->act_row = ing_res->first_row;
304 ing_res->act_row->next = row; /* append row to old act_row */
305 ing_res->act_row = row; /* set row as act_row */
306 row->row_number = linecount;
310 /* # line 325 "myingres.sc" */ /* close */
313 IIcsClose((char *)"c2",1824,27390);
315 /* # line 327 "myingres.sc" */ /* host code */
316 ing_res->status = ING_COMMAND_OK;
317 ing_res->num_rows = linecount;
320 ING_STATUS INGresultStatus(INGresult *res)
322 if (res == NULL) {return ING_NO_RESULT;}
325 void INGrowSeek(INGresult *res, int row_number)
328 if (res->act_row->row_number == row_number) {
332 * TODO: real error handling
334 if (row_number<0 || row_number>res->num_rows) {
337 for (trow = res->first_row; trow->row_number != row_number; trow = trow->next) ;
340 * Note - can be null - if row_number not found, right?
343 char *INGgetvalue(INGresult *res, int row_number, int column_number)
345 if (row_number != res->act_row->row_number) {
346 INGrowSeek(res, row_number);
348 return res->act_row->sqlvar[column_number].sqldata;
350 int INGgetisnull(INGresult *res, int row_number, int column_number)
352 if (row_number != res->act_row->row_number) {
353 INGrowSeek(res, row_number);
355 return (short)*res->act_row->sqlvar[column_number].sqlind;
357 int INGntuples(const INGresult *res)
359 return res->num_rows;
361 int INGnfields(const INGresult *res)
363 return res->num_fields;
365 char *INGfname(const INGresult *res, int column_number)
367 if ((column_number > res->num_fields) || (column_number < 0)) {
370 return res->fields[column_number].name;
373 short INGftype(const INGresult *res, int column_number)
375 return res->fields[column_number].type;
377 int INGexec(INGconn *conn, const char *query)
380 /* # line 402 "myingres.sc" */
384 /* # line 405 "myingres.sc" */
386 stmt = (char *)malloc(strlen(query)+1);
387 strncpy(stmt,query,strlen(query)+1);
389 /* # line 411 "myingres.sc" */ /* execute */
393 IIsyncup((char *)0,0);
395 /* # line 412 "myingres.sc" */ /* host code */
397 if ((check = INGcheck()) < 0) {
400 /* # line 417 "myingres.sc" */ /* inquire_ingres */
402 IILQisInqSqlio((short *)0,1,30,sizeof(rowcount),&rowcount,8);
404 /* # line 418 "myingres.sc" */ /* host code */
405 if ((check = INGcheck()) < 0) {
410 INGresult *INGquery(INGconn *conn, const char *query)
413 * TODO: error handling
415 IISQLDA *desc = NULL;
416 INGresult *res = NULL;
418 int cols = INGgetCols(query);
419 desc = INGgetDescriptor(cols, query);
420 res = INGgetINGresult(desc);
421 rows = INGfetchAll(query, res);
423 INGfreeINGresult(res);
428 void INGclear(INGresult *res)
433 IISQLDA *desc = res->sqlda;
434 INGfreeINGresult(res);
435 INGfreeDescriptor(desc);
437 INGconn *INGconnectDB(char *dbname, char *user, char *passwd)
439 if (dbname == NULL || strlen(dbname) == 0) {
442 INGconn *dbconn = (INGconn *)malloc(sizeof(INGconn));
443 memset(dbconn, 0, sizeof(INGconn));
444 /* # line 465 "myingres.sc" */
451 /* # line 471 "myingres.sc" */
453 strcpy(ingdbname,dbname);
455 strcpy(ingdbuser,user);
456 if (passwd != NULL) {
457 strcpy(ingdbpasw,passwd);
459 strcpy(ingdbpasw, "");
461 /* # line 482 "myingres.sc" */ /* connect */
465 IIsqConnect(0,ingdbname,(char *)"-dbms_password",ingdbpasw,(char *)0,
466 (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0,
467 (char *)0, (char *)0, (char *)0, (char *)0);
469 /* # line 486 "myingres.sc" */ /* host code */
471 /* # line 487 "myingres.sc" */ /* connect */
474 IIsqConnect(0,ingdbname,(char *)0, (char *)0, (char *)0, (char *)0,
475 (char *)0, (char *)0, (char *)0, (char *)0, (char *)0, (char *)0,
476 (char *)0, (char *)0, (char *)0);
478 /* # line 488 "myingres.sc" */ /* host code */
480 /* # line 490 "myingres.sc" */ /* inquire_sql */
482 IILQisInqSqlio((short *)0,1,32,31,conn_name,13);
484 /* # line 491 "myingres.sc" */ /* inquire_sql */
486 IILQisInqSqlio((short *)0,1,30,sizeof(sess_id),&sess_id,11);
488 /* # line 493 "myingres.sc" */ /* host code */
489 strncpy(dbconn->dbname, ingdbname, sizeof(dbconn->dbname));
490 strncpy(dbconn->user, ingdbuser, sizeof(dbconn->user));
491 strncpy(dbconn->password, ingdbpasw, sizeof(dbconn->password));
492 strncpy(dbconn->connection_name, conn_name, sizeof(dbconn->connection_name));
493 dbconn->session_id = sess_id;
494 dbconn->msg = (char*)malloc(257);
495 memset(dbconn->msg, 0, 257);
498 void INGdisconnectDB(INGconn *dbconn)
501 * TODO: check for any real use of dbconn: maybe whenn multithreaded?
503 /* # line 509 "myingres.sc" */ /* disconnect */
508 /* # line 510 "myingres.sc" */ /* host code */
509 if (dbconn != NULL) {
514 char *INGerrorMessage(const INGconn *conn)
516 /* # line 518 "myingres.sc" */
519 /* # line 520 "myingres.sc" */
521 /* # line 522 "myingres.sc" */ /* inquire_ingres */
523 IILQisInqSqlio((short *)0,1,32,255,errbuf,63);
525 /* # line 523 "myingres.sc" */ /* host code */
526 memcpy(conn->msg,&errbuf,256);
529 char *INGcmdTuples(INGresult *res)
531 return res->numrowstring;
534 int INGputCopyEnd(INGconn *conn, const char *errormsg);
535 int INGputCopyData(INGconn *conn, const char *buffer, int nbytes);
537 /* # line 537 "myingres.sc" */