error in parsing date and time leads to wrong value being inserted into the table
[csql.git] / src / sql / InsStatement.cxx
blob9c42e968d0c876a54c8b36bb6298e7fdb87a970d
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 <os.h>
17 #include <Statement.h>
18 #include <Info.h>
20 DbRetVal DmlStatement::getFieldInfo(const char *tname, const char *fname, FieldInfo *& info)
22 if (table) {
23 if (strcmp(tname, table->getName())==0)
24 return table->getFieldInfo(fname, info);
26 return ErrNotExists;
29 List DmlStatement::getFieldNameList(const char *tname, DbRetVal &rv)
31 if (table) {
32 if (strcmp(tname, table->getName())==0)
33 return table->getFieldNameList();
35 rv = ErrNotExists;
38 InsStatement::InsStatement()
40 parsedData = NULL;
41 dbMgr = NULL;
42 table = NULL;
43 params = NULL;
44 paramValues = NULL;
45 totalParams = 0;
48 InsStatement::~InsStatement()
50 if (table) { table->close(); table = NULL; }
51 if (totalParams) {
52 free(params);
53 params = NULL;
54 free(paramValues);
55 paramValues = NULL;
59 DbRetVal InsStatement::getParamFldInfo(int paramPos, FieldInfo *&info)
61 if (paramPos >totalParams ) return ErrBadCall;
62 FieldValue *value = (FieldValue*)params[paramPos-1];
63 if (value == NULL)
65 printError(ErrSysFatal, "param ptr is null: should never happen\n");
66 return ErrBadArg;
68 table->getFieldNameAlone(value->fldName,info->fldName);
69 info->type = value->type;
70 info->length = value->length;
71 info->isNull = value->isNullable;
72 return OK;
75 DbRetVal InsStatement::execute(int &rowsAffected)
77 DbRetVal rv = OK;
78 //copy param values to binded buffer
79 FieldValue *value;
80 for (int i = 0; i < totalParams; i ++)
82 value = (FieldValue*) params[i];
83 if (paramValues[i] == NULL)
85 //printError(ErrBadCall, "param values not set");
86 continue;
87 //return ErrBadCall;
89 AllDataType::copyVal(value->value, paramValues[i], value->type, value->length);
91 rv = table->insertTuple();
92 if (rv ==OK) rowsAffected = 1;
93 table-> resetNullinfo();
94 return rv;
97 DbRetVal InsStatement::setParam(int paramNo, void *value)
99 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
100 if (NULL == value) return ErrBadArg;
101 paramValues[paramNo -1] = (char*) value;
102 return OK;
105 DbRetVal InsStatement::setShortParam(int paramNo, short value)
107 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
108 FieldValue *fValue = (FieldValue*) params [paramNo-1];
109 if (NULL == fValue)
111 printError(ErrSysFatal, "field value is null. Should never happen");
112 return ErrSysFatal;
114 *(short*)fValue->value = value;
115 return OK;
118 DbRetVal InsStatement::setIntParam(int paramNo, int value)
120 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
121 FieldValue *cValue = (FieldValue*) params [paramNo-1];
122 if (NULL == cValue)
124 printError(ErrSysFatal, "condition value is null. Should never happen");
125 return ErrSysFatal;
128 *(int*)cValue->value = value;
129 return OK;
131 DbRetVal InsStatement::setNull(int paramNo)
133 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
134 FieldValue *cValue = (FieldValue*) params [paramNo-1];
135 if (NULL == cValue)
137 printError(ErrSysFatal, "FieldValue is null. Should never happen");
138 return ErrSysFatal;
140 char name[IDENTIFIER_LENGTH];
141 table->getFieldNameAlone(cValue->fldName,name);
142 table->markFldNull(name);
143 return OK;
145 DbRetVal InsStatement::setLongParam(int paramNo, long value)
147 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
148 FieldValue *cValue = (FieldValue*) params [paramNo-1];
149 if (NULL == cValue)
151 printError(ErrSysFatal, "condition value is null. Should never happen");
152 return ErrSysFatal;
154 *(long*)cValue->value = value;
155 return OK;
158 DbRetVal InsStatement::setLongLongParam(int paramNo, long long value)
160 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
161 FieldValue *cValue = (FieldValue*) params [paramNo-1];
162 if (NULL == cValue)
164 printError(ErrSysFatal, "condition value is null. Should never happen");
165 return ErrSysFatal;
167 *(long long*)cValue->value = value;
168 return OK;
170 DbRetVal InsStatement::setByteIntParam(int paramNo, ByteInt value)
172 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
173 FieldValue *cValue = (FieldValue*) params [paramNo-1];
174 if (NULL == cValue)
176 printError(ErrSysFatal, "condition value is null. Should never happen");
177 return ErrSysFatal;
179 *(ByteInt*)cValue->value = value;
180 return OK;
182 DbRetVal InsStatement::setFloatParam(int paramNo, float value)
184 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
185 FieldValue *cValue = (FieldValue*) params [paramNo-1];
186 if (NULL == cValue)
188 printError(ErrSysFatal, "condition value is null. Should never happen");
189 return ErrSysFatal;
191 *(float*)cValue->value = value;
192 return OK;
194 DbRetVal InsStatement::setDoubleParam(int paramNo, double value)
196 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
197 FieldValue *cValue = (FieldValue*) params [paramNo-1];
198 if (NULL == cValue)
200 printError(ErrSysFatal, "condition value is null. Should never happen");
201 return ErrSysFatal;
203 *(double*)cValue->value = value;
204 return OK;
206 DbRetVal InsStatement::setStringParam(int paramNo, char *value)
208 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
209 FieldValue *cValue = (FieldValue*) params [paramNo-1];
210 if (NULL == cValue)
212 printError(ErrSysFatal, "condition value is null. Should never happen");
213 return ErrSysFatal;
215 //TODO::check if the strlen(value) is greater than field length
216 //do in all stmts
217 strcpy((char*)cValue->value, value);
218 return OK;
220 DbRetVal InsStatement::setDateParam(int paramNo, Date value)
222 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
223 FieldValue *cValue = (FieldValue*) params [paramNo-1];
224 if (NULL == cValue)
226 printError(ErrSysFatal, "condition value is null. Should never happen");
227 return ErrSysFatal;
229 *(Date*)cValue->value = value;
230 return OK;
232 DbRetVal InsStatement::setTimeParam(int paramNo, Time value)
234 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
235 FieldValue *cValue = (FieldValue*) params [paramNo-1];
236 if (NULL == cValue)
238 printError(ErrSysFatal, "condition value is null. Should never happen");
239 return ErrSysFatal;
241 *(Time*)cValue->value = value;
242 return OK;
244 void* InsStatement::getParamValuePtr( int pos )
246 FieldValue *p = (FieldValue*) params [pos-1];
247 return ( (void*) p->value );
250 DbRetVal InsStatement::setTimeStampParam(int paramNo, TimeStamp value)
252 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
253 FieldValue *cValue = (FieldValue*) params [paramNo-1];
254 if (NULL == cValue)
256 printError(ErrSysFatal, "condition value is null. Should never happen");
257 return ErrSysFatal;
259 *(TimeStamp*)cValue->value = value;
260 return OK;
263 DbRetVal InsStatement::setBinaryParam(int paramNo, void *value, int length)
265 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
266 FieldValue *fValue = (FieldValue*) params [paramNo-1];
267 if (NULL == fValue)
269 printError(ErrSysFatal, "field value is null. Should never happen");
270 return ErrSysFatal;
272 memcpy(fValue->value, value, 2 * fValue->length);
273 return OK;
276 long long InsStatement::getLastInsertedVal(DbRetVal &rv)
278 if(table)
279 return ((TableImpl*)table)->getLastInsertedVal(rv);
280 else{
281 rv = ErrBadCall;
282 return 0;
286 DbRetVal InsStatement::resolve()
288 if (dbMgr == NULL) return ErrNoConnection;
289 //check whether the table exists
290 table = dbMgr->openTable(parsedData->getTableName());
291 if (table == NULL)
293 printError(ErrNotExists, "Unable to open the table:Table not exists");
294 return ErrNotExists;
297 List fieldNameList;
298 //check whether filed list is specified
299 if( 0 == parsedData->getFieldNameList().size() )
300 fieldNameList = table->getFieldNameList();
301 else
302 fieldNameList = parsedData->getFieldNameList();
304 //check whether the total number of field name in the list is same as the total
305 //number of values provided in the values list.
306 if ( fieldNameList.size() !=
307 parsedData->getFieldValueList().size())
309 dbMgr->closeTable(table);
310 table = NULL;
311 printError(ErrSyntaxError, "Field Name list and field values do not match");
312 return ErrSyntaxError;
315 //get the fieldname list and validate field names
316 ListIterator iter = fieldNameList.getIterator();
317 ListIterator valIter = parsedData->getFieldValueList().getIterator();
318 FieldName *name; FieldValue *value;
319 FieldInfo *fInfo = new FieldInfo();
320 int paramPos =1;
321 DbRetVal rv = OK;
322 while (iter.hasElement())
324 name = (FieldName*)iter.nextElement();
325 value = (FieldValue*) valIter.nextElement();
326 if (NULL == name || NULL == value)
328 dbMgr->closeTable(table);
329 table = NULL;
330 delete fInfo;
331 printError(ErrSyntaxError, "Field Name list and field values do not match");
332 return ErrSyntaxError;
334 rv = table->getFieldInfo(name->fldName, fInfo);
335 if (ErrNotFound == rv)
337 dbMgr->closeTable(table);
338 table = NULL;
339 delete fInfo;
340 printError(ErrSyntaxError, "Field %s does not exist in table",
341 name->fldName);
342 return ErrSyntaxError;
344 strcpy(value->fldName,name->fldName);
345 value->type = fInfo->type;
346 value->length = fInfo->length;
347 value->isNullable = fInfo->isNull;
348 // for binary datatype input buffer size should be 2 times the length
349 if (fInfo->type == typeBinary)
350 value->value = AllDataType::alloc(fInfo->type, 2 * fInfo->length);
351 else value->value = AllDataType::alloc(fInfo->type, fInfo->length);
352 value->isAllocVal = true;
353 if (value->parsedString == NULL) {
354 table->bindFld(name->fldName, NULL, true);
355 continue;
357 table->bindFld(name->fldName, value->value);
358 if (value->parsedString[0] == '?')
360 value->paramNo = paramPos++;
362 if (!value->paramNo) {
363 // Checking Integer value
364 if((value->type == typeInt) || (value->type==typeShort) || (value->type==typeByteInt) || (value->type==typeLongLong) || (value->type==typeLong)){
365 int len=strlen(value->parsedString);
366 for(int n=0;n<len;n++){
367 int p=value->parsedString[n];
368 if(!(p>=48 && p<=57 || p==45) )
369 delete fInfo;
370 return ErrBadArg;
373 // for binary datatype buffer is just strcpy'd.
374 //It will be converted into binary datatype in copyValuesToBindBuffer in DBAPI
375 if (value->type == typeBinary)
376 strncpy((char *)value->value, value->parsedString, 2 * fInfo->length);
377 else {
378 rv = AllDataType::strToValue(value->value, value->parsedString, fInfo->type, fInfo->length);
379 if (OK != rv) {
380 delete fInfo;
381 return ErrBadArg;
385 /* Checking range for char data type 8kb(8000) */
386 if(value->type==typeString){
387 int len=strlen(value->parsedString);
388 if(len > 8000){
389 printError(ErrBadRange,"Char data type length should be less than 8kb(8000).");
390 delete fInfo;
391 return ErrBadRange;
397 delete fInfo;
398 totalParams = paramPos -1;
399 if (0 == totalParams) {
400 if( 0 == parsedData->getFieldNameList().size() ) {
401 iter.reset();
402 while(iter.hasElement())
403 delete (Identifier *) iter.nextElement();
404 fieldNameList.reset();
406 return OK;
408 params = (void**) malloc ( totalParams * sizeof(FieldValue*));
409 paramValues = (char**) malloc( totalParams * sizeof(char*));
410 memset(params, 0, totalParams * sizeof(FieldValue*));
411 memset(paramValues, 0, totalParams * sizeof(char*));
412 valIter.reset();
413 while(valIter.hasElement())
415 value = (FieldValue*) valIter.nextElement();
416 if (value == NULL)
418 dbMgr->closeTable(table);
419 table = NULL;
420 free(params); params = NULL;
421 free(paramValues); paramValues = NULL;
422 printError(ErrSysFatal, "Should never happen. value NULL after iteration");
423 return ErrSysFatal;
425 if (value->paramNo == 0) continue;
426 params[value->paramNo -1 ] = value;
428 // memory to be deallocated created by table->getFieldNameList
429 if( 0 == parsedData->getFieldNameList().size() ) {
430 iter.reset();
431 while(iter.hasElement())
432 delete (Identifier *) iter.nextElement();
433 fieldNameList.reset();
435 return OK;
437 int InsStatement::getFldPos(char *name)
439 return table->getFldPos(name);