Bug in putting the prepare packet in the list
[csql.git] / src / sql / SelStatement.cxx
blob45235a3932853e651af7bb2d2aa0a8296acf1a12
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"
18 SelStatement::SelStatement()
20 parsedData = NULL;
21 dbMgr = NULL;
22 table = NULL;
23 params = NULL;
24 paramValues = NULL;
25 totalParams = 0;
26 bindFields = NULL;
27 bindFieldValues = NULL;
28 totalFields = 0;
31 SelStatement::~SelStatement()
33 if (table) {
34 table->setCondition(NULL);
35 if (dbMgr) dbMgr->closeTable(table);
37 if (totalParams) {
38 free(params);
39 params = NULL;
40 free(paramValues);
41 paramValues = NULL;
43 if (totalFields)
45 free(bindFields);
46 bindFields = NULL;
47 free(bindFieldValues);
48 bindFieldValues = NULL;
52 DbRetVal SelStatement::getParamFldInfo(int paramNo, FieldInfo *&info)
54 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
55 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
56 if (NULL == cValue)
58 printError(ErrSysFatal, "condition value is null. Should never happen");
59 return ErrSysFatal;
61 info->type = cValue->type;
62 info->length = cValue->length;
63 return OK;
65 DbRetVal SelStatement::execute(int &rowsAffected)
67 DbRetVal rv = OK;
68 //copy param values to binded buffer
69 ConditionValue *value;
70 for (int i = 0; i < totalParams; i ++)
72 value = (ConditionValue*) params[i];
73 if (paramValues[i] == NULL)
75 continue;
76 //printError(ErrBadCall, "param values not set");
77 //return ErrBadCall;
79 AllDataType::copyVal(value->value, paramValues[i], value->type, value->length);
81 rv = table->execute();
82 return rv;
85 DbRetVal SelStatement::setParam(int paramNo, void *value)
87 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
88 if (NULL == value) return ErrBadArg;
89 paramValues[paramNo -1] = (char*) value;
90 return OK;
93 DbRetVal SelStatement::setShortParam(int paramNo, short value)
95 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
96 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
97 if (NULL == cValue)
99 printError(ErrSysFatal, "field value is null. Should never happen");
100 return ErrSysFatal;
102 *(short*)cValue->value = value;
103 return OK;
106 DbRetVal SelStatement::setIntParam(int paramNo, int value)
108 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
109 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
110 if (NULL == cValue)
112 printError(ErrSysFatal, "condition value is null. Should never happen");
113 return ErrSysFatal;
115 *(int*)cValue->value = value;
116 return OK;
118 DbRetVal SelStatement::setLongParam(int paramNo, long value)
120 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
121 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
122 if (NULL == cValue)
124 printError(ErrSysFatal, "condition value is null. Should never happen");
125 return ErrSysFatal;
127 *(long*)cValue->value = value;
128 return OK;
131 DbRetVal SelStatement::setLongLongParam(int paramNo, long long value)
133 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
134 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
135 if (NULL == cValue)
137 printError(ErrSysFatal, "condition value is null. Should never happen");
138 return ErrSysFatal;
140 *(long long*)cValue->value = value;
141 return OK;
143 DbRetVal SelStatement::setByteIntParam(int paramNo, ByteInt value)
145 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
146 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
147 if (NULL == cValue)
149 printError(ErrSysFatal, "condition value is null. Should never happen");
150 return ErrSysFatal;
152 *(ByteInt*)cValue->value = value;
153 return OK;
155 DbRetVal SelStatement::setFloatParam(int paramNo, float value)
157 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
158 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
159 if (NULL == cValue)
161 printError(ErrSysFatal, "condition value is null. Should never happen");
162 return ErrSysFatal;
164 *(float*)cValue->value = value;
165 return OK;
167 DbRetVal SelStatement::setDoubleParam(int paramNo, double value)
169 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
170 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
171 if (NULL == cValue)
173 printError(ErrSysFatal, "condition value is null. Should never happen");
174 return ErrSysFatal;
176 *(double*)cValue->value = value;
177 return OK;
179 DbRetVal SelStatement::setStringParam(int paramNo, char *value)
181 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
182 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
183 if (NULL == cValue)
185 printError(ErrSysFatal, "condition value is null. Should never happen");
186 return ErrSysFatal;
188 strcpy((char*)cValue->value, value);
189 return OK;
191 DbRetVal SelStatement::setDateParam(int paramNo, Date value)
193 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
194 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
195 if (NULL == cValue)
197 printError(ErrSysFatal, "condition value is null. Should never happen");
198 return ErrSysFatal;
200 *(Date*)cValue->value = value;
201 return OK;
203 DbRetVal SelStatement::setTimeParam(int paramNo, Time value)
205 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
206 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
207 if (NULL == cValue)
209 printError(ErrSysFatal, "condition value is null. Should never happen");
210 return ErrSysFatal;
212 *(Time*)cValue->value = value;
213 return OK;
215 DbRetVal SelStatement::setTimeStampParam(int paramNo, TimeStamp value)
217 if (paramNo <=0 || paramNo > totalParams) return ErrBadArg;
218 ConditionValue *cValue = (ConditionValue*) params [paramNo-1];
219 if (NULL == cValue)
221 printError(ErrSysFatal, "condition value is null. Should never happen");
222 return ErrSysFatal;
224 *(TimeStamp*)cValue->value = value;
225 return OK;
228 DbRetVal SelStatement::setBindField(int colNo, void *value)
230 if (colNo <=0) return ErrBadArg;
231 //TODO: check the upper limit
232 //if (colNo > table->getFieldNameList().size()) return ErrBadArg;
233 if (NULL == value) return ErrBadArg;
234 bindFieldValues[colNo -1] = (char*) value;
235 return OK;
238 DbRetVal SelStatement::resolve()
240 if (dbMgr == NULL) return ErrNoConnection;
241 //check whether the table exists
242 table = dbMgr->openTable(parsedData->getTableName());
243 if (table == NULL)
245 printError(ErrNotExists, "Unable to open the table:Table not exists");
246 return ErrNotExists;
248 //get the fieldname list and validate field names
249 ListIterator iter = parsedData->getFieldNameList().getIterator();
250 FieldName *name = NULL;
251 FieldInfo *fInfo = new FieldInfo();
252 DbRetVal rv = OK;
253 while (iter.hasElement())
255 name = (FieldName*)iter.nextElement();
256 if (NULL == name)
258 dbMgr->closeTable(table);
259 table = NULL;
260 delete fInfo;
261 printError(ErrSysFatal, "Should never happen. Field Name list has NULL");
262 return ErrSysFatal;
264 if ('*' == name->fldName[0])
266 rv = resolveStar();
267 if (rv != OK)
269 dbMgr->closeTable(table);
270 table = NULL;
271 delete fInfo;
272 return rv;
274 //as soon as it encounters *, it breaks the loop negleting other field names
275 //as they all are deleted during resolveStar method.
276 break;
277 } else {
278 rv = table->getFieldInfo(name->fldName, fInfo);
279 if (ErrNotFound == rv)
281 dbMgr->closeTable(table);
282 table = NULL;
283 delete fInfo;
284 printError(ErrSyntaxError, "Field %s does not exist in table",
285 name->fldName);
286 return ErrSyntaxError;
288 FieldValue *newVal = new FieldValue();
289 newVal->parsedString = NULL;
290 newVal->paramNo = 0;
291 newVal->type = fInfo->type;
292 newVal->length = fInfo->length;
293 newVal->value = AllDataType::alloc(fInfo->type, fInfo->length);
294 parsedData->insertFieldValue(newVal);
295 table->bindFld(name->fldName, newVal->value);
298 delete fInfo;
300 rv = setBindFieldAndValues();
301 if (rv != OK)
303 dbMgr->closeTable(table);
304 table = NULL;
305 return rv;
308 table->setCondition(parsedData->getCondition());
310 rv = resolveForCondition();
311 if (rv != OK)
313 //TODO::free memory allocated for params
314 table->setCondition(NULL);
315 dbMgr->closeTable(table);
316 table = NULL;
318 return rv;
320 DbRetVal SelStatement::resolveStar()
322 DbRetVal rv = OK;
323 parsedData->clearFieldNameList();
324 List fNameList = table->getFieldNameList();
325 ListIterator fNameIter = fNameList.getIterator();
326 FieldValue *newVal = NULL;
327 //fNameList.resetIter(); //do not remove this.
328 FieldInfo *fInfo = new FieldInfo();
329 for (int i = 0; i < fNameList.size() ; i++)
331 char *fName = ((Identifier*)(fNameIter.nextElement()))->name;
332 rv = table->getFieldInfo(fName, fInfo);
333 if (ErrNotFound == rv)
335 delete fInfo;
336 fNameList.reset();
337 printError(ErrSysFatal, "Should never happen.");
338 return ErrSysFatal;
340 newVal = new FieldValue();
341 newVal->parsedString = NULL;
342 newVal->paramNo = 0;
343 newVal->type = fInfo->type;
344 newVal->length = fInfo->length;
345 newVal->value = AllDataType::alloc(fInfo->type, fInfo->length);
346 parsedData->insertFieldValue(newVal);
347 parsedData->insertField(fName);
348 table->bindFld(fName, newVal->value);
350 delete fInfo;
351 return OK;
354 DbRetVal SelStatement::setBindFieldAndValues()
356 totalFields = parsedData->getFieldNameList().size();
357 bindFields = (FieldValue**) malloc ( totalFields * sizeof(FieldValue*));
358 bindFieldValues = (char**) malloc( totalFields * sizeof(char*));
359 memset(bindFields, 0, totalFields * sizeof(FieldValue*));
360 memset(bindFieldValues, 0, totalFields * sizeof(char*));
361 ListIterator valIter = parsedData->getFieldValueList().getIterator();
362 int colNo =0;
363 FieldValue *value = NULL;
364 valIter.reset();
365 while(valIter.hasElement())
367 value = (FieldValue*) valIter.nextElement();
368 if (value == NULL)
370 free(bindFields); bindFields = NULL;
371 free(bindFieldValues); bindFieldValues = NULL;
372 printError(ErrSysFatal, "Should never happen. value NULL after iteration");
373 return ErrSysFatal;
375 bindFields[colNo++ ] = value;
377 return OK;
381 DbRetVal SelStatement::resolveForCondition()
383 //get the fieldname list and validate field names
384 ListIterator iter = parsedData->getConditionValueList().getIterator();
386 ConditionValue *value;
387 FieldInfo *fInfo = new FieldInfo();
388 int paramPos =1;
389 DbRetVal rv = OK;
390 while (iter.hasElement())
392 value = (ConditionValue*) iter.nextElement();
393 if (NULL == value)
395 delete fInfo;
396 printError(ErrSysFatal, "Should never happen.");
397 return ErrSysFatal;
399 rv = table->getFieldInfo(value->fName, fInfo);
400 if (ErrNotFound == rv)
402 delete fInfo;
403 printError(ErrSyntaxError, "Field %s does not exist in table",
404 value->fName);
405 return ErrSyntaxError;
407 value->type = fInfo->type;
408 value->length = fInfo->length;
409 value->value = AllDataType::alloc(fInfo->type, fInfo->length);
410 //table->bindFld(name->fldName, value->value);
411 if (value->parsedString == NULL)
413 delete fInfo;
414 printError(ErrSyntaxError, "Condition value should not be NULL");
415 return ErrSyntaxError;
417 if (value->parsedString[0] == '?')
419 value->paramNo = paramPos++;
421 if (!value->paramNo)
422 AllDataType::strToValue(value->value, value->parsedString, fInfo->type);
424 delete fInfo;
425 totalParams = paramPos -1;
426 if (0 == totalParams) return OK;
427 params = (void**) malloc ( totalParams * sizeof(FieldValue*));
428 paramValues = (char**) malloc( totalParams * sizeof(char*));
429 memset(params, 0, totalParams * sizeof(FieldValue*));
430 memset(paramValues, 0, totalParams * sizeof(char*));
431 iter.reset();
432 while(iter.hasElement())
434 value = (ConditionValue*) iter.nextElement();
435 if (value == NULL)
437 free(params); params = NULL;
438 free(paramValues); paramValues = NULL;
439 printError(ErrSysFatal, "Should never happen. value NULL after iteration");
440 return ErrSysFatal;
442 params[value->paramNo -1 ] = value;
444 return OK;
447 void* SelStatement::fetch()
449 void *tuple = table->fetch();
450 if (NULL == tuple) return NULL;
451 //copy values to binded buffer
452 FieldValue *value;
453 for (int i = 0; i < totalFields; i++)
455 value = bindFields[i];
456 if (bindFieldValues[i] == NULL)
458 printError(ErrBadCall, "Fields are not binded properly. Should never happen");
459 return NULL;
461 AllDataType::copyVal(bindFieldValues[i], value->value, value->type, value->length);
463 return tuple;
466 DbRetVal SelStatement::close()
468 return table->close();
471 void* SelStatement::fetchAndPrint()
473 void *tuple = table->fetch();
474 if (NULL == tuple) return NULL;
475 FieldValue *value;
476 bool nullValueSet;
477 for (int i = 0; i < totalFields; i++)
479 value = bindFields[i];
480 nullValueSet = table->isFldNull(i+1);
481 if (nullValueSet)
482 printf("NULL\t");
483 else
484 AllDataType::printVal(value->value, value->type, value->length);
486 return tuple;
489 void* SelStatement::next()
491 return( table->fetch() );
494 void* SelStatement::getFieldValuePtr( int pos )
496 FieldValue *v = bindFields[pos];
497 return ( (void*) v->value );
500 int SelStatement::noOfProjFields()
502 return totalFields;
505 DbRetVal SelStatement::getProjFldInfo (int projpos, FieldInfo *&fInfo)
507 //TODO::if not yet prepared return error
508 //TODO::check the upper limit for projpos
509 ListIterator iter = parsedData->getFieldNameList().getIterator();
510 FieldName *name = NULL;
511 DbRetVal rv = OK;
512 int position =0;
513 while (iter.hasElement())
515 name = (FieldName*)iter.nextElement();
516 if (NULL == name)
518 printError(ErrSysFatal, "Should never happen. Field Name list has NULL");
519 return ErrSysFatal;
521 if (position == projpos) break;
522 position++;
525 rv = table->getFieldInfo(name->fldName, fInfo);