nodejs-db-informix  master
nodejs bindings for Informix
 All Classes Functions Pages
result.cxx
1 /*
2  * Result set
3  */
4 
5 #include "result.h"
6 
7 /*
8 Col: 0, name: boolean_val, type: boolean
9 Col: 1, name: char_val, type: char
10 Col: 2, name: character_val, type: char
11 Col: 3, name: date_val, type: date
12 Col: 4, name: datetime_val, type: datetime
13 Col: 5, name: dec_val, type: decimal
14 Col: 6, name: decimal_val, type: decimal
15 Col: 7, name: double_val, type: float
16 Col: 8, name: float_val, type: float
17 Col: 9, name: int_val, type: integer
18 Col: 10, name: int8_val, type: int8
19 Col: 11, name: integer_val, type: integer
20 Col: 12, name: interval_ds_val, type: interval
21 Col: 13, name: interval_ym_val, type: interval
22 Col: 14, name: lvarchar_val, type: lvarchar
23 Col: 15, name: numeric_val, type: decimal
24 Col: 16, name: money_val, type: money
25 Col: 17, name: real_val, type: smallfloat
26 Col: 18, name: serial_val, type: serial
27 Col: 19, name: smallfloat_val, type: smallfloat
28 Col: 20, name: smallint_val, type: smallint
29 Col: 21, name: text_val, type: text
30 Col: 22, name: byte_val, type: byte
31 Col: 23, name: varchar_val, type: varchar
32 Col: 24, name: large_object_val, type: blob
33 Col: 25, name: large_text_val, type: clob
34 Col: 26, name: cnstr_val, type: cnstr_type
35 Col: 27, name: setof_base_val, type: SET(integer not null)
36 Col: 28, name: setof_cnstr, type: SET(cnstr_type not null)
37 Col: 29, name: boolean_null, type: boolean
38 Col: 30, name: char_null, type: char
39 Col: 31, name: character_null, type: char
40 Col: 32, name: date_null, type: date
41 Col: 33, name: datetime_null, type: datetime
42 Col: 34, name: dec_null, type: decimal
43 Col: 35, name: decimal_null, type: decimal
44 Col: 36, name: double_null, type: float
45 Col: 37, name: float_null, type: float
46 Col: 38, name: int_null, type: integer
47 Col: 39, name: int8_null, type: int8
48 Col: 40, name: integer_null, type: integer
49 Col: 41, name: interval_ds_null, type: interval
50 Col: 42, name: interval_ym_null, type: interval
51 Col: 43, name: lvarchar_null, type: lvarchar
52 Col: 44, name: numeric_null, type: decimal
53 Col: 45, name: money_null, type: money
54 Col: 46, name: real_null, type: smallfloat
55 Col: 47, name: smallfloat_null, type: smallfloat
56 Col: 48, name: smallint_null, type: smallint
57 Col: 49, name: text_null, type: text
58 Col: 50, name: varchar_null, type: varchar
59 */
60 
61 /*
62  * \n column name
63  * \ti ITTypeInfo of the column
64  */
65 nodejs_db_informix::Result::Column::Column(
66  const std::string n,
67  const ITTypeInfo *ti) throw (nodejs_db::Exception&)
68 {
69  if (ti == NULL) {
70  throw nodejs_db::Exception("Null column type");
71  }
72 
73  this->name = n;
74  // assume its not binary for now
75  this->binary = 0;
76  this->typeName = std::string(ti->Name().Data());
77 
78  if (this->typeName == "blob") {
79  this->binary = 0;
80  this->type = BLOB;
81  }
82  else
83  if (this->typeName == "boolean") {
84  this->binary = 0;
85  this->type = BOOL;
86  }
87  else
88  if (this->typeName == "byte") {
89  this->binary = 0;
90  this->type = INT;
91  }
92  else
93  if (this->typeName == "char") {
94  this->binary = 0;
95  this->type = STRING;
96  }
97  else
98  if (this->typeName == "clob") {
99  this->binary = 0;
100  this->type = TEXT;
101  }
102  else
103  if (this->typeName == "date") {
104  this->binary = 0;
105  this->type = DATE;
106  }
107  else
108  if (this->typeName == "datetime") {
109  this->binary = 0;
110  this->type = DATETIME;
111  }
112  else
113  if (this->typeName == "decimal") {
114  this->binary = 0;
115  this->type = NUMBER;
116  }
117  else
118  if (this->typeName == "float") {
119  this->binary = 0;
120  this->type = NUMBER;
121  }
122  else
123  if (this->typeName == "int8") {
124  this->binary = 0;
125  this->type = INT;
126  }
127  else
128  if (this->typeName == "integer") {
129  this->binary = 0;
130  this->type = INT;
131  }
132  else
133  if (this->typeName == "interval") {
134  this->binary = 0;
135  this->type = INTERVAL;
136  }
137  else
138  if (this->typeName == "lvarchar") {
139  this->binary = 0;
140  this->type = STRING;
141  }
142  else
143  if (this->typeName == "money") {
144  this->binary = 0;
145  this->type = MONEY;
146  }
147  else
148  if (this->typeName == "serial") {
149  this->binary = 0;
150  this->type = INT;
151  }
152  else
153  if (this->typeName == "smallfloat") {
154  this->binary = 0;
155  this->type = NUMBER;
156  }
157  else
158  if (this->typeName == "smallint") {
159  this->binary = 0;
160  this->type = NUMBER;
161  }
162  else
163  if (this->typeName == "text") {
164  this->binary = 0;
165  this->type = TEXT;
166  }
167  else
168  if (this->typeName == "varchar") {
169  this->binary = 0;
170  this->type = STRING;
171  }
172  else {
173  // sub-columns
174  if (ti->IsRow()) {
175  this->typeName = "row";
176  this->type = ROW;
177  this->binary = 0;
178  }
179  else
180  if (ti->IsCollection()) {
181  this->typeName = "collection";
182  this->type = COLLECTION;
183  this->binary = 0;
184  }
185  else
186  if (ti->IsConstructed()) {
187  this->typeName = "constructed";
188  this->type = CONSTRUCTED;
189  this->binary = 0;
190  }
191  }
192 }
193 
194 
195 
196 nodejs_db_informix::Result::Column::~Column() {
197 }
198 
199 
200 
201 bool nodejs_db_informix::Result::Column::isBinary() const {
202  return this->binary;
203 }
204 
205 
206 
207 std::string nodejs_db_informix::Result::Column::getName() const {
208  return this->name;
209 }
210 
211 
212 
213 nodejs_db::Result::Column::type_t
214 nodejs_db_informix::Result::Column::getType() const {
215  return this->type;
216 }
217 
218 
219 
220 std::string
221 nodejs_db_informix::Result::Column::getTypeName() const {
222  return this->typeName;
223 }
224 
225 
226 
227 nodejs_db_informix::Result::Result(ITBool b, long re)
228 throw (nodejs_db::Exception&) :
229  columns(),
230  columnNames(),
231  totalColumns(0),
232  rowNumber(0),
233  rowsAffected(re),
234  empty(true),
235  previousRow(NULL),
236  nextRow(NULL)
237 {
238  empty = bool(b);
239 }
240 
241 
242 
243 /**
244  *
245  * \rs Record set of type ITSet*
246  * \cti Column Type Information of type ITTypeInfo
247  */
248 nodejs_db_informix::Result::Result(ITSet* rs, const ITTypeInfo *cti, long re) throw(nodejs_db::Exception&) :
249  columns(),
250  columnNames(),
251  totalColumns(0),
252  rowNumber(0),
253  rowsAffected(re),
254  empty(true),
255  previousRow(NULL),
256  nextRow(NULL)
257 {
258  // check the column info and populate column data-structure
259  if (rs == NULL || cti == NULL) {
260  throw nodejs_db::Exception("Could not retreive column information");
261  }
262 
263  columns.clear();
264  columnNames.clear();
265 
266  this->resultSet = rs;
267  this->totalColumns = static_cast<uint16_t>(cti->ColumnCount());
268 
269  if (this->totalColumns > 0) {
270  // populate the Columns
271  for (uint16_t c = 0; c < this->totalColumns; ++c) {
272  std::string n = cti->ColumnName(c).Data();
273 
274  Column *col = new Column(n, cti->ColumnType(c));
275 
276  this->columns.push_back(col);
277  this->columnNames.push_back(n);
278  }
279 
280  this->empty = false;
281  }
282 
283  this->nextRow = this->row();
284 }
285 
286 
287 
288 /**
289  *
290  *
291  */
292 nodejs_db_informix::Result::Result(ITSet* rs, long re) throw(nodejs_db::Exception&) :
293  columns(),
294  columnNames(),
295  totalColumns(0),
296  rowNumber(0),
297  rowsAffected(re),
298  empty(true),
299  previousRow(NULL),
300  nextRow(NULL)
301 {
302  if (rs == NULL) {
303  throw nodejs_db::Exception("Null ResultSet");
304  }
305 
306  columns.clear();
307  columnNames.clear();
308 
309  // construct the column name, values from first row
310 
311  this->empty = false;
312  this->resultSet = rs;
313  this->nextRow = this->row();
314 }
315 
316 
317 
318 nodejs_db_informix::Result::~Result() {
319  this->free();
320 }
321 
322 
323 
324 void nodejs_db_informix::Result::free() throw() {
325  this->release();
326 }
327 
328 
329 
330 void nodejs_db_informix::Result::release() throw() {
331  this->columns.clear();
332  this->columnNames.clear();
333 }
334 
335 
336 
337 bool nodejs_db_informix::Result::hasNext() const throw() {
338  return (this->nextRow != NULL);
339 }
340 
341 
342 
343 std::vector<std::string>*
344 nodejs_db_informix::Result::next() throw(nodejs_db::Exception&) {
345  if (this->nextRow == NULL) {
346  return NULL;
347  }
348 
349  this->rowNumber++;
350  this->previousRow = this->nextRow;
351  this->nextRow = this->row();
352 
353  return this->previousRow;
354 }
355 
356 
357 
358 unsigned long* nodejs_db_informix::Result::columnLengths() throw(nodejs_db::Exception&) {
359  return this->colLengths;
360 }
361 
362 
363 
364 std::vector<std::string>*
365 nodejs_db_informix::Result::row() throw(nodejs_db::Exception&) {
366  std::vector<std::string> *row = new std::vector<std::string>();
367 
368  ITValue *v = this->resultSet->Fetch();
369  if (v == NULL) {
370  // throw nodejs_db::Exception("Cannot fetch ITValue for next row");
371  return NULL;
372  }
373 
374  ITRow *r; //ITRow is an abstract class
375  if (v->QueryInterface(ITRowIID, (void**) &r) == IT_QUERYINTERFACE_FAILED) {
376  throw nodejs_db::Exception("Couldn't fetch ITRow for next row");
377  } else {
378  long nc = r->NumColumns(); // number of columns
379  // TODO: amitkr@ don't we need to free this up at some point?
380  this->colLengths = new unsigned long[nc];
381  for (long i = 0; i < nc; ++i) {
382  ITValue *cv = r->Column(i); // column value
383  if (cv->IsNull()) {
384  // append null
385  row->push_back(std::string("null"));
386  this->colLengths[i] = std::string("null").length();
387  } else {
388  row->push_back(std::string(cv->Printable().Data()));
389  this->colLengths[i] = cv->Printable().Length();
390  }
391  }
392  }
393 
394  return row;
395 }
396 
397 
398 
399 uint64_t nodejs_db_informix::Result::index() const throw(std::out_of_range&) {
400  if (this->rowNumber == 0) {
401  throw std::out_of_range("Not standing on a row");
402  }
403  return (this->rowNumber - 1);
404 }
405 
406 
407 
409 nodejs_db_informix::Result::column(uint16_t i) const throw(std::out_of_range&) {
410  if (i >= this->totalColumns) {
411  throw std::out_of_range("Wrong column index");
412  }
413 
414 #ifdef DEV
415  std::cout << *(this->columns[i]) << std::endl;
416 #endif
417 
418  return this->columns[i];
419 }
420 
421 
422 
423 uint64_t nodejs_db_informix::Result::insertId() const throw() {
424  return 0;
425 }
426 
427 
428 
429 uint64_t nodejs_db_informix::Result::affectedCount() const throw() {
430  return rowsAffected;
431 }
432 
433 
434 
435 uint16_t nodejs_db_informix::Result::warningCount() const throw() {
436  return 0;
437 }
438 
439 
440 
441 uint16_t nodejs_db_informix::Result::columnCount() const throw() {
442  return this->totalColumns;
443 }
444 
445 
446 
447 uint64_t nodejs_db_informix::Result::count() const throw(nodejs_db::Exception&) {
448  if (!this->isBuffered()) {
449  throw nodejs_db::Exception("Result is not buffered");
450  }
451  return 0;
452 }
453 
454 
455 
456 bool nodejs_db_informix::Result::isBuffered() const throw() {
457  return true;
458 }
459 
460 
461 
462 bool nodejs_db_informix::Result::isEmpty() const throw() {
463  return this->empty;
464 }