1 /***************************************************************************
2 * Copyright (C) 2007 by Prabakaran Thirumalai *
3 * praba_tuty@yahoo.com *
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. *
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. *
15 ***************************************************************************/
16 #include "Statement.h"
19 UpdStatement::UpdStatement()
30 UpdStatement::~UpdStatement() {
31 if (table
) { table
->close(); table
= NULL
; }
33 //TODO::below free cause memory corruption.
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
);
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");
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
;
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
;
80 DbRetVal
UpdStatement::execute(int &rowsAffected
)
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
)
94 //printError(ErrBadCall, "param values not set");
97 AllDataType::copyVal(uValue
->value
, paramValues
[i
], uValue
->type
, uValue
->length
);
99 cValue
= (ConditionValue
*) params
[i
];
100 if (paramValues
[i
] == NULL
)
103 //printError(ErrBadCall, "param values not set");
106 AllDataType::copyVal(cValue
->value
, paramValues
[i
], cValue
->type
, cValue
->length
);
109 rv
= table
->execute();
110 if (rv
!= OK
) return rv
;
113 ListIterator iter
= parsedData
->getUpdateFieldValueList().getIterator();
117 tuple
= (char*)table
->fetchNoBind(rv
);
119 if (tuple
== NULL
) {break;}
121 while (iter
.hasElement())
123 uValue
= (UpdateFieldValue
*) iter
.nextElement();
124 if(uValue
->expre
!=NULL
)
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();
133 rv
=table
->markFldNull(uValue
->fldName
);
134 if(rv
==ErrNullViolation
){return ErrNullViolation
;}
138 rv
= table
->updateTuple();
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
;
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");
164 ConditionValue
*cValue
;
165 UpdateFieldValue
*uValue
;
166 if (paramNo
<= totalAssignParams
) {
167 uValue
= (UpdateFieldValue
*) params
[paramNo
-1];
168 *(short*)uValue
->value
= value
;
170 cValue
= (ConditionValue
*) params
[paramNo
-1];
171 *(short*)cValue
->value
= value
;
176 DbRetVal
UpdStatement::setIntParam(int paramNo
, int value
)
178 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
179 if (NULL
== params
[paramNo
-1])
181 printError(ErrSysFatal
, "param not set. Should never happen");
184 ConditionValue
*cValue
;
185 UpdateFieldValue
*uValue
;
186 if (paramNo
<= totalAssignParams
) {
187 uValue
= (UpdateFieldValue
*) params
[paramNo
-1];
188 *(int*)uValue
->value
= value
;
190 cValue
= (ConditionValue
*) params
[paramNo
-1];
191 *(int*)cValue
->value
= value
;
196 DbRetVal
UpdStatement::setNull(int paramNo
)
198 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
199 if (NULL
== params
[paramNo
-1])
201 printError(ErrSysFatal
, "param not set. Should never happen");
204 ConditionValue
*cValue
;
205 UpdateFieldValue
*uValue
;
206 if (paramNo
<= totalAssignParams
) {
207 uValue
= (UpdateFieldValue
*) params
[paramNo
-1];
208 table
->markFldNull(uValue
->fldName
);
210 printf("paramerise for predicate nullset not supported\n");
214 DbRetVal
UpdStatement::setLongParam(int paramNo
, long value
)
216 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
217 if (NULL
== params
[paramNo
-1])
219 printError(ErrSysFatal
, "param not set. Should never happen");
223 ConditionValue
*cValue
;
224 UpdateFieldValue
*uValue
;
225 if (paramNo
<= totalAssignParams
) {
226 uValue
= (UpdateFieldValue
*) params
[paramNo
-1];
227 *(long*)uValue
->value
= value
;
229 cValue
= (ConditionValue
*) params
[paramNo
-1];
230 *(long*)cValue
->value
= value
;
235 DbRetVal
UpdStatement::setLongLongParam(int paramNo
, long long value
)
237 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
238 if (NULL
== params
[paramNo
-1])
240 printError(ErrSysFatal
, "param not set. Should never happen");
244 ConditionValue
*cValue
;
245 UpdateFieldValue
*uValue
;
246 if (paramNo
<= totalAssignParams
) {
247 uValue
= (UpdateFieldValue
*) params
[paramNo
-1];
248 *(long long*)uValue
->value
= value
;
250 cValue
= (ConditionValue
*) params
[paramNo
-1];
251 *(long long*)cValue
->value
= value
;
256 DbRetVal
UpdStatement::setByteIntParam(int paramNo
, ByteInt value
)
258 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
259 if (NULL
== params
[paramNo
-1])
261 printError(ErrSysFatal
, "param not set. Should never happen");
265 ConditionValue
*cValue
;
266 UpdateFieldValue
*uValue
;
267 if (paramNo
<= totalAssignParams
) {
268 uValue
= (UpdateFieldValue
*) params
[paramNo
-1];
269 *(ByteInt
*)uValue
->value
= value
;
271 cValue
= (ConditionValue
*) params
[paramNo
-1];
272 *(ByteInt
*)cValue
->value
= value
;
277 DbRetVal
UpdStatement::setFloatParam(int paramNo
, float value
)
279 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
280 if (NULL
== params
[paramNo
-1])
282 printError(ErrSysFatal
, "param not set. Should never happen");
286 ConditionValue
*cValue
;
287 UpdateFieldValue
*uValue
;
288 if (paramNo
<= totalAssignParams
) {
289 uValue
= (UpdateFieldValue
*) params
[paramNo
-1];
290 *(float*)uValue
->value
= value
;
292 cValue
= (ConditionValue
*) params
[paramNo
-1];
293 *(float*)cValue
->value
= value
;
299 DbRetVal
UpdStatement::setDoubleParam(int paramNo
, double value
)
301 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
302 if (NULL
== params
[paramNo
-1])
304 printError(ErrSysFatal
, "param not set. Should never happen");
308 ConditionValue
*cValue
;
309 UpdateFieldValue
*uValue
;
310 if (paramNo
<= totalAssignParams
) {
311 uValue
= (UpdateFieldValue
*) params
[paramNo
-1];
312 *(double*)uValue
->value
= value
;
314 cValue
= (ConditionValue
*) params
[paramNo
-1];
315 *(double*)cValue
->value
= value
;
320 DbRetVal
UpdStatement::setStringParam(int paramNo
, char *value
)
322 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
323 if (NULL
== params
[paramNo
-1])
325 printError(ErrSysFatal
, "param not set. Should never happen");
329 ConditionValue
*cValue
;
330 UpdateFieldValue
*uValue
;
331 if (paramNo
<= totalAssignParams
) {
332 uValue
= (UpdateFieldValue
*) params
[paramNo
-1];
333 strcpy((char*)uValue
->value
, value
);
335 cValue
= (ConditionValue
*) params
[paramNo
-1];
336 strcpy((char*)cValue
->value
, value
);
342 DbRetVal
UpdStatement::setDateParam(int paramNo
, Date value
)
344 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
345 if (NULL
== params
[paramNo
-1])
347 printError(ErrSysFatal
, "param not set. Should never happen");
351 ConditionValue
*cValue
;
352 UpdateFieldValue
*uValue
;
353 if (paramNo
<= totalAssignParams
) {
354 uValue
= (UpdateFieldValue
*) params
[paramNo
-1];
355 *(Date
*)uValue
->value
= value
;
357 cValue
= (ConditionValue
*) params
[paramNo
-1];
358 *(Date
*)cValue
->value
= value
;
363 DbRetVal
UpdStatement::setTimeParam(int paramNo
, Time value
)
365 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
366 if (NULL
== params
[paramNo
-1])
368 printError(ErrSysFatal
, "param not set. Should never happen");
372 ConditionValue
*cValue
;
373 UpdateFieldValue
*uValue
;
374 if (paramNo
<= totalAssignParams
) {
375 uValue
= (UpdateFieldValue
*) params
[paramNo
-1];
376 *(Time
*)uValue
->value
= value
;
378 cValue
= (ConditionValue
*) params
[paramNo
-1];
379 *(Time
*)cValue
->value
= value
;
385 DbRetVal
UpdStatement::setTimeStampParam(int paramNo
, TimeStamp value
)
387 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
388 if (NULL
== params
[paramNo
-1])
390 printError(ErrSysFatal
, "param not set. Should never happen");
394 ConditionValue
*cValue
;
395 UpdateFieldValue
*uValue
;
396 if (paramNo
<= totalAssignParams
) {
397 uValue
= (UpdateFieldValue
*) params
[paramNo
-1];
398 *(TimeStamp
*)uValue
->value
= value
;
400 cValue
= (ConditionValue
*) params
[paramNo
-1];
401 *(TimeStamp
*)cValue
->value
= value
;
406 DbRetVal
UpdStatement::setBinaryParam(int paramNo
, void *value
, int length
)
408 if (paramNo
<=0 || paramNo
> totalParams
) return ErrBadArg
;
409 if (NULL
== params
[paramNo
-1])
411 printError(ErrSysFatal
, "param not set. Should never happen");
415 ConditionValue
*cValue
;
416 UpdateFieldValue
*uValue
;
417 if (paramNo
<= totalAssignParams
) {
418 uValue
= (UpdateFieldValue
*) params
[paramNo
-1];
419 memcpy(uValue
->value
, value
, 2 * uValue
->length
);
421 cValue
= (ConditionValue
*) params
[paramNo
-1];
422 AllDataType::convertToBinary(cValue
->value
,value
,typeString
,cValue
->length
);
427 DbRetVal
UpdStatement::resolve()
429 if (dbMgr
== NULL
) return ErrNoConnection
;
430 //check whether the table exists
431 table
= dbMgr
->openTable(parsedData
->getTableName());
434 printError(ErrNotExists
, "Unable to open the table:Table not exists");
438 table
->setCondition(parsedData
->getCondition());
440 DbRetVal rv
= resolveForAssignment();
443 //TODO::free memory allocated for params
444 table
->setCondition(NULL
);
445 dbMgr
->closeTable(table
);
451 DbRetVal
UpdStatement::resolveForAssignment()
453 //get the fieldname list and validate field names
454 ListIterator iter
= parsedData
->getUpdateFieldValueList().getIterator();
456 UpdateFieldValue
*value
;
457 FieldInfo
*fInfo
= new FieldInfo();
460 while (iter
.hasElement())
462 value
= (UpdateFieldValue
*) iter
.nextElement();
466 printError(ErrSysFatal
, "Should never happen.");
469 rv
= table
->getFieldInfo(value
->fldName
, fInfo
);
470 if (ErrNotFound
== rv
)
473 printError(ErrSyntaxError
, "Field %s does not exist in table",
475 return ErrSyntaxError
;
477 if (fInfo
->isUnique
) {
479 printError(ErrUnique
, "Unique field %s cannot be updated", value
->fldName
);
482 if (fInfo
->isAutoIncrement
){
484 printError(ErrAutoIncUpdate
, "Auto_increment key field '%s' cannot be updated \n", value
->fldName
);
485 return ErrAutoIncUpdate
;
488 value
->type
= fInfo
->type
;
489 value
->length
= fInfo
->length
;
490 value
->isNullable
= fInfo
->isNull
;
491 // for binary datatype input buffer size should be 2 times the length
492 if (value
->type
== typeBinary
)
493 value
->value
= AllDataType::alloc(fInfo
->type
, 2 * fInfo
->length
);
494 else value
->value
= AllDataType::alloc(fInfo
->type
, fInfo
->length
);
495 table
->bindFld(value
->fldName
, value
->value
);
496 if( NULL
!= value
->expre
)
498 (value
->expre
)->convertStrToVal(value
->type
);
501 if (value
->parsedString
== NULL
)
503 if (fInfo
->isNull
) { delete fInfo
; return ErrNullViolation
; }
504 table
->markFldNull(value
->fldName
);
507 if (value
->parsedString
[0] == '?')
509 value
->paramNo
= paramPos
++;
511 if (!value
->paramNo
) {
512 // for binary datatype buffer is just strcpy'd. It will be converted into binary datatype in copyValuesToBindBuffer in DBAPI
513 if (value
->type
== typeBinary
)
514 strncpy((char *)value
->value
, value
->parsedString
, 2 * fInfo
->length
);
515 else AllDataType::strToValue(value
->value
, value
->parsedString
, fInfo
->type
, value
->length
);
518 totalAssignParams
= paramPos
-1;
521 //get the fieldname list and validate field names
522 ListIterator cIter
= parsedData
->getConditionValueList().getIterator();
523 ConditionValue
*cValue
= NULL
;
524 while (cIter
.hasElement())
526 cValue
= (ConditionValue
*) cIter
.nextElement();
530 printError(ErrSysFatal
, "Should never happen.");
533 rv
= table
->getFieldInfo(cValue
->fName
, fInfo
);
534 if (ErrNotFound
== rv
)
537 printError(ErrSyntaxError
, "Field %s does not exist in table",
539 return ErrSyntaxError
;
541 cValue
->type
= fInfo
->type
;
542 cValue
->length
= fInfo
->length
;
543 cValue
->isNullable
= fInfo
->isNull
;
544 // for binary datatype input buffer size should be 2 times the length
545 if (cValue
->type
== typeBinary
)
547 if(cValue
->parsedString
[0] == '?')
548 cValue
->value
= AllDataType::alloc(fInfo
->type
, fInfo
->length
);
550 cValue
->value
= AllDataType::alloc(fInfo
->type
, 2 * fInfo
->length
);
552 else cValue
->value
= AllDataType::alloc(fInfo
->type
, fInfo
->length
);
553 if(cValue
->paramNo
== 1){continue;}
554 if (cValue
->parsedString
== NULL
)
557 printError(ErrSyntaxError
, "Condition value should not be NULL");
558 return ErrSyntaxError
;
561 if (cValue
->parsedString
[0] == '?')
563 if(! cValue
->opLike
) // checks if 'LIKE' operator is used
564 cValue
->paramNo
= paramPos
++;
566 if (!cValue
->paramNo
) {
567 // Here for binary dataType it is not strcpy'd bcos internally memcmp is done for predicates like f2 = 'abcd' where f2 is binary
568 AllDataType::strToValue(cValue
->value
, cValue
->parsedString
, fInfo
->type
, fInfo
->length
);
573 totalParams
= paramPos
-1;
574 if (0 == totalParams
) return OK
;
575 params
= (void**) malloc ( totalParams
* sizeof(FieldValue
*));
576 paramValues
= (char**) malloc( totalParams
* sizeof(char*));
578 memset(params
, 0, totalParams
* sizeof(FieldValue
*));
579 memset(paramValues
, 0, totalParams
* sizeof(char*));
582 while(iter
.hasElement())
584 value
= (UpdateFieldValue
*) iter
.nextElement();
587 free(params
); params
= NULL
;
588 free(paramValues
); paramValues
= NULL
;
589 printError(ErrSysFatal
, "Should never happen. value NULL after iteration");
592 if (0 == value
->paramNo
) continue;
593 params
[value
->paramNo
-1 ] = value
;
597 while(cIter
.hasElement())
599 cValue
= (ConditionValue
*) cIter
.nextElement();
602 free(params
); params
= NULL
;
603 free(paramValues
); paramValues
= NULL
;
604 printError(ErrSysFatal
, "Should never happen. value NULL after iteration");
607 if (0 == cValue
->paramNo
) continue;
608 params
[cValue
->paramNo
-1 ] = cValue
;
612 int UpdStatement::getFldPos(char *name
)
614 return table
->getFldPos(name
);