Varchar free when compact table was called.
[csql.git] / src / sql / InsStatement.cxx
blob3248f04e980a437a27cb82d939fbd3526a67db5d
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 InsStatement::InsStatement()
22 parsedData = NULL;
23 dbMgr = NULL;
24 table = NULL;
25 params = NULL;
26 paramValues = NULL;
27 totalParams = 0;
30 InsStatement::~InsStatement()
32 if (table) { table->close(); table = NULL; }
33 if (totalParams) {
34 free(params);
35 params = NULL;
36 free(paramValues);
37 paramValues = NULL;
41 DbRetVal InsStatement::getParamFldInfo(int paramPos, FieldInfo *&info)
43 if (paramPos >totalParams ) return ErrBadCall;
44 FieldValue *value = (FieldValue*)params[paramPos-1];
45 if (value == NULL)
47 printError(ErrSysFatal, "param ptr is null: should never happen\n");
48 return ErrBadArg;
50 table->getFieldNameAlone(value->fldName,info->fldName);
51 info->type = value->type;
52 info->length = value->length;
53 info->isNull = value->isNullable;
54 return OK;
57 DbRetVal InsStatement::execute(int &rowsAffected)
59 DbRetVal rv = OK;
60 //copy param values to binded buffer
61 FieldValue *value;
62 for (int i = 0; i < totalParams; i ++)
64 value = (FieldValue*) params[i];
65 if (paramValues[i] == NULL)
67 //printError(ErrBadCall, "param values not set");
68 continue;
69 //return ErrBadCall;
71 AllDataType::copyVal(value->value, paramValues[i], value->type, value->length);
73 rv = table->insertTuple();
74 if (rv ==OK) rowsAffected = 1;
75 table-> resetNullinfo();
76 return rv;
79 DbRetVal InsStatement::setParam(int paramNo, void *value)
81 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
82 if (NULL == value) return ErrBadArg;
83 paramValues[paramNo -1] = (char*) value;
84 return OK;
87 DbRetVal InsStatement::setShortParam(int paramNo, short value)
89 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
90 FieldValue *fValue = (FieldValue*) params [paramNo-1];
91 if (NULL == fValue)
93 printError(ErrSysFatal, "field value is null. Should never happen");
94 return ErrSysFatal;
96 *(short*)fValue->value = value;
97 return OK;
100 DbRetVal InsStatement::setIntParam(int paramNo, int value)
102 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
103 FieldValue *cValue = (FieldValue*) params [paramNo-1];
104 if (NULL == cValue)
106 printError(ErrSysFatal, "condition value is null. Should never happen");
107 return ErrSysFatal;
110 *(int*)cValue->value = value;
111 return OK;
113 DbRetVal InsStatement::setNull(int paramNo)
115 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
116 FieldValue *cValue = (FieldValue*) params [paramNo-1];
117 if (NULL == cValue)
119 printError(ErrSysFatal, "FieldValue is null. Should never happen");
120 return ErrSysFatal;
122 char name[IDENTIFIER_LENGTH];
123 table->getFieldNameAlone(cValue->fldName,name);
124 table->markFldNull(name);
125 return OK;
127 DbRetVal InsStatement::setLongParam(int paramNo, long value)
129 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
130 FieldValue *cValue = (FieldValue*) params [paramNo-1];
131 if (NULL == cValue)
133 printError(ErrSysFatal, "condition value is null. Should never happen");
134 return ErrSysFatal;
136 *(long*)cValue->value = value;
137 return OK;
140 DbRetVal InsStatement::setLongLongParam(int paramNo, long long value)
142 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
143 FieldValue *cValue = (FieldValue*) params [paramNo-1];
144 if (NULL == cValue)
146 printError(ErrSysFatal, "condition value is null. Should never happen");
147 return ErrSysFatal;
149 *(long long*)cValue->value = value;
150 return OK;
152 DbRetVal InsStatement::setByteIntParam(int paramNo, ByteInt value)
154 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
155 FieldValue *cValue = (FieldValue*) params [paramNo-1];
156 if (NULL == cValue)
158 printError(ErrSysFatal, "condition value is null. Should never happen");
159 return ErrSysFatal;
161 *(ByteInt*)cValue->value = value;
162 return OK;
164 DbRetVal InsStatement::setFloatParam(int paramNo, float value)
166 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
167 FieldValue *cValue = (FieldValue*) params [paramNo-1];
168 if (NULL == cValue)
170 printError(ErrSysFatal, "condition value is null. Should never happen");
171 return ErrSysFatal;
173 *(float*)cValue->value = value;
174 return OK;
176 DbRetVal InsStatement::setDoubleParam(int paramNo, double value)
178 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
179 FieldValue *cValue = (FieldValue*) params [paramNo-1];
180 if (NULL == cValue)
182 printError(ErrSysFatal, "condition value is null. Should never happen");
183 return ErrSysFatal;
185 *(double*)cValue->value = value;
186 return OK;
188 DbRetVal InsStatement::setStringParam(int paramNo, char *value)
190 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
191 FieldValue *cValue = (FieldValue*) params [paramNo-1];
192 if (NULL == cValue)
194 printError(ErrSysFatal, "condition value is null. Should never happen");
195 return ErrSysFatal;
197 //TODO::check if the strlen(value) is greater than field length
198 //do in all stmts
199 strcpy((char*)cValue->value, value);
200 return OK;
202 DbRetVal InsStatement::setDateParam(int paramNo, Date value)
204 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
205 FieldValue *cValue = (FieldValue*) params [paramNo-1];
206 if (NULL == cValue)
208 printError(ErrSysFatal, "condition value is null. Should never happen");
209 return ErrSysFatal;
211 *(Date*)cValue->value = value;
212 return OK;
214 DbRetVal InsStatement::setTimeParam(int paramNo, Time value)
216 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
217 FieldValue *cValue = (FieldValue*) params [paramNo-1];
218 if (NULL == cValue)
220 printError(ErrSysFatal, "condition value is null. Should never happen");
221 return ErrSysFatal;
223 *(Time*)cValue->value = value;
224 return OK;
226 void* InsStatement::getParamValuePtr( int pos )
228 FieldValue *p = (FieldValue*) params [pos-1];
229 return ( (void*) p->value );
232 DbRetVal InsStatement::setTimeStampParam(int paramNo, TimeStamp 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 *(TimeStamp*)cValue->value = value;
242 return OK;
245 DbRetVal InsStatement::setBinaryParam(int paramNo, void *value, int length)
247 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
248 FieldValue *fValue = (FieldValue*) params [paramNo-1];
249 if (NULL == fValue)
251 printError(ErrSysFatal, "field value is null. Should never happen");
252 return ErrSysFatal;
254 memcpy(fValue->value, value, 2 * fValue->length);
255 return OK;
258 long long InsStatement::getLastInsertedVal(DbRetVal &rv)
260 if(table)
261 return ((TableImpl*)table)->getLastInsertedVal(rv);
262 else{
263 rv = ErrBadCall;
264 return 0;
268 DbRetVal InsStatement::resolve()
270 if (dbMgr == NULL) return ErrNoConnection;
271 //check whether the table exists
272 table = dbMgr->openTable(parsedData->getTableName());
273 if (table == NULL)
275 printError(ErrNotExists, "Unable to open the table:Table not exists");
276 return ErrNotExists;
279 List fieldNameList;
280 //check whether filed list is specified
281 if( 0 == parsedData->getFieldNameList().size() )
282 fieldNameList = table->getFieldNameList();
283 else
284 fieldNameList = parsedData->getFieldNameList();
286 //check whether the total number of field name in the list is same as the total
287 //number of values provided in the values list.
288 if ( fieldNameList.size() !=
289 parsedData->getFieldValueList().size())
291 dbMgr->closeTable(table);
292 table = NULL;
293 printError(ErrSyntaxError, "Field Name list and field values do not match");
294 return ErrSyntaxError;
297 //get the fieldname list and validate field names
298 ListIterator iter = fieldNameList.getIterator();
299 ListIterator valIter = parsedData->getFieldValueList().getIterator();
300 FieldName *name; FieldValue *value;
301 FieldInfo *fInfo = new FieldInfo();
302 int paramPos =1;
303 DbRetVal rv = OK;
304 while (iter.hasElement())
306 name = (FieldName*)iter.nextElement();
307 value = (FieldValue*) valIter.nextElement();
308 if (NULL == name || NULL == value)
310 dbMgr->closeTable(table);
311 table = NULL;
312 delete fInfo;
313 printError(ErrSyntaxError, "Field Name list and field values do not match");
314 return ErrSyntaxError;
316 rv = table->getFieldInfo(name->fldName, fInfo);
317 if (ErrNotFound == rv)
319 dbMgr->closeTable(table);
320 table = NULL;
321 delete fInfo;
322 printError(ErrSyntaxError, "Field %s does not exist in table",
323 name->fldName);
324 return ErrSyntaxError;
326 strcpy(value->fldName,name->fldName);
327 value->type = fInfo->type;
328 value->length = fInfo->length;
329 value->isNullable = fInfo->isNull;
330 // for binary datatype input buffer size should be 2 times the length
331 if (fInfo->type == typeBinary)
332 value->value = AllDataType::alloc(fInfo->type, 2 * fInfo->length);
333 else value->value = AllDataType::alloc(fInfo->type, fInfo->length);
334 value->isAllocVal = true;
335 if (value->parsedString == NULL) {
336 table->bindFld(name->fldName, NULL, true);
337 continue;
339 table->bindFld(name->fldName, value->value);
340 if (value->parsedString[0] == '?')
342 value->paramNo = paramPos++;
344 if (!value->paramNo) {
345 // Checking Integer value
346 if((value->type == typeInt) || (value->type==typeShort) || (value->type==typeByteInt) || (value->type==typeLongLong) || (value->type==typeLong)){
347 int len=strlen(value->parsedString);
348 for(int n=0;n<len;n++){
349 int p=value->parsedString[n];
350 if(!(p>=48 && p<=57 || p==45) )
351 return ErrBadArg;
354 // for binary datatype buffer is just strcpy'd. It will be converted into binary datatype in copyValuesToBindBuffer in DBAPI
355 if (value->type == typeBinary)
356 strncpy((char *)value->value, value->parsedString, 2 * fInfo->length);
357 else AllDataType::strToValue(value->value, value->parsedString, fInfo->type, fInfo->length);
358 /* Checking range for char data type 8kb(8000) */
359 if(value->type==typeString){
360 int len=strlen(value->parsedString);
361 if(len > 8000){
362 printError(ErrBadRange,"Char data type length should be less than 8kb(8000).");
363 return ErrBadRange;
369 delete fInfo;
370 totalParams = paramPos -1;
371 if (0 == totalParams) {
372 if( 0 == parsedData->getFieldNameList().size() ) {
373 iter.reset();
374 while(iter.hasElement())
375 delete (Identifier *) iter.nextElement();
376 fieldNameList.reset();
378 return OK;
380 params = (void**) malloc ( totalParams * sizeof(FieldValue*));
381 paramValues = (char**) malloc( totalParams * sizeof(char*));
382 memset(params, 0, totalParams * sizeof(FieldValue*));
383 memset(paramValues, 0, totalParams * sizeof(char*));
384 valIter.reset();
385 while(valIter.hasElement())
387 value = (FieldValue*) valIter.nextElement();
388 if (value == NULL)
390 dbMgr->closeTable(table);
391 table = NULL;
392 free(params); params = NULL;
393 free(paramValues); paramValues = NULL;
394 printError(ErrSysFatal, "Should never happen. value NULL after iteration");
395 return ErrSysFatal;
397 if (value->paramNo == 0) continue;
398 params[value->paramNo -1 ] = value;
400 // memory to be deallocated created by table->getFieldNameList
401 if( 0 == parsedData->getFieldNameList().size() ) {
402 iter.reset();
403 while(iter.hasElement())
404 delete (Identifier *) iter.nextElement();
405 fieldNameList.reset();
407 return OK;
409 int InsStatement::getFldPos(char *name)
411 return table->getFldPos(name);