changing close to closescan
[csql.git] / src / sql / UpdStatement.cxx
blobed302bc4d812fa3844cd37745063130f40495ec2
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 ***************************************************************************/
16 #include "Statement.h"
17 #include <Info.h>
19 UpdStatement::UpdStatement()
21 parsedData = NULL;
22 dbMgr = NULL;
23 table = NULL;
24 params = NULL;
25 paramValues = NULL;
26 totalParams = 0;
27 totalAssignParams =0;
30 UpdStatement::~UpdStatement() {
31 if (table) { table->close(); table = NULL; }
32 if (totalParams) {
33 //TODO::below free cause memory corruption.
34 free(params);
35 params = NULL;
36 free(paramValues);
37 paramValues = NULL;
40 void* UpdStatement::getParamValuePtr( int pos )
42 ConditionValue *cValue;
43 UpdateFieldValue *uValue;
44 if (pos <= totalAssignParams) {
45 uValue = (UpdateFieldValue*) params[pos-1];
46 return( (void*) uValue->value );
47 } else {
48 cValue = (ConditionValue*) params[pos-1];
49 return( (void*) cValue->value );
53 DbRetVal UpdStatement::getParamFldInfo(int paramPos, FieldInfo *&info)
55 if (paramPos <=0 || paramPos > totalParams) return ErrBadArg;
56 if (NULL == params[paramPos-1])
58 printError(ErrSysFatal, "param not set. Should never happen");
59 return ErrSysFatal;
62 ConditionValue *cValue;
63 UpdateFieldValue *uValue;
64 if (paramPos <= totalAssignParams) {
65 uValue = (UpdateFieldValue*) params[paramPos-1];
66 table->getFieldNameAlone(uValue->fldName,info->fldName);
67 info->type = uValue->type;
68 info->length = uValue->length;
69 info->isNull = uValue->isNullable;
70 } else {
71 cValue = (ConditionValue*) params[paramPos-1];
72 table->getFieldNameAlone(cValue->fName,info->fldName);
73 info->type = cValue->type;
74 info->length = cValue->length;
75 info->isNull = cValue->isNullable;
77 return OK;
80 DbRetVal UpdStatement::execute(int &rowsAffected)
82 DbRetVal rv = OK;
83 //copy param values to binded buffer
84 ConditionValue *cValue;
85 UpdateFieldValue *uValue;
87 for (int i = 0; i < totalParams; i ++)
89 if (i < totalAssignParams) {
90 uValue = (UpdateFieldValue*) params[i];
91 if (paramValues[i] == NULL)
93 continue;
94 //printError(ErrBadCall, "param values not set");
95 //return ErrBadCall;
97 AllDataType::copyVal(uValue->value, paramValues[i], uValue->type, uValue->length);
98 } else {
99 cValue = (ConditionValue*) params[i];
100 if (paramValues[i] == NULL)
102 continue;
103 //printError(ErrBadCall, "param values not set");
104 //return ErrBadCall;
106 AllDataType::copyVal(cValue->value, paramValues[i], cValue->type, cValue->length);
109 rv = table->execute();
110 if (rv != OK) return rv;
111 rowsAffected = 0;
112 void *tuple;
113 ListIterator iter = parsedData->getUpdateFieldValueList().getIterator();
114 bool nullFlag;
115 while(true)
117 tuple = (char*)table->fetchNoBind(rv);
118 if (rv != OK) break;
119 if (tuple == NULL) {break;}
120 iter.reset();
121 while (iter.hasElement())
123 uValue = (UpdateFieldValue*) iter.nextElement();
124 if(uValue->expre!=NULL)
126 nullFlag=false;
127 uValue->expre->setTuple(tuple);
128 uValue->expre->setTable(table);
129 AllDataType::copyVal(uValue->value,(uValue->expre)->evaluate(uValue->type,nullFlag),uValue->type, uValue->length);
130 uValue->expre->memFree();
131 if(nullFlag)
133 rv=table->markFldNull(uValue->fldName);
134 if(rv==ErrNullViolation){return ErrNullViolation;}
138 rv = table->updateTuple();
139 if (rv != OK) break;
140 rowsAffected++;
142 table->closeScan();
143 return rv;
147 DbRetVal UpdStatement::setParam(int paramNo, void *value)
149 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
150 if (NULL == value) return ErrBadArg;
151 paramValues[paramNo -1] = (char*) value;
152 return OK;
155 DbRetVal UpdStatement::setShortParam(int paramNo, short value)
157 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
158 if (NULL == params[paramNo-1])
160 printError(ErrSysFatal, "param not set. Should never happen");
161 return ErrSysFatal;
164 ConditionValue *cValue;
165 UpdateFieldValue *uValue;
166 if (paramNo <= totalAssignParams) {
167 uValue = (UpdateFieldValue*) params[paramNo-1];
168 *(short*)uValue->value = value;
169 } else {
170 cValue = (ConditionValue*) params[paramNo-1];
171 *(short*)cValue->value = value;
173 return OK;
177 DbRetVal UpdStatement::setIntParam(int paramNo, int value)
179 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
180 if (NULL == params[paramNo-1])
182 printError(ErrSysFatal, "param not set. Should never happen");
183 return ErrSysFatal;
185 ConditionValue *cValue;
186 UpdateFieldValue *uValue;
187 if (paramNo <= totalAssignParams) {
188 uValue = (UpdateFieldValue*) params[paramNo-1];
189 *(int*)uValue->value = value;
190 } else {
191 cValue = (ConditionValue*) params[paramNo-1];
192 *(int*)cValue->value = value;
194 return OK;
197 DbRetVal UpdStatement::setLongParam(int paramNo, long value)
199 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
200 if (NULL == params[paramNo-1])
202 printError(ErrSysFatal, "param not set. Should never happen");
203 return ErrSysFatal;
206 ConditionValue *cValue;
207 UpdateFieldValue *uValue;
208 if (paramNo <= totalAssignParams) {
209 uValue = (UpdateFieldValue*) params[paramNo-1];
210 *(long*)uValue->value = value;
211 } else {
212 cValue = (ConditionValue*) params[paramNo-1];
213 *(long*)cValue->value = value;
215 return OK;
218 DbRetVal UpdStatement::setLongLongParam(int paramNo, long long value)
220 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
221 if (NULL == params[paramNo-1])
223 printError(ErrSysFatal, "param not set. Should never happen");
224 return ErrSysFatal;
227 ConditionValue *cValue;
228 UpdateFieldValue *uValue;
229 if (paramNo <= totalAssignParams) {
230 uValue = (UpdateFieldValue*) params[paramNo-1];
231 *(long long*)uValue->value = value;
232 } else {
233 cValue = (ConditionValue*) params[paramNo-1];
234 *(long long*)cValue->value = value;
236 return OK;
239 DbRetVal UpdStatement::setByteIntParam(int paramNo, ByteInt value)
241 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
242 if (NULL == params[paramNo-1])
244 printError(ErrSysFatal, "param not set. Should never happen");
245 return ErrSysFatal;
248 ConditionValue *cValue;
249 UpdateFieldValue *uValue;
250 if (paramNo <= totalAssignParams) {
251 uValue = (UpdateFieldValue*) params[paramNo-1];
252 *(ByteInt*)uValue->value = value;
253 } else {
254 cValue = (ConditionValue*) params[paramNo-1];
255 *(ByteInt*)cValue->value = value;
257 return OK;
260 DbRetVal UpdStatement::setFloatParam(int paramNo, float value)
262 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
263 if (NULL == params[paramNo-1])
265 printError(ErrSysFatal, "param not set. Should never happen");
266 return ErrSysFatal;
269 ConditionValue *cValue;
270 UpdateFieldValue *uValue;
271 if (paramNo <= totalAssignParams) {
272 uValue = (UpdateFieldValue*) params[paramNo-1];
273 *(float*)uValue->value = value;
274 } else {
275 cValue = (ConditionValue*) params[paramNo-1];
276 *(float*)cValue->value = value;
278 return OK;
282 DbRetVal UpdStatement::setDoubleParam(int paramNo, double value)
284 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
285 if (NULL == params[paramNo-1])
287 printError(ErrSysFatal, "param not set. Should never happen");
288 return ErrSysFatal;
291 ConditionValue *cValue;
292 UpdateFieldValue *uValue;
293 if (paramNo <= totalAssignParams) {
294 uValue = (UpdateFieldValue*) params[paramNo-1];
295 *(double*)uValue->value = value;
296 } else {
297 cValue = (ConditionValue*) params[paramNo-1];
298 *(double*)cValue->value = value;
300 return OK;
303 DbRetVal UpdStatement::setStringParam(int paramNo, char *value)
305 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
306 if (NULL == params[paramNo-1])
308 printError(ErrSysFatal, "param not set. Should never happen");
309 return ErrSysFatal;
312 ConditionValue *cValue;
313 UpdateFieldValue *uValue;
314 if (paramNo <= totalAssignParams) {
315 uValue = (UpdateFieldValue*) params[paramNo-1];
316 strcpy((char*)uValue->value, value);
317 } else {
318 cValue = (ConditionValue*) params[paramNo-1];
319 strcpy((char*)cValue->value, value);
321 return OK;
325 DbRetVal UpdStatement::setDateParam(int paramNo, Date value)
327 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
328 if (NULL == params[paramNo-1])
330 printError(ErrSysFatal, "param not set. Should never happen");
331 return ErrSysFatal;
334 ConditionValue *cValue;
335 UpdateFieldValue *uValue;
336 if (paramNo <= totalAssignParams) {
337 uValue = (UpdateFieldValue*) params[paramNo-1];
338 *(Date*)uValue->value = value;
339 } else {
340 cValue = (ConditionValue*) params[paramNo-1];
341 *(Date*)cValue->value = value;
343 return OK;
346 DbRetVal UpdStatement::setTimeParam(int paramNo, Time value)
348 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
349 if (NULL == params[paramNo-1])
351 printError(ErrSysFatal, "param not set. Should never happen");
352 return ErrSysFatal;
355 ConditionValue *cValue;
356 UpdateFieldValue *uValue;
357 if (paramNo <= totalAssignParams) {
358 uValue = (UpdateFieldValue*) params[paramNo-1];
359 *(Time*)uValue->value = value;
360 } else {
361 cValue = (ConditionValue*) params[paramNo-1];
362 *(Time*)cValue->value = value;
364 return OK;
368 DbRetVal UpdStatement::setTimeStampParam(int paramNo, TimeStamp value)
370 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
371 if (NULL == params[paramNo-1])
373 printError(ErrSysFatal, "param not set. Should never happen");
374 return ErrSysFatal;
377 ConditionValue *cValue;
378 UpdateFieldValue *uValue;
379 if (paramNo <= totalAssignParams) {
380 uValue = (UpdateFieldValue*) params[paramNo-1];
381 *(TimeStamp*)uValue->value = value;
382 } else {
383 cValue = (ConditionValue*) params[paramNo-1];
384 *(TimeStamp*)cValue->value = value;
386 return OK;
389 DbRetVal UpdStatement::setBinaryParam(int paramNo, void *value)
391 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
392 if (NULL == params[paramNo-1])
394 printError(ErrSysFatal, "param not set. Should never happen");
395 return ErrSysFatal;
398 ConditionValue *cValue;
399 UpdateFieldValue *uValue;
400 if (paramNo <= totalAssignParams) {
401 uValue = (UpdateFieldValue*) params[paramNo-1];
402 memcpy(uValue->value, value, 2 * uValue->length);
403 } else {
404 cValue = (ConditionValue*) params[paramNo-1];
405 AllDataType::convertToBinary(cValue->value,value,typeString,cValue->length);
407 return OK;
410 DbRetVal UpdStatement::resolve()
412 if (dbMgr == NULL) return ErrNoConnection;
413 //check whether the table exists
414 table = dbMgr->openTable(parsedData->getTableName());
415 if (table == NULL)
417 printError(ErrNotExists, "Unable to open the table:Table not exists");
418 return ErrNotExists;
421 table->setCondition(parsedData->getCondition());
423 DbRetVal rv = resolveForAssignment();
424 if (rv != OK)
426 //TODO::free memory allocated for params
427 table->setCondition(NULL);
428 dbMgr->closeTable(table);
429 table = NULL;
431 return rv;
434 DbRetVal UpdStatement::resolveForAssignment()
436 //get the fieldname list and validate field names
437 ListIterator iter = parsedData->getUpdateFieldValueList().getIterator();
439 UpdateFieldValue *value;
440 FieldInfo *fInfo = new FieldInfo();
441 int paramPos =1;
442 DbRetVal rv = OK;
443 while (iter.hasElement())
445 value = (UpdateFieldValue*) iter.nextElement();
446 if (NULL == value)
448 delete fInfo;
449 printError(ErrSysFatal, "Should never happen.");
450 return ErrSysFatal;
452 rv = table->getFieldInfo(value->fldName, fInfo);
453 if (ErrNotFound == rv)
455 delete fInfo;
456 printError(ErrSyntaxError, "Field %s does not exist in table",
457 value->fldName);
458 return ErrSyntaxError;
460 if (fInfo->isUnique) {
461 delete fInfo;
462 printError(ErrUnique, "Unique field %s cannot be updated", value->fldName);
463 return ErrUnique;
465 value->type = fInfo->type;
466 value->length = fInfo->length;
467 value->isNullable = fInfo->isNull;
468 // for binary datatype input buffer size should be 2 times the length
469 if (value->type == typeBinary)
470 value->value = AllDataType::alloc(fInfo->type, 2 * fInfo->length);
471 else value->value = AllDataType::alloc(fInfo->type, fInfo->length);
472 table->bindFld(value->fldName, value->value);
473 if( NULL != value->expre )
475 (value->expre)->convertStrToVal(value->type);
476 continue;
478 if (value->parsedString == NULL)
480 if (fInfo->isNull) { delete fInfo; return ErrNullViolation; }
481 table->markFldNull(value->fldName);
482 continue;
484 if (value->parsedString[0] == '?')
486 value->paramNo = paramPos++;
488 if (!value->paramNo) {
489 // for binary datatype buffer is just strcpy'd. It will be converted into binary datatype in copyValuesToBindBuffer in DBAPI
490 if (value->type == typeBinary)
491 strncpy((char *)value->value, value->parsedString, 2 * fInfo->length);
492 else AllDataType::strToValue(value->value, value->parsedString, fInfo->type, value->length);
495 totalAssignParams = paramPos -1;
498 //get the fieldname list and validate field names
499 ListIterator cIter = parsedData->getConditionValueList().getIterator();
500 ConditionValue *cValue = NULL;
501 while (cIter.hasElement())
503 cValue = (ConditionValue*) cIter.nextElement();
504 if (NULL == cValue)
506 delete fInfo;
507 printError(ErrSysFatal, "Should never happen.");
508 return ErrSysFatal;
510 rv = table->getFieldInfo(cValue->fName, fInfo);
511 if (ErrNotFound == rv)
513 delete fInfo;
514 printError(ErrSyntaxError, "Field %s does not exist in table",
515 cValue->fName);
516 return ErrSyntaxError;
518 cValue->type = fInfo->type;
519 cValue->length = fInfo->length;
520 cValue->isNullable = fInfo->isNull;
521 // for binary datatype input buffer size should be 2 times the length
522 if (cValue->type == typeBinary)
524 if(cValue->parsedString[0] == '?')
525 cValue->value = AllDataType::alloc(fInfo->type, fInfo->length);
526 else
527 cValue->value = AllDataType::alloc(fInfo->type, 2 * fInfo->length);
529 else cValue->value = AllDataType::alloc(fInfo->type, fInfo->length);
530 if(cValue->paramNo == 1){continue;}
531 if (cValue->parsedString == NULL)
533 delete fInfo;
534 printError(ErrSyntaxError, "Condition value should not be NULL");
535 return ErrSyntaxError;
538 if (cValue->parsedString[0] == '?')
540 if(! cValue->opLike) // checks if 'LIKE' operator is used
541 cValue->paramNo = paramPos++;
543 if (!cValue->paramNo) {
544 // Here for binary dataType it is not strcpy'd bcos internally memcmp is done for predicates like f2 = 'abcd' where f2 is binary
545 AllDataType::strToValue(cValue->value, cValue->parsedString, fInfo->type, fInfo->length);
549 delete fInfo;
550 totalParams = paramPos -1;
551 if (0 == totalParams) return OK;
552 params = (void**) malloc ( totalParams * sizeof(FieldValue*));
553 paramValues = (char**) malloc( totalParams * sizeof(char*));
555 memset(params, 0, totalParams * sizeof(FieldValue*));
556 memset(paramValues, 0, totalParams * sizeof(char*));
558 iter.reset();
559 while(iter.hasElement())
561 value = (UpdateFieldValue*) iter.nextElement();
562 if (value == NULL)
564 free(params); params = NULL;
565 free(paramValues); paramValues = NULL;
566 printError(ErrSysFatal, "Should never happen. value NULL after iteration");
567 return ErrSysFatal;
569 if (0 == value->paramNo) continue;
570 params[value->paramNo -1 ] = value;
573 cIter.reset();
574 while(cIter.hasElement())
576 cValue = (ConditionValue*) cIter.nextElement();
577 if (cValue == NULL)
579 free(params); params = NULL;
580 free(paramValues); paramValues = NULL;
581 printError(ErrSysFatal, "Should never happen. value NULL after iteration");
582 return ErrSysFatal;
584 if (0 == cValue->paramNo) continue;
585 params[cValue->paramNo -1 ] = cValue;
587 return OK;
589 int UpdStatement::getFldPos(char *name)
591 return table->getFldPos(name);