~ubuntu-branches/ubuntu/quantal/mysql-workbench/quantal

« back to all changes in this revision

Viewing changes to ext/cppconn/driver/mysql_resultset.cpp

  • Committer: Package Import Robot
  • Author(s): Dmitry Smirnov
  • Date: 2012-03-01 21:57:30 UTC
  • Revision ID: package-import@ubuntu.com-20120301215730-o7y8av8y38n162ro
Tags: upstream-5.2.38+dfsg
ImportĀ upstreamĀ versionĀ 5.2.38+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
 
3
 
 
4
The MySQL Connector/C++ is licensed under the terms of the GPLv2
 
5
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
 
6
MySQL Connectors. There are special exceptions to the terms and
 
7
conditions of the GPLv2 as it is applied to this software, see the
 
8
FLOSS License Exception
 
9
<http://www.mysql.com/about/legal/licensing/foss-exception.html>.
 
10
 
 
11
This program is free software; you can redistribute it and/or modify
 
12
it under the terms of the GNU General Public License as published
 
13
by the Free Software Foundation; version 2 of the License.
 
14
 
 
15
This program is distributed in the hope that it will be useful, but
 
16
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 
17
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
 
18
for more details.
 
19
 
 
20
You should have received a copy of the GNU General Public License along
 
21
with this program; if not, write to the Free Software Foundation, Inc.,
 
22
51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
 
23
*/
 
24
 
 
25
 
 
26
 
 
27
#include <string.h>
 
28
#include <stdlib.h>
 
29
#include <stdio.h>
 
30
#include <sstream>
 
31
#include <boost/scoped_array.hpp>
 
32
 
 
33
#include <cppconn/exception.h>
 
34
#include <cppconn/resultset.h>
 
35
#include <cppconn/warning.h>
 
36
#include "mysql_util.h"
 
37
#include "mysql_resultset.h"
 
38
#include "mysql_resultset_metadata.h"
 
39
#include "mysql_statement.h"
 
40
 
 
41
#include "nativeapi/native_resultset_wrapper.h"
 
42
 
 
43
#include "mysql_debug.h"
 
44
 
 
45
namespace sql
 
