due to buffer overlap it was dumping core
[csql.git] / src / sqlnetwork / SqlNwStatement.cxx
blob99b06c65f01fc51e1487ebc2427762655acea5c4
1 /***************************************************************************
2 * Copyright (C) 2007 by Prabakaran Thirumalai *
3 * praba_tuty@yahoo.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 #include <SqlNwStatement.h>
21 #include <Network.h>
23 DbRetVal SqlNwStatement::prepare(char *stmtstr)
25 DbRetVal rv = OK;
26 isSel = false;
27 SqlNwConnection *conn = (SqlNwConnection*)con;
28 if (! conn->isConOpen()) {
29 printError(ErrNoConnection, "No connection present");
30 return ErrNoConnection;
32 if (isPrepared) free();
33 SqlPacketPrepare *pkt = new SqlPacketPrepare();
34 pkt->stmtString = stmtstr;
35 pkt->stmtLength = strlen(stmtstr) + 1;
36 pkt->marshall();
37 rv = conn->send(SQL_NW_PKT_PREPARE, pkt->getMarshalledBuffer(), pkt->getBufferSize());
38 if (rv != OK) {
39 printError(rv, "Data could not be sent");
40 return rv;
42 int response = 0;
43 rv = conn->receive();
44 if (rv != OK) {
45 printError(rv, "Unable to Receive from peer");
46 return rv;
48 ResponsePacket *rpkt = (ResponsePacket *) ((TCPClient *)conn->nwClient)->respPkt;
49 char *ptr = (char *) &rpkt->retVal;
50 if (*ptr == 0) { delete pkt; return ErrPeerResponse; }
51 if (rpkt->isSelect) isSel = true; else isSel = false;
52 int params = *(ptr + 2);
53 int proj = *(ptr + 3);
54 stmtID = rpkt->stmtID;
55 char *buffer = NULL;
56 if (params) {
57 PacketHeader header;
58 int fd = ((TCPClient *)(conn->nwClient))->sockfd;
59 int numbytes = os::recv(fd, &header, sizeof(PacketHeader), 0);
60 if (numbytes == -1) {
61 printError(ErrOS, "Error reading from socket\n");
62 return ErrOS;
64 printf("HEADER says packet type is %d\n", header.packetType);
65 buffer = (char*) malloc(header.packetLength);
66 numbytes = os::recv(fd,buffer,header.packetLength,0);
67 if (numbytes == -1) {
68 printError(ErrOS, "Error reading from socket\n");
69 return ErrOS;
71 SqlPacketParamMetadata *mdpkt = new SqlPacketParamMetadata();
72 mdpkt->setBuffer(buffer);
73 mdpkt->unmarshall();
74 BindSqlField *bindField=NULL;
75 for (int i=0; i < mdpkt->noParams; i++) {
76 bindField = new BindSqlField();
77 bindField->type = (DataType) mdpkt->type[i];
78 bindField->length = mdpkt->length[i];
79 if (mdpkt->type[i] == typeBinary)
80 bindField->value = AllDataType::alloc(bindField->type, 2 * bindField->length);
81 else bindField->value = AllDataType::alloc(bindField->type, bindField->length);
82 paramList.append(bindField);
84 delete mdpkt;
86 if (proj) {
87 PacketHeader header;
88 int fd = ((TCPClient *)(conn->nwClient))->sockfd;
89 int numbytes = os::recv(fd, &header, sizeof(PacketHeader), 0);
90 if (numbytes == -1) {
91 printError(ErrOS, "Error reading from socket\n");
92 return ErrOS;
94 printf("HEADER says packet type is %d\n", header.packetType);
95 buffer = (char*) malloc(header.packetLength);
96 numbytes = os::recv(fd,buffer,header.packetLength,0);
97 if (numbytes == -1) {
98 printError(ErrOS, "Error reading from socket\n");
99 return ErrOS;
101 SqlPacketProjMetadata *prjmdpkt = new SqlPacketProjMetadata();
102 prjmdpkt->setBuffer(buffer);
103 prjmdpkt->unmarshall();
104 BindSqlProjectField *prjFld=NULL;
105 for (int i=0; i < prjmdpkt->noProjs; i++) {
106 prjFld = new BindSqlProjectField();
107 prjFld->type = (DataType) prjmdpkt->type[i];
108 prjFld->length = prjmdpkt->length[i];
109 prjFld->value = AllDataType::alloc(prjFld->type, prjFld->length);
110 bindList.append(prjFld);
112 delete prjmdpkt;
114 isPrepared = true;
115 delete pkt;
116 return rv;
119 DbRetVal SqlNwStatement::execute(int &rowsAffected)
121 DbRetVal rv = OK;
122 SqlNwConnection *conn = (SqlNwConnection*)con;
123 if (! conn->isConOpen()) {
124 printError(ErrNoConnection, "No connection present");
125 return ErrNoConnection;
127 if (!isPrepared) return ErrNotPrepared;
128 SqlPacketExecute *pkt = new SqlPacketExecute();
129 pkt->stmtID = getStmtID();
130 pkt->noParams=paramList.size();
131 pkt->setParams(paramList);
132 pkt->marshall();
133 rv = conn->send(SQL_NW_PKT_EXECUTE, pkt->getMarshalledBuffer(), pkt->getBufferSize());
134 if (rv != OK) {
135 printError(rv, "Data could not be sent");
136 return rv;
138 rv = conn->receive();
139 if (rv != OK) return rv;
140 if(pkt->noParams) delete [] pkt->paramValues;
141 delete pkt;
142 ResponsePacket *rpkt = (ResponsePacket *) ((TCPClient *)conn->nwClient)->respPkt;
143 char *ptr = (char *) &rpkt->retVal;
144 rowsAffected = rpkt->rows;
145 if (*ptr != 1) return ErrPeerResponse;
146 return rv;
149 DbRetVal SqlNwStatement::bindParam(int pos, void* value)
151 DbRetVal rv = OK;
152 printError(ErrWarning, "Deprecated. Use setParamXXX instead\n");
153 return rv;
156 DbRetVal SqlNwStatement::bindField(int pos, void* value)
158 if (!isPrepared) return OK;
159 BindSqlProjectField *prjFld = (BindSqlProjectField *) bindList.get(pos);
160 prjFld->value = value;
161 return OK;
163 void* SqlNwStatement::fetch()
165 DbRetVal rv = OK;
166 SqlNwConnection *conn = (SqlNwConnection*)con;
167 if (! conn->isConOpen()) {
168 printError(ErrNoConnection, "No connection present");
169 return NULL;
171 if (!isPrepared) return NULL;
172 void *ptrToFirstField = NULL;
173 SqlPacketFetch *pkt = new SqlPacketFetch();
174 pkt->stmtID = getStmtID();
175 pkt->marshall();
176 rv = conn->send(SQL_NW_PKT_FETCH, pkt->getMarshalledBuffer(), pkt->getBufferSize());
177 if (rv != OK) {
178 printError(rv, "Data could not be sent");
179 return NULL;
181 rv = conn->receive();
182 if (rv != OK) {
183 printError(rv, "Unable to receive from Network");
184 return NULL;
186 ResponsePacket *rpkt = (ResponsePacket *) ((TCPClient *)conn->nwClient)->respPkt;
187 char *ptr = (char *) &rpkt->retVal;
188 if (*ptr == 0) { delete pkt; return NULL; }
189 if (*(ptr+1) == 1) { delete pkt; rv = OK; return NULL; }
190 PacketHeader header;
191 int fd = ((TCPClient *)(conn->nwClient))->sockfd;
192 int numbytes = os::recv(fd, &header, sizeof(PacketHeader), 0);
193 if (numbytes == -1) {
194 printError(ErrOS, "Error reading from socket\n");
195 return NULL;
197 printf("HEADER says packet type is %d\n", header.packetType);
198 char *buffer = (char*) malloc(header.packetLength);
199 numbytes = os::recv(fd,buffer,header.packetLength,0);
200 if (numbytes == -1) {
201 printError(ErrOS, "Error reading from socket\n");
203 return NULL;
205 SqlPacketResultSet *rspkt = new SqlPacketResultSet();
206 rspkt->setBuffer(buffer);
207 rspkt->setProjList(bindList);
208 rspkt->noProjs = bindList.size();
209 rspkt->unmarshall();
210 delete [] rspkt->projValues;
211 ptrToFirstField = bindList.get(1);
212 delete rspkt;
213 delete pkt;
214 return ptrToFirstField;
217 void* SqlNwStatement::fetch(DbRetVal &ret)
219 SqlNwConnection *conn = (SqlNwConnection*)con;
220 if (! conn->isConOpen()) {
221 printError(ErrNoConnection, "No connection present");
222 ret = ErrNoConnection;
223 return NULL;
225 if (!isPrepared) return NULL;
226 void *ptrToFirstField = NULL;
227 SqlPacketFetch *pkt = new SqlPacketFetch();
228 pkt->stmtID = getStmtID();
229 pkt->marshall();
230 DbRetVal rv = conn->send(SQL_NW_PKT_FETCH, pkt->getMarshalledBuffer(), pkt->getBufferSize());
231 if (rv != OK) {
232 printError(rv, "Data could not be sent");
233 return NULL;
235 rv = conn->receive();
236 if (rv != OK) {
237 printError(rv, "Unable to receive from Network");
238 return NULL;
240 ResponsePacket *rpkt = (ResponsePacket *) ((TCPClient *)conn->nwClient)->respPkt;
241 char *ptr = (char *) &rpkt->retVal;
242 if (*ptr == 0) { delete pkt; ret = ErrPeerResponse; return NULL; }
243 if (*(ptr+1) == 1) { delete pkt; ret = OK; return NULL; }
245 PacketHeader header;
246 int fd = ((TCPClient *)(conn->nwClient))->sockfd;
247 int numbytes = os::recv(fd, &header, sizeof(PacketHeader), 0);
248 if (numbytes == -1) {
249 printError(ErrOS, "Error reading from socket\n");
250 return NULL;
252 printf("HEADER says packet type is %d\n", header.packetType);
253 char *buffer = (char*) malloc(header.packetLength);
254 numbytes = os::recv(fd,buffer,header.packetLength,0);
255 if (numbytes == -1) {
256 printError(ErrOS, "Error reading from socket\n");
257 return NULL;
259 SqlPacketResultSet *rspkt = new SqlPacketResultSet();
260 rspkt->setBuffer(buffer);
261 rspkt->setProjList(bindList);
262 rspkt->noProjs = bindList.size();
263 rspkt->unmarshall();
264 delete [] rspkt->projValues;
265 ptrToFirstField = bindList.get(1);
266 delete rspkt;
267 delete pkt;
268 return ptrToFirstField;
272 void* SqlNwStatement::fetchAndPrint(bool SQL)
274 if (!isPrepared) return NULL;
275 void *ptrToFirstField = NULL;
276 //TODO
277 return ptrToFirstField;
280 void* SqlNwStatement::next()
282 return fetch();
285 DbRetVal SqlNwStatement::close()
287 if (!isPrepared) return OK;
288 //TODO
289 return OK;
292 void* SqlNwStatement::getFieldValuePtr( int pos )
294 BindSqlProjectField *fld=(BindSqlProjectField *) bindList.get(pos+1);
295 return fld->value;
298 int SqlNwStatement::noOfProjFields()
300 if (!isPrepared) return 0;
301 //TODO
302 return 0;
305 int SqlNwStatement::noOfParamFields()
307 if (!isPrepared) return 0;
308 //TODO
309 return 0;
312 DbRetVal SqlNwStatement::getProjFldInfo (int projpos, FieldInfo *&fInfo)
314 //TODO
315 return ErrNotFound;
318 DbRetVal SqlNwStatement::getParamFldInfo (int parampos, FieldInfo *&fInfo)
320 //TODO
321 return ErrNotFound;
324 DbRetVal SqlNwStatement::free()
326 DbRetVal rv = OK;
327 SqlNwConnection *conn = (SqlNwConnection*)con;
328 if (! conn->isConOpen()) {
329 printError(ErrNoConnection, "No connection present");
330 return ErrNoConnection;
332 if (!isPrepared) return OK;
333 SqlPacketFree *pkt = new SqlPacketFree();
334 pkt->stmtID = getStmtID();
335 pkt->marshall();
336 rv = conn->send(SQL_NW_PKT_FREE, pkt->getMarshalledBuffer(), pkt->getBufferSize());
337 if (rv != OK) {
338 printError(rv, "Data could not be sent");
339 return rv;
341 rv = conn->receive();
342 if (rv != OK) return rv;
343 ResponsePacket *rpkt = (ResponsePacket *) ((TCPClient *)conn->nwClient)->respPkt;
344 char *ptr = (char *) &rpkt->retVal;
345 if (*ptr != 1) {
346 printf("there is some error\n");
347 return ErrPeerResponse;
349 ListIterator itprm = paramList.getIterator();
350 BindSqlField *fld = NULL;
351 while((fld = (BindSqlField *) itprm.nextElement()) != NULL) {
352 if (fld->value) ::free(fld->value); delete fld;
354 paramList.reset();
355 ListIterator itprj = bindList.getIterator();
356 BindSqlProjectField *pfld = NULL;
357 while((pfld = (BindSqlProjectField *) itprj.nextElement()) != NULL) {
358 delete pfld;
360 bindList.reset();
361 isPrepared = false;
362 delete pkt;
363 return rv;
366 // In all the following setXXXParam functions type and length fields are
367 // reinitialized to accommodate fix for MySQL bug #1382
368 // SQLDescribeParam returns the same type information
370 void SqlNwStatement::setShortParam(int paramPos, short value)
372 if (!isPrepared) return;
373 if (paramPos <= 0) return;
374 BindSqlField *bindField = (BindSqlField *) paramList.get(paramPos);
375 bindField->type = typeShort;
376 bindField->length = AllDataType::size(typeShort);
377 *(short *) bindField->value = value;
378 return;
381 void SqlNwStatement::setIntParam(int paramPos, int value)
383 if (!isPrepared) return ;
384 if (paramPos <= 0) return;
385 BindSqlField *bindField = (BindSqlField *) paramList.get(paramPos);
386 bindField->type = typeInt;
387 bindField->length = AllDataType::size(typeInt);
388 *(int *) bindField->value = value;
389 return;
392 void SqlNwStatement::setLongParam(int paramPos, long value)
394 if (!isPrepared) return ;
395 if (paramPos <= 0) return;
396 BindSqlField *bindField = (BindSqlField *) paramList.get(paramPos);
397 bindField->type = typeLong;
398 bindField->length = AllDataType::size(typeLong);
399 *(long *) bindField->value = value;
400 return;
404 void SqlNwStatement::setLongLongParam(int paramPos, long long value)
406 if (!isPrepared) return ;
407 if (paramPos <= 0) return;
408 BindSqlField *bindField = (BindSqlField *) paramList.get(paramPos);
409 bindField->type = typeLongLong;
410 bindField->length = AllDataType::size(typeLongLong);
411 *(long long *) bindField->value = value;
412 return;
415 void SqlNwStatement::setByteIntParam(int paramPos, ByteInt value)
417 if (!isPrepared) return ;
418 if (paramPos <= 0) return;
419 BindSqlField *bindField = (BindSqlField *) paramList.get(paramPos);
420 bindField->type = typeByteInt;
421 bindField->length = AllDataType::size(typeByteInt);
422 *(ByteInt *) bindField->value = value;
423 return;
426 void SqlNwStatement::setFloatParam(int paramPos, float value)
428 if (!isPrepared) return ;
429 if (paramPos <= 0) return;
430 BindSqlField *bindField = (BindSqlField *) paramList.get(paramPos);
431 bindField->type = typeFloat;
432 bindField->length = AllDataType::size(typeFloat);
433 *(float *) bindField->value = value;
434 return;
437 void SqlNwStatement::setDoubleParam(int paramPos, double value)
439 if (!isPrepared) return ;
440 if (paramPos <= 0) return;
441 BindSqlField *bindField = (BindSqlField *) paramList.get(paramPos);
442 bindField->type = typeDouble;
443 bindField->length = AllDataType::size(typeDouble);
444 *(double *) bindField->value = value;
445 return;
448 void SqlNwStatement::setStringParam(int paramPos, char *value)
450 if (!isPrepared) return ;
451 if (paramPos <= 0) return;
452 BindSqlField *bindField = (BindSqlField *) paramList.get(paramPos);
453 bindField->type = typeString;
454 strcpy((char *) bindField->value, value);
455 return;
458 void SqlNwStatement::setDateParam(int paramPos, Date value)
460 if (!isPrepared) return ;
461 if (paramPos <= 0) return;
462 BindSqlField *bindField = (BindSqlField *) paramList.get(paramPos);
463 bindField->type = typeDate;
464 bindField->length = AllDataType::size(typeDate);
465 *(Date *)bindField->value = value;
466 return;
469 void SqlNwStatement::setTimeParam(int paramPos, Time value)
471 if (!isPrepared) return ;
472 if (paramPos <= 0) return;
473 BindSqlField *bindField = (BindSqlField *) paramList.get(paramPos);
474 bindField->type = typeTime;
475 bindField->length = AllDataType::size(typeTime);
476 * (Time *) bindField->value = value;
477 return;
480 void SqlNwStatement::setTimeStampParam(int paramPos, TimeStamp value)
482 if (!isPrepared) return ;
483 if (paramPos <= 0) return;
484 BindSqlField *bindField = (BindSqlField *) paramList.get(paramPos);
485 bindField->type = typeTimeStamp;
486 bindField->length = AllDataType::size(typeTimeStamp);
487 *(TimeStamp *) bindField->value = value;
488 return;
491 void SqlNwStatement::setBinaryParam(int paramPos, void *value)
493 if (!isPrepared) return;
494 if (paramPos <= 0) return;
495 BindSqlField *bindField = (BindSqlField *) paramList.get(paramPos);
496 bindField->type = typeBinary;
497 memcpy(bindField->value, value, 2 * bindField->length);
498 return;
501 void SqlNwStatement::getPrimaryKeyFieldName(char *tablename, char *pkfieldname)
503 if (pkfieldname == NULL) return;
504 //TODO
505 return;