46
{
 
47
namespace mysql
 
48
{
 
49
 
 
50
 
 
51
 
 
52
/* {{{ MySQL_ResultSet::MySQL_ResultSet() -I- */
 
53
MySQL_ResultSet::MySQL_ResultSet(boost::shared_ptr< NativeAPI::NativeResultsetWrapper > res, sql::ResultSet::enum_type rset_type,
 
54
                        MySQL_Statement * par, boost::shared_ptr< MySQL_DebugLogger > & l
 
55
                )
 
56
        : row(NULL), result(res), row_position(0), was_null(false), parent(par),
 
57
          logger(l), resultset_type(rset_type)
 
58
{
 
59
        CPP_ENTER("MySQL_ResultSet::MySQL_ResultSet");
 
60
        num_rows = result->num_rows();
 
61
 
 
62
        num_fields = result->num_fields();
 
63
        for (unsigned int i = 0; i < num_fields; ++i) {
 
64
#if A0
 
65
                std::cout << "Elements=" << field_name_to_index_map.size() << "\n";
 
66
#endif
 
67
                boost::scoped_array< char > upstring(sql::mysql::util::utf8_strup(getFieldMeta(i + 1)->name, 0));
 
68
                field_name_to_index_map[upstring.get()] = i;
 
69
        }
 
70
#if A0
 
71
        std::cout << "Elements=" << field_name_to_index_map.size() << "\n";
 
72
#endif
 
73
        rs_meta.reset(new MySQL_ResultSetMetaData(result, logger));
 
74
}
 
75
/* }}} */
 
76
 
 
77
 
 
78
/* {{{ MySQL_ResultSet::~MySQL_ResultSet() -I- */
 
79
MySQL_ResultSet::~MySQL_ResultSet()
 
80
{
 
81
        CPP_ENTER("MySQL_ResultSet::~MySQL_ResultSet");
 
82
}
 
83
/* }}} */
 
84
 
 
85
 
 
86
/* {{{ MySQL_ResultSet::absolute() -I- */
 
87
bool
 
88
MySQL_ResultSet::absolute(const int new_pos)
 
89
{
 
90
        CPP_ENTER("MySQL_ResultSet::absolute");
 
91
        checkValid();
 
92
        checkScrollable();
 
93
        if (new_pos > 0) {
 
94
                if (new_pos > (int) num_rows) {
 
95
                        row_position = num_rows + 1; /* after last row */
 
96
                } else {
 
97
                        row_position = (my_ulonglong) new_pos; /* the cast is inspected and is valid */
 
98
                        seek();
 
99
                        return true;
 
100
                }
 
101
        } else if (new_pos < 0) {
 
102
                if ((-new_pos) > (int) num_rows) {
 
103
                        row_position = 0; /* before first new_pos */
 
104
                } else {
 
105
                        row_position = num_rows - (-new_pos)  + 1;
 
106
                        seek();
 
107
                        return true;
 
108
                }
 
109
        } else {
 
110
                /* According to the JDBC book, absolute(0) means before the result set */
 
111
                row_position = 0;
 
112
                /* no seek() here, as we are not on data*/
 
113
                result->data_seek(0);
 
114
        }
 
115
        return (row_position > 0 && row_position < (num_rows + 1));
 
116
}
 
117
/* }}} */
 
118
 
 
119
 
 
120
/* {{{ MySQL_ResultSet::afterLast() -I- */
 
121
void
 
122
MySQL_ResultSet::afterLast()
 
123
{
 
124
        CPP_ENTER("MySQL_ResultSet::afterLast");
 
125
        checkValid();
 
126
        row_position = num_rows + 1;
 
127
}
 
128
/* }}} */
 
129
 
 
130
 
 
131
/* {{{ MySQL_ResultSet::beforeFirst() -I- */
 
132
void
 
133
MySQL_ResultSet::beforeFirst()
 
134
{
 
135
        CPP_ENTER("MySQL_ResultSet::beforeFirst");
 
136
        checkValid();
 
137
        checkScrollable();
 
138
        result->data_seek(0);
 
139
        row_position = 0;
 
140
}
 
141
/* }}} */
 
142
 
 
143
 
 
144
/* {{{ MySQL_ResultSet::cancelRowUpdates() -U- */
 
145
void
 
146
MySQL_ResultSet::cancelRowUpdates()
 
147
{
 
148
        CPP_ENTER("MySQL_ResultSet::cancelRowUpdates");
 
149
        checkValid();
 
150
        throw sql::MethodNotImplementedException("MySQL_ResultSet::cancelRowUpdates()");
 
151
}
 
152
/* }}} */
 
153
 
 
154
 
 
155
/* {{{ MySQL_ResultSet::checkScrollable() -I- */
 
156
void
 
157
MySQL_ResultSet::checkScrollable() const
 
158
{
 
159
        CPP_ENTER("MySQL_ResultSet::checkScrollable");
 
160
        CPP_INFO_FMT("this=%p", this);
 
161
        if (resultset_type == sql::ResultSet::TYPE_FORWARD_ONLY) {
 
162
                throw sql::NonScrollableException("Nonscrollable result set");
 
163
        }
 
164
}
 
165
/* }}} */
 
166
 
 
167
 
 
168
/* {{{ MySQL_ResultSet::isScrollable() -I- */
 
169
bool
 
170
MySQL_ResultSet::isScrollable() const
 
171
{
 
172
//      CPP_ENTER("MySQL_ResultSet::isScrollable");
 
173
//      CPP_INFO_FMT("this=%p", this);
 
174
        return (resultset_type != sql::ResultSet::TYPE_FORWARD_ONLY);
 
175
}
 
176
/* }}} */
 
177
 
 
178
 
 
179
/* {{{ MySQL_ResultSet::checkValid() -I- */
 
180
void
 
181
MySQL_ResultSet::checkValid() const
 
182
{
 
183
        CPP_ENTER("MySQL_ResultSet::checkValid");
 
184
        CPP_INFO_FMT("this=%p", this);
 
185
        if (isClosed()) {
 
186
                throw sql::InvalidInstanceException("ResultSet has been closed");
 
187
        }
 
188
}
 
189
/* }}} */
 
190
 
 
191
 
 
192
/* {{{ MySQL_ResultSet::clearWarnings() -U- */
 
193
void
 
194
MySQL_ResultSet::clearWarnings()
 
195
{
 
196
        CPP_ENTER("MySQL_ResultSet::clearWarnings");
 
197
        checkValid();
 
198
        throw sql::MethodNotImplementedException("MySQL_ResultSet::clearWarnings()");
 
199
}
 
200
/* }}} */
 
201
 
 
202
 
 
203
/* {{{ MySQL_ResultSet::close() -I- */
 
204
void
 
205
MySQL_ResultSet::close()
 
206
{
 
207
        CPP_ENTER("MySQL_ResultSet::close");
 
208
        checkValid();
 
209
        result.reset();
 
210
//      result->dispose();
 
211
}
 
212
/* }}} */
 
213
 
 
214
 
 
215
/* {{{ MySQL_ResultSet::findColumn() -I- */
 
216
uint32_t
 
217
MySQL_ResultSet::findColumn(const sql::SQLString& columnLabel) const
 
218
{
 
219
        CPP_ENTER("MySQL_ResultSet::findColumn");
 
220
        checkValid();
 
221
        boost::scoped_array< char > upstring(sql::mysql::util::utf8_strup(columnLabel.c_str(), 0));
 
222
#if A0
 
223
        std::cout << "Elements=" << field_name_to_index_map.size() << "\n";
 
224
        FieldNameIndexMap::const_iterator tmp_iter = field_name_to_index_map.begin();
 
225
        FieldNameIndexMap::const_iterator tmp_iter_end = field_name_to_index_map.end();
 
226
        for (;tmp_iter != tmp_iter_end; tmp_iter++) {
 
227
                std::cout << "[[" << tmp_iter->first << "]] second=[[" << tmp_iter->second << "]]\n";
 
228
        }
 
229
        sql::SQLString tmp(upstring.get());
 
230
        std::cout << "[" << tmp << "]\n";
 
231
#endif
 
232
 
 
233
        FieldNameIndexMap::const_iterator iter = field_name_to_index_map.find(sql::SQLString(upstring.get()));
 
234
        if (iter == field_name_to_index_map.end()) {
 
235
                return 0;
 
236
        }
 
237
        /* findColumn returns 1-based indexes */
 
238
        return iter->second + 1;
 
239
}
 
240
/* }}} */
 
241
 
 
242
 
 
243
/* {{{ MySQL_ResultSet::first() -I- */
 
244
bool
 
245
MySQL_ResultSet::first()
 
246
{
 
247
        CPP_ENTER("MySQL_ResultSet::first");
 
248
        checkValid();
 
249
        checkScrollable();
 
250
        if (num_rows) {
 
251
                row_position = 1;
 
252
                seek();
 
253
        }
 
254
        return num_rows != 0;
 
255
}
 
256
/* }}} */
 
257
 
 
258
 
 
259
/* {{{ MySQL_ResultSet::getBlob() -I- */
 
260
std::istream *
 
261
MySQL_ResultSet::getBlob(const uint32_t columnIndex) const
 
262
{
 
263
        CPP_ENTER("MySQL_ResultSet::getBlob(int)");
 
264
        /* isBeforeFirst checks for validity */
 
265
        if (isBeforeFirstOrAfterLast()) {
 
266
                throw sql::InvalidArgumentException("MySQL_ResultSet::getBoolean: can't fetch because not on result set");
 
267
        }
 
268
        return new std::istringstream(getString(columnIndex));
 
269
}
 
270
/* }}} */
 
271
 
 
272
 
 
273
/* {{{ MySQL_ResultSet::getBlob() -I- */
 
274
std::istream *
 
275
MySQL_ResultSet::getBlob(const sql::SQLString& columnLabel) const
 
276
{
 
277
        CPP_ENTER("MySQL_ResultSet::getBlob(string)");
 
278
        /* isBeforeFirst checks for validity */
 
279
        if (isBeforeFirstOrAfterLast()) {
 
280
                throw sql::InvalidArgumentException("MySQL_ResultSet::getBoolean: can't fetch because not on result set");
 
281
        }
 
282
        return new std::istringstream(getString(columnLabel));
 
283
}
 
284
/* }}} */
 
285
 
 
286
 
 
287
/* {{{ MySQL_ResultSet::getBoolean() -I- */
 
288
bool
 
289
MySQL_ResultSet::getBoolean(const uint32_t columnIndex) const
 
290
{
 
291
        CPP_ENTER("MySQL_ResultSet::getBoolean(int)");
 
292
        /* isBeforeFirst checks for validity */
 
293
        if (isBeforeFirstOrAfterLast()) {
 
294
                throw sql::InvalidArgumentException("MySQL_ResultSet::getBoolean: can't fetch because not on result set");
 
295
        }
 
296
        return getInt(columnIndex)? true:false;
 
297
}
 
298
/* }}} */
 
299
 
 
300
 
 
301
/* {{{ MySQL_ResultSet::getBoolean() -I- */
 
302
bool
 
303
MySQL_ResultSet::getBoolean(const sql::SQLString& columnLabel) const
 
304
{
 
305
        CPP_ENTER("MySQL_ResultSet::getBoolean(string)");
 
306
        /* isBeforeFirst checks for validity */
 
307
        if (isBeforeFirstOrAfterLast()) {
 
308
                throw sql::InvalidArgumentException("MySQL_ResultSet::getBoolean: can't fetch because not on result set");
 
309
        }
 
310
        return getInt(columnLabel)? true:false;
 
311
}
 
312
/* }}} */
 
313
 
 
314
 
 
315
/* {{{ MySQL_ResultSet::getConcurrency() -U- */
 
316
int
 
317
MySQL_ResultSet::getConcurrency()
 
318
{
 
319
        CPP_ENTER("MySQL_ResultSet::getConcurrency");
 
320
        checkValid();
 
321
        throw sql::MethodNotImplementedException("MySQL_ResultSet::getConcurrency()");
 
322
        return 0; // fool compilers
 
323
}
 
324
/* }}} */
 
325
 
 
326
 
 
327
/* {{{ MySQL_ResultSet::getCursorName() -U- */
 
328
SQLString
 
329
MySQL_ResultSet::getCursorName()
 
330
{
 
331
        CPP_ENTER("MySQL_ResultSet::getCursorName");
 
332
        checkValid();
 
333
        throw sql::MethodNotImplementedException("MySQL_ResultSet::getCursorName()");
 
334
        return ""; // fool compilers
 
335
}
 
336
/* }}} */
 
337
 
 
338
 
 
339
/* {{{ MySQL_ResultSet::getDouble() -I- */
 
340
long double
 
341
MySQL_ResultSet::getDouble(const uint32_t columnIndex) const
 
342
{
 
343
        CPP_ENTER("MySQL_ResultSet::getDouble(int)");
 
344
 
 
345
        /* isBeforeFirst checks for validity */
 
346
        if (isBeforeFirstOrAfterLast()) {
 
347
                throw sql::InvalidArgumentException("MySQL_ResultSet::getDouble: can't fetch because not on result set");
 
348
        }
 
349
 
 
350
        if (columnIndex == 0 || columnIndex > num_fields) {
 
351
                throw sql::InvalidArgumentException("MySQL_ResultSet::getDouble: invalid value of 'columnIndex'");
 
352
        }
 
353
        if (row[columnIndex - 1] == NULL) {
 
354
                was_null = true;
 
355
                return 0.0;
 
356
        }
 
357
        was_null = false;
 
358
        if (getFieldMeta(columnIndex)->type == MYSQL_TYPE_BIT) {
 
359
                return getInt64(columnIndex);
 
360
        }
 
361
        return sql::mysql::util::strtold(row[columnIndex - 1], NULL);
 
362
}
 
363
/* }}} */
 
364
 
 
365
 
 
366
/* {{{ MySQL_ResultSet::getDouble() -I- */
 
367
long double
 
368
MySQL_ResultSet::getDouble(const sql::SQLString& columnLabel) const
 
369
{
 
370
        CPP_ENTER("MySQL_ResultSet::getDouble(string)");
 
371
        return getDouble(findColumn(columnLabel));
 
372
}
 
373
/* }}} */
 
374
 
 
375
 
 
376
/* {{{ MySQL_ResultSet::getFetchDirection() -U- */
 
377
int
 
378
MySQL_ResultSet::getFetchDirection()
 
379
{
 
380
        CPP_ENTER("MySQL_ResultSet::getFetchDirection");
 
381
        checkValid();
 
382
        throw sql::MethodNotImplementedException("MySQL_ResultSet::getFetchDirection()");
 
383
        return 0; // fool compilers
 
384
}
 
385
/* }}} */
 
386
 
 
387
 
 
388
/* {{{ MySQL_ResultSet::getFetchSize() -U- */
 
389
size_t
 
390
MySQL_ResultSet::getFetchSize()
 
391
{
 
392
        CPP_ENTER("MySQL_ResultSet::getFetchSize");
 
393
        checkValid();
 
394
        throw sql::MethodNotImplementedException("MySQL_ResultSet::getFetchSize()");
 
395
        return 0; // fool compilers
 
396
}
 
397
/* }}} */
 
398
 
 
399
 
 
400
/* {{{ MySQL_ResultSet::getFieldMeta() -U- */
 
401
MYSQL_FIELD * MySQL_ResultSet::getFieldMeta(unsigned int columnIndex) const
 
402
{
 
403
        return result->fetch_field_direct(columnIndex - 1);
 
404
}
 
405
/* }}} */
 
406
 
 
407
 
 
408
/* {{{ MySQL_ResultSet::getHoldability() -U- */
 
409
int
 
410
MySQL_ResultSet::getHoldability()
 
411
{
 
412
        CPP_ENTER("MySQL_ResultSet::getHoldability");
 
413
        checkValid();
 
414
        throw sql::MethodNotImplementedException("MySQL_ResultSet::getHoldability()");
 
415
        return 0; // fool compilers
 
416
}
 
417
/* }}} */
 
418
 
 
419
 
 
420
/* {{{ MySQL_ResultSet::getInt() -I- */
 
421
int32_t
 
422
MySQL_ResultSet::getInt(const uint32_t columnIndex) const
 
423
{
 
424
        CPP_ENTER("MySQL_ResultSet::getInt(int)");
 
425
        /* isBeforeFirst checks for validity */
 
426
        if (isBeforeFirstOrAfterLast()) {
 
427
                throw sql::InvalidArgumentException("MySQL_ResultSet::getInt: can't fetch because not on result set");
 
428
        }
 
429
        if (columnIndex == 0 || columnIndex > num_fields) {
 
430
                throw sql::InvalidArgumentException("MySQL_ResultSet::getInt: invalid value of 'columnIndex'");
 
431
        }
 
432
        CPP_INFO_FMT("%ssigned", (getFieldMeta(columnIndex)->flags & UNSIGNED_FLAG)? "un":"");
 
433
        if (getFieldMeta(columnIndex)->flags & UNSIGNED_FLAG) {
 
434
                return static_cast<uint32_t>(getInt64(columnIndex));
 
435
        }
 
436
        return static_cast<int32_t>(getInt64(columnIndex));
 
437
}
 
438
/* }}} */
 
439
 
 
440
 
 
441
/* {{{ MySQL_ResultSet::getInt() -I- */
 
442
int32_t
 
443
MySQL_ResultSet::getInt(const sql::SQLString& columnLabel) const
 
444
{
 
445
        CPP_ENTER("MySQL_ResultSet::getInt(string)");
 
446
        return getInt(findColumn(columnLabel));
 
447
}
 
448
/* }}} */
 
449
 
 
450
 
 
451
/* {{{ MySQL_ResultSet::getUInt() -I- */
 
452
uint32_t
 
453
MySQL_ResultSet::getUInt(const uint32_t columnIndex) const
 
454
{
 
455
        CPP_ENTER("MySQL_ResultSet::getUInt(int)");
 
456
        /* isBeforeFirst checks for validity */
 
457
        if (isBeforeFirstOrAfterLast()) {
 
458
                throw sql::InvalidArgumentException("MySQL_ResultSet::getUInt: can't fetch because not on result set");
 
459
        }
 
460
        if (columnIndex == 0 || columnIndex > num_fields) {
 
461
                throw sql::InvalidArgumentException("MySQL_ResultSet::getUInt: invalid value of 'columnIndex'");
 
462
        }
 
463
        CPP_INFO_FMT("%ssigned", (getFieldMeta(columnIndex)->flags & UNSIGNED_FLAG)? "un":"");
 
464
        return static_cast<uint32_t>(getUInt64(columnIndex));// & 0xffffffff;
 
465
}
 
466
/* }}} */
 
467
 
 
468
 
 
469
/* {{{ MySQL_ResultSet::getUInt() -I- */
 
470
uint32_t
 
471
MySQL_ResultSet::getUInt(const sql::SQLString& columnLabel) const
 
472
{
 
473
        CPP_ENTER("MySQL_ResultSet::getUInt(string)");
 
474
        return getUInt(findColumn(columnLabel));
 
475
}
 
476
/* }}} */
 
477
 
 
478
 
 
479
/* {{{ MySQL_ResultSet::getInt64() -I- */
 
480
int64_t
 
481
MySQL_ResultSet::getInt64(const uint32_t columnIndex) const
 
482
{
 
483
        CPP_ENTER("MySQL_ResultSet::getInt64(int)");
 
484
 
 
485
        /* isBeforeFirst checks for validity */
 
486
        if (isBeforeFirstOrAfterLast()) {
 
487
                throw sql::InvalidArgumentException("MySQL_ResultSet::getInt64: can't fetch because not on result set");
 
488
        }
 
489
 
 
490
        if (columnIndex == 0 || columnIndex > num_fields) {
 
491
                throw sql::InvalidArgumentException("MySQL_ResultSet::getInt64: invalid value of 'columnIndex'");
 
492
        }
 
493
 
 
494
        if (row[columnIndex - 1] == NULL) {
 
495
                was_null = true;
 
496
                return 0;
 
497
        }
 
498
        CPP_INFO_FMT("%ssigned", (getFieldMeta(columnIndex)->flags & UNSIGNED_FLAG)? "un":"");
 
499
        was_null = false;
 
500
        if (getFieldMeta(columnIndex)->type == MYSQL_TYPE_BIT) {
 
501
                uint64_t uval = 0;
 
502
                std::div_t length= std::div(getFieldMeta(columnIndex)->length, 8);
 
503
                if (length.rem) {
 
504
                        ++length.quot;
 
505
                }
 
506
 
 
507
                switch (length.quot) {
 
508
                        case 8:uval = (uint64_t) bit_uint8korr(row[columnIndex - 1]);break;
 
509
                        case 7:uval = (uint64_t) bit_uint7korr(row[columnIndex - 1]);break;
 
510
                        case 6:uval = (uint64_t) bit_uint6korr(row[columnIndex - 1]);break;
 
511
                        case 5:uval = (uint64_t) bit_uint5korr(row[columnIndex - 1]);break;
 
512
                        case 4:uval = (uint64_t) bit_uint4korr(row[columnIndex - 1]);break;
 
513
                        case 3:uval = (uint64_t) bit_uint3korr(row[columnIndex - 1]);break;
 
514
                        case 2:uval = (uint64_t) bit_uint2korr(row[columnIndex - 1]);break;
 
515
                        case 1:uval = (uint64_t) bit_uint1korr(row[columnIndex - 1]);break;
 
516
                }
 
517
                return uval;
 
518
        }
 
519
 
 
520
        if (getFieldMeta(columnIndex)->flags & UNSIGNED_FLAG) {
 
521
                return strtoull(row[columnIndex - 1], NULL, 10);
 
522
        }
 
523
        return strtoll(row[columnIndex - 1], NULL, 10);
 
524
}
 
525
/* }}} */
 
526
 
 
527
 
 
528
/* {{{ MySQL_ResultSet::getInt64() -I- */
 
529
int64_t
 
530
MySQL_ResultSet::getInt64(const sql::SQLString& columnLabel) const
 
531
{
 
532
        CPP_ENTER("MySQL_ResultSet::getInt64(string)");
 
533
        return getInt64(findColumn(columnLabel));
 
534
}
 
535
/* }}} */
 
536
 
 
537
 
 
538
/* {{{ MySQL_ResultSet::getUInt64() -I- */
 
539
uint64_t
 
540
MySQL_ResultSet::getUInt64(const uint32_t columnIndex) const
 
541
{
 
542
        CPP_ENTER("MySQL_ResultSet::getUInt64(int)");
 
543
 
 
544
        /* isBeforeFirst checks for validity */
 
545
        if (isBeforeFirstOrAfterLast()) {
 
546
                throw sql::InvalidArgumentException("MySQL_ResultSet::getUInt64: can't fetch because not on result set");
 
547
        }
 
548
 
 
549
        if (columnIndex == 0 || columnIndex > num_fields) {
 
550
                throw sql::InvalidArgumentException("MySQL_ResultSet::getUInt64: invalid value of 'columnIndex'");
 
551
        }
 
552
 
 
553
        if (row[columnIndex - 1] == NULL) {
 
554
                was_null = true;
 
555
                return 0;
 
556
        }
 
557
        CPP_INFO_FMT("%ssigned", (getFieldMeta(columnIndex)->flags & UNSIGNED_FLAG)? "un":"");
 
558
        was_null = false;
 
559
        if (getFieldMeta(columnIndex)->type == MYSQL_TYPE_BIT) {
 
560
                uint64_t uval = 0;
 
561
                std::div_t length= std::div(getFieldMeta(columnIndex)->length, 8);
 
562
                if (length.rem) {
 
563
                        ++length.quot;
 
564
                }
 
565
                switch (length.quot) {
 
566
                        case 8:uval = (uint64_t) bit_uint8korr(row[columnIndex - 1]);break;
 
567
                        case 7:uval = (uint64_t) bit_uint7korr(row[columnIndex - 1]);break;
 
568
                        case 6:uval = (uint64_t) bit_uint6korr(row[columnIndex - 1]);break;
 
569
                        case 5:uval = (uint64_t) bit_uint5korr(row[columnIndex - 1]);break;
 
570
                        case 4:uval = (uint64_t) bit_uint4korr(row[columnIndex - 1]);break;
 
571
                        case 3:uval = (uint64_t) bit_uint3korr(row[columnIndex - 1]);break;
 
572
                        case 2:uval = (uint64_t) bit_uint2korr(row[columnIndex - 1]);break;
 
573
                        case 1:uval = (uint64_t) bit_uint1korr(row[columnIndex - 1]);break;
 
574
                }
 
575
                return uval;
 
576
        }
 
577
 
 
578
        if (getFieldMeta(columnIndex)->flags & UNSIGNED_FLAG) {
 
579
                return strtoull(row[columnIndex - 1], NULL, 10);
 
580
        }
 
581
        return strtoll(row[columnIndex - 1], NULL, 10);
 
582
}
 
583
/* }}} */
 
584
 
 
585
 
 
586
/* {{{ MySQL_ResultSet::getUInt64() -I- */
 
587
uint64_t
 
588
MySQL_ResultSet::getUInt64(const sql::SQLString& columnLabel) const
 
589
{
 
590
        CPP_ENTER("MySQL_ResultSet::getUInt64(string)");
 
591
        return getUInt64(findColumn(columnLabel));
 
592
}
 
593
/* }}} */
 
594
 
 
595
 
 
596
/* {{{ MySQL_ResultSet::getMetaData() -I- */
 
597
sql::ResultSetMetaData *
 
598
MySQL_ResultSet::getMetaData() const
 
599
{
 
600
        CPP_ENTER("MySQL_ResultSet::getMetaData");
 
601
        checkValid();
 
602
        return rs_meta.get();
 
603
}
 
604
/* }}} */
 
605
 
 
606
 
 
607
/* {{{ MySQL_ResultSet::getRow() -I- */
 
608
size_t
 
609
MySQL_ResultSet::getRow() const
 
610
{
 
611
        CPP_ENTER("MySQL_ResultSet::getRow");
 
612
        checkValid();
 
613
        /* row_position is 0 based */
 
614
        return static_cast<size_t>(row_position);
 
615
}
 
616
/* }}} */
 
617
 
 
618
 
 
619
/* {{{ MySQL_ResultSet::getRowId() -U- */
 
620
sql::RowID *
 
621
MySQL_ResultSet::getRowId(uint32_t)
 
622
{
 
623
        CPP_ENTER("MySQL_ResultSet::getRowId");
 
624
        checkValid();
 
625
        throw sql::MethodNotImplementedException("MySQL_ResultSet::getRowId(uint32_t columnIndex)");
 
626
        return NULL; // fool compilers
 
627
}
 
628
/* }}} */
 
629
 
 
630
 
 
631
/* {{{ MySQL_ResultSet::getRowId() -U- */
 
632
sql::RowID *
 
633
MySQL_ResultSet::getRowId(const sql::SQLString &)
 
634
{
 
635
        CPP_ENTER("MySQL_ResultSet::getRowId");
 
636
        checkValid();
 
637
        throw sql::MethodNotImplementedException("MySQL_ResultSet::getRowId(const sql::SQLString & columnLabel)");
 
638
        return NULL; // fool compilers
 
639
}
 
640
/* }}} */
 
641
 
 
642
 
 
643
/* {{{ MySQL_ResultSet::getStatement() -I- */
 
644
const sql::Statement *
 
645
MySQL_ResultSet::getStatement() const
 
646
{
 
647
        CPP_ENTER("MySQL_ResultSet::getStatement");
 
648
        return parent;
 
649
}
 
650
/* }}} */
 
651
 
 
652
 
 
653
/* {{{ MySQL_ResultSet::getString() -I- */
 
654
SQLString
 
655
MySQL_ResultSet::getString(const uint32_t columnIndex) const
 
656
{
 
657
        CPP_ENTER("MySQL_ResultSet::getString(int)");
 
658
        CPP_INFO_FMT("this=%p column=%u", this, columnIndex);
 
659
 
 
660
        /* isBeforeFirst checks for validity */
 
661
        if (isBeforeFirstOrAfterLast()) {
 
662
                throw sql::InvalidArgumentException("MySQL_ResultSet::getString: can't fetch because not on result set");
 
663
        }
 
664
 
 
665
        if (columnIndex == 0 || columnIndex > num_fields) {
 
666
                throw sql::InvalidArgumentException("MySQL_ResultSet::getString: invalid value of 'columnIndex'");
 
667
        }
 
668
 
 
669
        if (row[columnIndex - 1] == NULL) {
 
670
                was_null = true;
 
671
                return "";
 
672
        }
 
673
 
 
674
        if (getFieldMeta(columnIndex)->type == MYSQL_TYPE_BIT) {
 
675
                char buf[30];
 
676
                snprintf(buf, sizeof(buf) - 1, "%llu", (unsigned long long) getUInt64(columnIndex));
 
677
                return sql::SQLString(buf);
 
678
        }
 
679
 
 
680
        size_t len = result->fetch_lengths()[columnIndex - 1];
 
681
        CPP_INFO_FMT("value=%*s",  len> 50? 50:len, row[columnIndex - 1]);
 
682
        was_null = false;
 
683
        return sql::SQLString(row[columnIndex - 1], len);
 
684
}
 
685
/* }}} */
 
686
 
 
687
 
 
688
/* {{{ MySQL_ResultSet::getString() -I- */
 
689
SQLString
 
690
MySQL_ResultSet::getString(const sql::SQLString& columnLabel) const
 
691
{
 
692
        CPP_ENTER("MySQL_ResultSet::getString(string)");
 
693
        return getString(findColumn(columnLabel));
 
694
}
 
695
/* }}} */
 
696
 
 
697
 
 
698
/* {{{ MySQL_ResultSet::getType() -I- */
 
699
sql::ResultSet::enum_type
 
700
MySQL_ResultSet::getType() const
 
701
{
 
702
        CPP_ENTER("MySQL_ResultSet::getType");
 
703
        checkValid();
 
704
        return resultset_type;
 
705
}
 
706
/* }}} */
 
707
 
 
708
 
 
709
/* {{{ MySQL_ResultSet::getWarnings() -U- */
 
710
void
 
711
MySQL_ResultSet::getWarnings()
 
712
{
 
713
        CPP_ENTER("MySQL_ResultSet::getWarnings");
 
714
        checkValid();
 
715
        throw sql::MethodNotImplementedException("MySQL_ResultSet::getWarnings()");
 
716
}
 
717
/* }}} */
 
718
 
 
719
 
 
720
/* {{{ MySQL_ResultSet::insertRow() -U- */
 
721
void
 
722
MySQL_ResultSet::insertRow()
 
723
{
 
724
        CPP_ENTER("MySQL_ResultSet::insertRow");
 
725
        checkValid();
 
726
        throw sql::MethodNotImplementedException("MySQL_ResultSet::insertRow()");
 
727
}
 
728
/* }}} */
 
729
 
 
730
 
 
731
/* {{{ MySQL_ResultSet::isAfterLast() -I- */
 
732
bool
 
733
MySQL_ResultSet::isAfterLast() const
 
734
{
 
735
        CPP_ENTER("MySQL_ResultSet::isAfterLast");
 
736
        checkValid();
 
737
        checkScrollable();
 
738
        return (row_position == num_rows + 1);
 
739
}
 
740
/* }}} */
 
741
 
 
742
 
 
743
/* {{{ MySQL_ResultSet::isBeforeFirst() -I- */
 
744
bool
 
745
MySQL_ResultSet::isBeforeFirst() const
 
746
{
 
747
        CPP_ENTER("MySQL_ResultSet::isBeforeFirst");
 
748
        checkValid();
 
749
        return (row_position == 0);
 
750
}
 
751
/* }}} */
 
752
 
 
753
 
 
754
/* {{{ MySQL_ResultSet::isClosed() -I- */
 
755
bool
 
756
MySQL_ResultSet::isClosed() const
 
757
{
 
758
        CPP_ENTER("MySQL_ResultSet::isClosed");
 
759
        return !result;
 
760
//      return !result->isValid();
 
761
}
 
762
/* }}} */
 
763
 
 
764
 
 
765
/* {{{ MySQL_ResultSet::isFirst() -I- */
 
766
bool
 
767
MySQL_ResultSet::isFirst() const
 
768
{
 
769
        CPP_ENTER("MySQL_ResultSet::isFirst");
 
770
        checkValid();
 
771
        return (row_position == 1);
 
772
}
 
773
/* }}} */
 
774
 
 
775
 
 
776
/* {{{ MySQL_ResultSet::isLast() -I- */
 
777
bool
 
778
MySQL_ResultSet::isLast() const
 
779
{
 
780
        CPP_ENTER("MySQL_ResultSet::isLast");
 
781
        checkValid();
 
782
        checkScrollable();
 
783
        return (row_position == num_rows);
 
784
}
 
785
/* }}} */
 
786
 
 
787
 
 
788
/* {{{ MySQL_ResultSet::isNull() -I- */
 
789
bool
 
790
MySQL_ResultSet::isNull(const uint32_t columnIndex) const
 
791
{
 
792
        CPP_ENTER("MySQL_ResultSet::isNull(int)");
 
793
        checkValid();
 
794
 
 
795
        if (columnIndex == 0 || columnIndex > num_fields) {
 
796
                throw sql::InvalidArgumentException("MySQL_ResultSet::isNull: invalid value of 'columnIndex'");
 
797
        }
 
798
        /* isBeforeFirst checks for validity */
 
799
        if (isBeforeFirstOrAfterLast()) {
 
800
                throw sql::InvalidArgumentException("MySQL_ResultSet::getDouble: can't fetch because not on result set");
 
801
        }
 
802
        return (row[columnIndex - 1] == NULL);
 
803
}
 
804
/* }}} */
 
805
 
 
806
 
 
807
/* {{{ MySQL_ResultSet::isNull() -I- */
 
808
bool
 
809
MySQL_ResultSet::isNull(const sql::SQLString& columnLabel) const
 
810
{
 
811
        CPP_ENTER("MySQL_ResultSet::isNull(string)");
 
812
        int32_t col_idx = findColumn(columnLabel);
 
813
        if (col_idx == 0) {
 
814
                throw sql::InvalidArgumentException("MySQL_ResultSet::isNull: invalid value of 'columnLabel'");
 
815
        }
 
816
        return isNull(col_idx);
 
817
}
 
818
/* }}} */
 
819
 
 
820
 
 
821
/* {{{ MySQL_ResultSet::last() -I- */
 
822
bool
 
823
MySQL_ResultSet::last()
 
824
{
 
825
        CPP_ENTER("MySQL_ResultSet::last");
 
826
        checkValid();
 
827
        checkScrollable();
 
828
        if (num_rows) {
 
829
                row_position = num_rows;
 
830
                seek();
 
831
        }
 
832
        return num_rows != 0;
 
833
}
 
834
/* }}} */
 
835
 
 
836
 
 
837
/* {{{ MySQL_ResultSet::moveToCurrentRow() -U- */
 
838
void
 
839
MySQL_ResultSet::moveToCurrentRow()
 
840
{
 
841
        CPP_ENTER("MySQL_ResultSet::moveToCurrentRow");
 
842
        checkValid();
 
843
        throw sql::MethodNotImplementedException("MySQL_ResultSet::moveToCurrentRow()");
 
844
        checkScrollable();
 
845
}
 
846
/* }}} */
 
847
 
 
848
 
 
849
/* {{{ MySQL_ResultSet::moveToInsertRow() -U- */
 
850
void
 
851
MySQL_ResultSet::moveToInsertRow()
 
852
{
 
853
        CPP_ENTER("MySQL_ResultSet::moveToInsertRow");
 
854
        checkValid();
 
855
        throw sql::MethodNotImplementedException("MySQL_ResultSet::moveToInsertRow()");
 
856
        checkScrollable();
 
857
}
 
858
/* }}} */
 
859
 
 
860
 
 
861
/* {{{ MySQL_ResultSet::next() -I- */
 
862
bool
 
863
MySQL_ResultSet::next()
 
864
{
 
865
        CPP_ENTER("MySQL_ResultSet::next");
 
866
        checkValid();
 
867
        bool ret = false;
 
868
        if (isScrollable()) {
 
869
                if (isLast()) {
 
870
                        afterLast();
 
871
                } else if (row_position < num_rows + 1) {
 
872
                        row = result->fetch_row();
 
873
                        ++row_position;
 
874
                        ret = (row != NULL);
 
875
                }
 
876
        } else {
 
877
                row = result->fetch_row();
 
878
                ++row_position;
 
879
                ret = (row != NULL);
 
880
        }
 
881
        CPP_INFO_FMT("new_position=%llu num_rows=%llu", row_position, num_rows);
 
882
        return ret;
 
883
}
 
884
/* }}} */
 
885
 
 
886
 
 
887
/* {{{ MySQL_ResultSet::previous() -I- */
 
888
bool
 
889
MySQL_ResultSet::previous()
 
890
{
 
891
        CPP_ENTER("MySQL_ResultSet::previous");
 
892
 
 
893
        checkScrollable();
 
894
        /* isBeforeFirst checks for validity */
 
895
        if (isBeforeFirst()) {
 
896
                return false;
 
897
        } else if (isFirst()) {
 
898
                beforeFirst();
 
899
                return false;
 
900
        } else if (row_position > 1) {
 
901
                --row_position;
 
902
                seek();
 
903
                return true;
 
904
        }
 
905
        throw sql::SQLException("Impossible");
 
906
}
 
907
/* }}} */
 
908
 
 
909
 
 
910
/* {{{ MySQL_ResultSet::refreshRow() -U- */
 
911
void
 
912
MySQL_ResultSet::refreshRow()
 
913
{
 
914
        CPP_ENTER("MySQL_ResultSet::refreshRow");
 
915
        checkValid();
 
916
        throw sql::MethodNotImplementedException("MySQL_ResultSet::refreshRow()");
 
917
}
 
918
/* }}} */
 
919
 
 
920
 
 
921
/* {{{ MySQL_ResultSet::relative() -I- */
 
922
bool
 
923
MySQL_ResultSet::relative(const int rows)
 
924
{
 
925
        CPP_ENTER("MySQL_ResultSet::relative");
 
926
        checkValid();
 
927
        checkScrollable();
 
928
        if (rows != 0) {
 
929
                if ((row_position + rows) > num_rows || (row_position + rows) < 1) {
 
930
                        row_position = rows > 0? num_rows + 1 : 0; /* after last or before first */
 
931
                } else {
 
932
                        row_position += rows;
 
933
                        seek();
 
934
                }
 
935
        }
 
936
 
 
937
        return (row_position > 0 && row_position <= num_rows);
 
938
}
 
939
/* }}} */
 
940
 
 
941
 
 
942
/* {{{ MySQL_ResultSet::rowDeleted() -U- */
 
943
bool
 
944
MySQL_ResultSet::rowDeleted()
 
945
{
 
946
        CPP_ENTER("MySQL_ResultSet::rowDeleted");
 
947
        checkValid();
 
948
        throw sql::MethodNotImplementedException("MySQL_ResultSet::rowDeleted()");
 
949
        return false; // fool compilers
 
950
}
 
951
/* }}} */
 
952
 
 
953
 
 
954
/* {{{ MySQL_ResultSet::rowInserted() -U- */
 
955
bool
 
956
MySQL_ResultSet::rowInserted()
 
957
{
 
958
        CPP_ENTER("MySQL_ResultSet::rowInserted");
 
959
        checkValid();
 
960
        throw sql::MethodNotImplementedException("MySQL_ResultSet::rowInserted()");
 
961
        return false; // fool compilers
 
962
}
 
963
/* }}} */
 
964
 
 
965
 
 
966
/* {{{ MySQL_ResultSet::rowUpdated() -U- */
 
967
bool
 
968
MySQL_ResultSet::rowUpdated()
 
969
{
 
970
        CPP_ENTER("MySQL_ResultSet::rowUpdated");
 
971
        checkValid();
 
972
        throw sql::MethodNotImplementedException("MySQL_ResultSet::rowUpdated()");
 
973
        return false; // fool compilers
 
974
}
 
975
/* }}} */
 
976
 
 
977
 
 
978
/* {{{ MySQL_ResultSet::rowsCount() -I- */
 
979
size_t
 
980
MySQL_ResultSet::rowsCount() const
 
981
{
 
982
        CPP_ENTER("MySQL_ResultSet::rowsCount");
 
983
        checkValid();
 
984
        checkScrollable();
 
985
        return static_cast<size_t>(result->num_rows());
 
986
}
 
987
/* }}} */
 
988
 
 
989
 
 
990
/* {{{ MySQL_ResultSet::setFetchSize() -U- */
 
991
void
 
992
MySQL_ResultSet::setFetchSize(size_t /* rows */)
 
993
{
 
994
        CPP_ENTER("MySQL_ResultSet::setFetchSize");
 
995
        checkValid();
 
996
        throw sql::MethodNotImplementedException("MySQL_ResultSet::setFetchSize()");
 
997
}
 
998
/* }}} */
 
999
 
 
1000
 
 
1001
/* {{{ MySQL_ResultSet::wasNull() -I- */
 
1002
bool
 
1003
MySQL_ResultSet::wasNull() const
 
1004
{
 
1005
        CPP_ENTER("MySQL_ResultSet::wasNull");
 
1006
        checkValid();
 
1007
        /* isBeforeFirst checks for validity */
 
1008
        if (isBeforeFirstOrAfterLast()) {
 
1009
                throw sql::InvalidArgumentException("MySQL_ResultSet::wasNull: can't fetch because not on result set");
 
1010
        }
 
1011
        return was_null;
 
1012
}
 
1013
/* }}} */
 
1014
 
 
1015
 
 
1016
/* {{{ MySQL_ResultSet::isBeforeFirstOrAfterLast() -I- */
 
1017
bool
 
1018
MySQL_ResultSet::isBeforeFirstOrAfterLast() const
 
1019
{
 
1020
        CPP_ENTER("MySQL_ResultSet::isBeforeFirstOrAfterLast");
 
1021
        checkValid();
 
1022
        return (row_position == 0) || (isScrollable() && (row_position == num_rows + 1));
 
1023
}
 
1024
/* }}} */
 
1025
 
 
1026
 
 
1027
/* {{{ MySQL_ResultSet::seek() -I- */
 
1028
void
 
1029
MySQL_ResultSet::seek()
 
1030
{
 
1031
        CPP_ENTER("MySQL_ResultSet::seek");
 
1032
        checkScrollable();
 
1033
        result->data_seek(row_position - 1);
 
1034
        row = result->fetch_row();
 
1035
}
 
1036
/* }}} */
 
1037
 
 
1038
 
 
1039
} /* namespace mysql */
 
1040
} /* namespace sql */
 
1041
 
 
1042
/*
 
1043
 * Local variables:
 
1044
 * tab-width: 4
 
1045
 * c-basic-offset: 4
 
1046
 * End:
 
1047
 * vim600: noet sw=4 ts=4 fdm=marker
 
1048
 * vim<600: noet sw=4 ts=4
 
1049
 */