~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/sql/kernel/qsqlresult.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
 
4
**
 
5
** This file is part of the sql module of the Qt Toolkit.
 
6
**
 
7
** This file may be distributed under the terms of the Q Public License
 
8
** as defined by Trolltech AS of Norway and appearing in the file
 
9
** LICENSE.QPL included in the packaging of this file.
 
10
**
 
11
** This file may be distributed and/or modified under the terms of the
 
12
** GNU General Public License version 2 as published by the Free Software
 
13
** Foundation and appearing in the file LICENSE.GPL included in the
 
14
** packaging of this file.
 
15
**
 
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
 
17
**   information about Qt Commercial License Agreements.
 
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
 
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
 
20
**
 
21
** Contact info@trolltech.com if any conditions of this licensing are
 
22
** not clear to you.
 
23
**
 
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
26
**
 
27
****************************************************************************/
 
28
 
 
29
#include "qvariant.h"
 
30
#include "qmap.h"
 
31
#include "qregexp.h"
 
32
#include "qsqlerror.h"
 
33
#include "qsqlfield.h"
 
34
#include "qsqlrecord.h"
 
35
#include "qsqlresult.h"
 
36
#include "qvector.h"
 
37
#include "qsqldriver.h"
 
38
 
 
39
struct Holder {
 
40
    Holder(const QString& hldr = QString(), int index = -1): holderName(hldr), holderPos(index) {}
 
41
    bool operator==(const Holder& h) const { return h.holderPos == holderPos && h.holderName == holderName; }
 
42
    bool operator!=(const Holder& h) const { return h.holderPos != holderPos || h.holderName != holderName; }
 
43
    QString holderName;
 
44
    int            holderPos;
 
45
};
 
46
 
 
47
class QSqlResultPrivate
 
48
{
 
49
public:
 
50
    QSqlResultPrivate(QSqlResult* d)
 
51
    : q(d), sqldriver(0), idx(QSql::BeforeFirstRow), active(false),
 
52
      isSel(false), forwardOnly(false), bindCount(0), binds(QSqlResult::PositionalBinding)
 
53
    {}
 
54
 
 
55
    void clearValues()
 
56
    {
 
57
        values.clear();
 
58
        bindCount = 0;
 
59
    }
 
60
 
 
61
    void resetBindCount()
 
62
    {
 
63
        bindCount = 0;
 
64
    }
 
65
 
 
66
    void clearIndex()
 
67
    {
 
68
        indexes.clear();
 
69
        holders.clear();
 
70
        types.clear();
 
71
    }
 
72
 
 
73
    void clear()
 
74
    {
 
75
        clearValues();
 
76
        clearIndex();;
 
77
    }
 
78
 
 
79
    QString positionalToNamedBinding();
 
80
    QString namedToPositionalBinding();
 
81
    QString holderAt(int index) const;
 
82
 
 
83
public:
 
84
    QSqlResult* q;
 
85
    const QSqlDriver* sqldriver;
 
86
    int idx;
 
87
    QString sql;
 
88
    bool active;
 
89
    bool isSel;
 
90
    QSqlError error;
 
91
    bool forwardOnly;
 
92
 
 
93
    int bindCount;
 
94
    QSqlResult::BindingSyntax binds;
 
95
 
 
96
    QString executedQuery;
 
97
    QMap<int, QSql::ParamType> types;
 
98
    QVector<QVariant> values;
 
99
    typedef QMap<QString, int> IndexMap;
 
100
    IndexMap indexes;
 
101
 
 
102
    typedef QVector<Holder> HolderVector;
 
103
    HolderVector holders;
 
104
};
 
105
 
 
106
QString QSqlResultPrivate::holderAt(int index) const
 
107
{
 
108
    return indexes.key(index);
 
109
}
 
110
 
 
111
QString QSqlResultPrivate::positionalToNamedBinding()
 
112
{
 
113
    QRegExp rx(QLatin1String("'[^']*'|\\?"));
 
114
    QString q = sql;
 
115
    int i = 0, cnt = -1;
 
116
    while ((i = rx.indexIn(q, i)) != -1) {
 
117
        if (rx.cap(0) == QLatin1String("?"))
 
118
            q = q.replace(i, 1, QLatin1String(":f") + QString::number(++cnt));
 
119
        i += rx.matchedLength();
 
120
    }
 
121
    return q;
 
122
}
 
123
 
 
124
QString QSqlResultPrivate::namedToPositionalBinding()
 
125
{
 
126
    QRegExp rx(QLatin1String("'[^']*'|:([a-zA-Z0-9_]+)"));
 
127
    QString q = sql;
 
128
    int i = 0, cnt = -1;
 
129
    while ((i = rx.indexIn(q, i)) != -1) {
 
130
        if (rx.cap(1).isEmpty()) {
 
131
            i += rx.matchedLength();
 
132
        } else {
 
133
            // record the index of the placeholder - needed
 
134
            // for emulating named bindings with ODBC
 
135
            indexes[rx.cap(0)]= ++cnt;
 
136
            q.replace(i, rx.matchedLength(), QLatin1String("?"));
 
137
            ++i;
 
138
        }
 
139
    }
 
140
    return q;
 
141
}
 
142
 
 
143
/*!
 
144
    \class QSqlResult
 
145
    \brief The QSqlResult class provides an abstract interface for
 
146
    accessing data from specific SQL databases.
 
147
 
 
148
    \ingroup database
 
149
    \module sql
 
150
 
 
151
    Normally, you would use QSqlQuery instead of QSqlResult, since
 
152
    QSqlQuery provides a generic wrapper for database-specific
 
153
    implementations of QSqlResult.
 
154
 
 
155
    If you are implementing your own SQL driver (by subclassing
 
156
    QSqlDriver), you will need to provide your own QSqlResult
 
157
    subclass that implements all the pure virtual functions and other
 
158
    virtual functions that you need.
 
159
 
 
160
    \sa QSqlDriver
 
161
*/
 
162
 
 
163
/*!
 
164
    \enum QSqlResult::BindingSyntax
 
165
 
 
166
    This enum type specifies the different syntaxes for specifying
 
167
    placeholders in prepared queries.
 
168
 
 
169
    \value PositionalBinding Use the ODBC-style positional syntax, with "?" as placeholders.
 
170
    \value NamedBinding Use the Oracle-style syntax with named placeholders (e.g., ":id")
 
171
    \omitvalue BindByPosition
 
172
    \omitvalue BindByName
 
173
 
 
174
    \sa bindingSyntax()
 
175
*/
 
176
 
 
177
/*!
 
178
    Creates a QSqlResult using database driver \a db. The object is
 
179
    initialized to an inactive state.
 
180
 
 
181
    \sa isActive(), driver()
 
182
*/
 
183
 
 
184
QSqlResult::QSqlResult(const QSqlDriver *db)
 
185
{
 
186
    d = new QSqlResultPrivate(this);
 
187
    d->sqldriver = db;
 
188
}
 
189
 
 
190
/*!
 
191
    Destroys the object and frees any allocated resources.
 
192
*/
 
193
 
 
194
QSqlResult::~QSqlResult()
 
195
{
 
196
    delete d;
 
197
}
 
198
 
 
199
/*!
 
200
    Sets the current query for the result to \a query. You must call
 
201
    reset() to execute the query on the database.
 
202
 
 
203
    \sa reset(), lastQuery()
 
204
*/
 
205
 
 
206
void QSqlResult::setQuery(const QString& query)
 
207
{
 
208
    d->sql = query;
 
209
}
 
210
 
 
211
/*!
 
212
    Returns the current SQL query text, or an empty string if there
 
213
    isn't one.
 
214
 
 
215
    \sa setQuery()
 
216
*/
 
217
 
 
218
QString QSqlResult::lastQuery() const
 
219
{
 
220
    return d->sql;
 
221
}
 
222
 
 
223
/*!
 
224
    Returns the current (zero-based) row position of the result. May
 
225
    return the special values QSql::BeforeFirstRow or
 
226
    QSql::AfterLastRow.
 
227
 
 
228
    \sa setAt(), isValid()
 
229
*/
 
230
int QSqlResult::at() const
 
231
{
 
232
    return d->idx;
 
233
}
 
234
 
 
235
 
 
236
/*!
 
237
    Returns true if the result is positioned on a valid record (that
 
238
    is, the result is not positioned before the first or after the
 
239
    last record); otherwise returns false.
 
240
 
 
241
    \sa at()
 
242
*/
 
243
 
 
244
bool QSqlResult::isValid() const
 
245
{
 
246
    return d->idx != QSql::BeforeFirstRow && d->idx != QSql::AfterLastRow;
 
247
}
 
248
 
 
249
/*!
 
250
    \fn bool QSqlResult::isNull(int index)
 
251
 
 
252
    Returns true if the field at position \a index in the current row
 
253
    is null; otherwise returns false.
 
254
*/
 
255
 
 
256
/*!
 
257
    Returns true if the result has records to be retrieved; otherwise
 
258
    returns false.
 
259
*/
 
260
 
 
261
bool QSqlResult::isActive() const
 
262
{
 
263
    return d->active;
 
264
}
 
265
 
 
266
/*!
 
267
    This function is provided for derived classes to set the
 
268
    internal (zero-based) row position to \a index.
 
269
 
 
270
    \sa at()
 
271
*/
 
272
 
 
273
void QSqlResult::setAt(int index)
 
274
{
 
275
    d->idx = index;
 
276
}
 
277
 
 
278
 
 
279
/*!
 
280
    This function is provided for derived classes to indicate whether
 
281
    or not the current statement is a SQL \c SELECT statement. The \a
 
282
    select parameter should be true if the statement is a \c SELECT
 
283
    statement; otherwise it should be false.
 
284
 
 
285
    \sa isSelect()
 
286
*/
 
287
 
 
288
void QSqlResult::setSelect(bool select)
 
289
{
 
290
    d->isSel = select;
 
291
}
 
292
 
 
293
/*!
 
294
    Returns true if the current result is from a \c SELECT statement;
 
295
    otherwise returns false.
 
296
 
 
297
    \sa setSelect()
 
298
*/
 
299
 
 
300
bool QSqlResult::isSelect() const
 
301
{
 
302
    return d->isSel;
 
303
}
 
304
 
 
305
/*!
 
306
    Returns the driver associated with the result. This is the object
 
307
    that was passed to the constructor.
 
308
*/
 
309
 
 
310
const QSqlDriver *QSqlResult::driver() const
 
311
{
 
312
    return d->sqldriver;
 
313
}
 
314
 
 
315
 
 
316
/*!
 
317
    This function is provided for derived classes to set the internal
 
318
    active state to \a active.
 
319
 
 
320
    \sa isActive()
 
321
*/
 
322
 
 
323
void QSqlResult::setActive(bool active)
 
324
{
 
325
    d->active = active;
 
326
}
 
327
 
 
328
/*!
 
329
    This function is provided for derived classes to set the last
 
330
    error to \a error.
 
331
 
 
332
    \sa lastError()
 
333
*/
 
334
 
 
335
void QSqlResult::setLastError(const QSqlError &error)
 
336
{
 
337
    d->error = error;
 
338
}
 
339
 
 
340
 
 
341
/*!
 
342
    Returns the last error associated with the result.
 
343
*/
 
344
 
 
345
QSqlError QSqlResult::lastError() const
 
346
{
 
347
    return d->error;
 
348
}
 
349
 
 
350
/*!
 
351
    \fn int QSqlResult::size()
 
352
 
 
353
    Returns the size of the \c SELECT result, or -1 if it cannot be
 
354
    determined or if the query is not a \c SELECT statement.
 
355
 
 
356
    \sa numRowsAffected()
 
357
*/
 
358
 
 
359
/*!
 
360
    \fn int QSqlResult::numRowsAffected()
 
361
 
 
362
    Returns the number of rows affected by the last query executed, or
 
363
    -1 if it cannot be determined or if the query is a \c SELECT
 
364
    statement.
 
365
 
 
366
    \sa size()
 
367
*/
 
368
 
 
369
/*!
 
370
    \fn QVariant QSqlResult::data(int index)
 
371
 
 
372
    Returns the data for field \a index in the current row as
 
373
    a QVariant. This function is only called if the result is in
 
374
    an active state and is positioned on a valid record and \a index is
 
375
    non-negative. Derived classes must reimplement this function and
 
376
    return the value of field \a index, or QVariant() if it cannot be
 
377
    determined.
 
378
*/
 
379
 
 
380
/*!
 
381
    \fn  bool QSqlResult::reset(const QString &query)
 
382
 
 
383
    Sets the result to use the SQL statement \a query for subsequent
 
384
    data retrieval.
 
385
    
 
386
    Derived classes must reimplement this function and apply the \a
 
387
    query to the database. This function is only called after the
 
388
    result is set to an inactive state and is positioned before the
 
389
    first record of the new result. Derived classes should return
 
390
    true if the query was successful and ready to be used, or false
 
391
    otherwise.
 
392
 
 
393
    \sa setQuery()
 
394
*/
 
395
 
 
396
/*!
 
397
    \fn bool QSqlResult::fetch(int index)
 
398
 
 
399
    Positions the result to an arbitrary (zero-based) row \a index.
 
400
 
 
401
    This function is only called if the result is in an active state.
 
402
    Derived classes must reimplement this function and position the
 
403
    result to the row \a index, and call setAt() with an appropriate
 
404
    value. Return true to indicate success, or false to signify
 
405
    failure.
 
406
 
 
407
    \sa isActive(), fetchFirst(), fetchLast(), fetchNext(), fetchPrevious()
 
408
*/
 
409
 
 
410
/*!
 
411
    \fn bool QSqlResult::fetchFirst()
 
412
 
 
413
    Positions the result to the first record (row 0) in the result.
 
414
 
 
415
    This function is only called if the result is in an active state.
 
416
    Derived classes must reimplement this function and position the
 
417
    result to the first record, and call setAt() with an appropriate
 
418
    value. Return true to indicate success, or false to signify
 
419
    failure.
 
420
 
 
421
    \sa fetch(), fetchLast()
 
422
*/
 
423
 
 
424
/*!
 
425
    \fn bool QSqlResult::fetchLast()
 
426
 
 
427
    Positions the result to the last record (last row) in the result.
 
428
 
 
429
    This function is only called if the result is in an active state.
 
430
    Derived classes must reimplement this function and position the
 
431
    result to the last record, and call setAt() with an appropriate
 
432
    value. Return true to indicate success, or false to signify
 
433
    failure.
 
434
 
 
435
    \sa fetch(), fetchFirst()
 
436
*/
 
437
 
 
438
/*!
 
439
    Positions the result to the next available record (row) in the
 
440
    result.
 
441
 
 
442
    This function is only called if the result is in an active
 
443
    state. The default implementation calls fetch() with the next
 
444
    index. Derived classes can reimplement this function and position
 
445
    the result to the next record in some other way, and call setAt()
 
446
    with an appropriate value. Return true to indicate success, or
 
447
    false to signify failure.
 
448
 
 
449
    \sa fetch(), fetchPrevious()
 
450
*/
 
451
 
 
452
bool QSqlResult::fetchNext()
 
453
{
 
454
    return fetch(at() + 1);
 
455
}
 
456
 
 
457
/*!
 
458
    Positions the result to the previous record (row) in the result.
 
459
 
 
460
    This function is only called if the result is in an active state.
 
461
    The default implementation calls fetch() with the previous index.
 
462
    Derived classes can reimplement this function and position the
 
463
    result to the next record in some other way, and call setAt()
 
464
    with an appropriate value. Return true to indicate success, or
 
465
    false to signify failure.
 
466
*/
 
467
 
 
468
bool QSqlResult::fetchPrevious()
 
469
{
 
470
    return fetch(at() - 1);
 
471
}
 
472
 
 
473
/*!
 
474
    Returns true if you can only scroll forward through the result
 
475
    set; otherwise returns false.
 
476
 
 
477
    \sa setForwardOnly()
 
478
*/
 
479
bool QSqlResult::isForwardOnly() const
 
480
{
 
481
    return d->forwardOnly;
 
482
}
 
483
 
 
484
/*!
 
485
    Sets forward only mode to \a forward. If \a forward is true, only
 
486
    fetchNext() is allowed for navigating the results. Forward only
 
487
    mode needs much less memory since results do not have to be
 
488
    cached. By default, this feature is disabled.
 
489
 
 
490
    \sa isForwardOnly(), fetchNext()
 
491
*/
 
492
void QSqlResult::setForwardOnly(bool forward)
 
493
{
 
494
    d->forwardOnly = forward;
 
495
}
 
496
 
 
497
/*!
 
498
    Prepares the given \a query, using the underlying database
 
499
    functionality where possible.
 
500
 
 
501
    \sa prepare()
 
502
*/
 
503
bool QSqlResult::savePrepare(const QString& query)
 
504
{
 
505
    if (!driver())
 
506
        return false;
 
507
    d->clear();
 
508
    d->sql = query;
 
509
    if (!driver()->hasFeature(QSqlDriver::PreparedQueries))
 
510
        return prepare(query);
 
511
 
 
512
    if (driver()->hasFeature(QSqlDriver::NamedPlaceholders)) {
 
513
        // parse the query to memorize parameter location
 
514
        d->namedToPositionalBinding();
 
515
        d->executedQuery = d->positionalToNamedBinding();
 
516
    } else {
 
517
        d->executedQuery = d->namedToPositionalBinding();
 
518
    }
 
519
    return prepare(d->executedQuery);
 
520
}
 
521
 
 
522
/*!
 
523
    Prepares the given \a query for execution; the query will normally
 
524
    use placeholders so that it can be executed repeatedly.
 
525
 
 
526
    \sa exec()
 
527
*/
 
528
bool QSqlResult::prepare(const QString& query)
 
529
{
 
530
    QRegExp rx(QLatin1String("'[^']*'|:([a-zA-Z0-9_]+)"));
 
531
    int i = 0;
 
532
    while ((i = rx.indexIn(query, i)) != -1) {
 
533
        if (!rx.cap(1).isEmpty())
 
534
            d->holders.append(Holder(rx.cap(0), i));
 
535
        i += rx.matchedLength();
 
536
    }
 
537
    d->sql = query;
 
538
    return true; // fake prepares should always succeed
 
539
}
 
540
 
 
541
/*!
 
542
    Executes the query.
 
543
 
 
544
    \sa prepare()
 
545
*/
 
546
bool QSqlResult::exec()
 
547
{
 
548
    bool ret;
 
549
    // fake preparation - just replace the placeholders..
 
550
    QString query = lastQuery();
 
551
    if (d->binds == NamedBinding) {
 
552
        int i;
 
553
        QVariant val;
 
554
        QString holder;
 
555
        for (i = d->holders.count() - 1; i >= 0; --i) {
 
556
            holder = d->holders[i].holderName;
 
557
            val = d->values[d->indexes[holder]];
 
558
            QSqlField f(QLatin1String(""), val.type());
 
559
            f.setValue(val);
 
560
            query = query.replace(d->holders[i].holderPos,
 
561
                                   holder.length(), driver()->formatValue(f));
 
562
        }
 
563
    } else {
 
564
        QString val;
 
565
        int i = 0;
 
566
        int idx = 0;
 
567
        for (idx = 0; idx < d->values.count(); ++idx) {
 
568
            i = query.indexOf(QLatin1Char('?'), i);
 
569
            if (i == -1)
 
570
                continue;
 
571
            QVariant var = d->values[idx];
 
572
            QSqlField f(QLatin1String(""), var.type());
 
573
            if (var.isNull())
 
574
                f.clear();
 
575
            else
 
576
                f.setValue(var);
 
577
            val = driver()->formatValue(f);
 
578
            query = query.replace(i, 1, driver()->formatValue(f));
 
579
            i += val.length();
 
580
        }
 
581
    }
 
582
 
 
583
    // have to retain the original query with placeholders
 
584
    QString orig = lastQuery();
 
585
    ret = reset(query);
 
586
    d->executedQuery = query;
 
587
    setQuery(orig);
 
588
    d->resetBindCount();
 
589
    return ret;
 
590
}
 
591
 
 
592
/*!
 
593
    Binds the value \a val of parameter type \a paramType to position \a index
 
594
    in the current record (row).
 
595
 
 
596
    \sa addBindValue()
 
597
*/
 
598
void QSqlResult::bindValue(int index, const QVariant& val, QSql::ParamType paramType)
 
599
{
 
600
    d->binds = PositionalBinding;
 
601
    QString nm(QLatin1String(":f") + QString::number(index));
 
602
    d->indexes[nm] = index;
 
603
    if (d->values.count() <= index)
 
604
        d->values.resize(index + 1);
 
605
    d->values[index] = val;
 
606
    if (paramType != QSql::In || !d->types.isEmpty())
 
607
        d->types[index] = paramType;
 
608
}
 
609
 
 
610
/*!
 
611
    \overload
 
612
 
 
613
    Binds the value \a val of parameter type \a paramType to the \a
 
614
    placeholder name in the current record (row).
 
615
*/
 
616
void QSqlResult::bindValue(const QString& placeholder, const QVariant& val,
 
617
                           QSql::ParamType paramType)
 
618
{
 
619
    d->binds = NamedBinding;
 
620
    // if the index has already been set when doing emulated named
 
621
    // bindings - don't reset it
 
622
    int idx = d->indexes.value(placeholder, -1);
 
623
    if (idx >= 0) {
 
624
        if (d->values.count() <= idx)
 
625
            d->values.resize(idx + 1);
 
626
        d->values[idx] = val;
 
627
    } else {
 
628
        d->values.append(val);
 
629
        idx = d->values.count() - 1;
 
630
        d->indexes[placeholder] = idx;
 
631
    }
 
632
 
 
633
    if (paramType != QSql::In || !d->types.isEmpty())
 
634
        d->types[idx] = paramType;
 
635
}
 
636
 
 
637
/*!
 
638
    Binds the value \a val of parameter type \a paramType to the next
 
639
    available position in the current record (row).
 
640
 
 
641
    \sa bindValue()
 
642
*/
 
643
void QSqlResult::addBindValue(const QVariant& val, QSql::ParamType paramType)
 
644
{
 
645
    d->binds = PositionalBinding;
 
646
    bindValue(d->bindCount, val, paramType);
 
647
    ++d->bindCount;
 
648
}
 
649
 
 
650
/*!
 
651
    Returns the value bound at position \a index in the current record
 
652
    (row).
 
653
 
 
654
    \sa bindValue(), boundValues()
 
655
*/
 
656
QVariant QSqlResult::boundValue(int index) const
 
657
{
 
658
    return d->values.value(index);
 
659
}
 
660
 
 
661
/*!
 
662
    \overload
 
663
 
 
664
    Returns the value bound by the given \a placeholder name in the
 
665
    current record (row).
 
666
 
 
667
    \sa bindValueType()
 
668
*/
 
669
QVariant QSqlResult::boundValue(const QString& placeholder) const
 
670
{
 
671
    int idx = d->indexes.value(placeholder, -1);
 
672
    return d->values.value(idx);
 
673
}
 
674
 
 
675
/*!
 
676
    Returns the parameter type for the value bound at position \a index.
 
677
 
 
678
    \sa boundValue()
 
679
*/
 
680
QSql::ParamType QSqlResult::bindValueType(int index) const
 
681
{
 
682
    return d->types.value(index, QSql::In);
 
683
}
 
684
 
 
685
/*!
 
686
    \overload
 
687
 
 
688
    Returns the parameter type for the value bound with the given \a
 
689
    placeholder name.
 
690
*/
 
691
QSql::ParamType QSqlResult::bindValueType(const QString& placeholder) const
 
692
{
 
693
    return d->types.value(d->indexes.value(placeholder, -1), QSql::In);
 
694
}
 
695
 
 
696
/*!
 
697
    Returns the number of bound values in the result.
 
698
 
 
699
    \sa boundValues()
 
700
*/
 
701
int QSqlResult::boundValueCount() const
 
702
{
 
703
    return d->values.count();
 
704
}
 
705
 
 
706
/*!
 
707
    Returns a vector of the result's bound values for the current
 
708
    record (row).
 
709
 
 
710
    \sa boundValueCount()
 
711
*/
 
712
QVector<QVariant>& QSqlResult::boundValues() const
 
713
{
 
714
    return d->values;
 
715
}
 
716
 
 
717
/*!
 
718
    Returns the binding syntax used by prepared queries.
 
719
*/
 
720
QSqlResult::BindingSyntax QSqlResult::bindingSyntax() const
 
721
{
 
722
    return d->binds;
 
723
}
 
724
 
 
725
/*!
 
726
    Clears the entire result set and releases any associated
 
727
    resources.
 
728
*/
 
729
void QSqlResult::clear()
 
730
{
 
731
    d->clear();
 
732
}
 
733
 
 
734
/*!
 
735
    Returns the query that was actually executed. This may differ from
 
736
    the query that was passed, for example if bound values were used
 
737
    with a prepared query and the underlying database doesn't support
 
738
    prepared queries.
 
739
 
 
740
    \sa exec(), setQuery()
 
741
*/
 
742
QString QSqlResult::executedQuery() const
 
743
{
 
744
    return d->executedQuery;
 
745
}
 
746
 
 
747
void QSqlResult::resetBindCount()
 
748
{
 
749
    d->resetBindCount();
 
750
}
 
751
 
 
752
/*!
 
753
    Returns the name of the bound value at position \a index in the
 
754
    current record (row).
 
755
 
 
756
    \sa boundValue()
 
757
*/
 
758
QString QSqlResult::boundValueName(int index) const
 
759
{
 
760
    return d->holderAt(index);
 
761
}
 
762
 
 
763
/*!
 
764
    Returns true if at least one of the query's bound values is a \c
 
765
    QSql::Out or a \c QSql::InOut; otherwise returns false.
 
766
 
 
767
    \sa bindValueType()
 
768
*/
 
769
bool QSqlResult::hasOutValues() const
 
770
{
 
771
    if (d->types.isEmpty())
 
772
        return false;
 
773
    QMap<int, QSql::ParamType>::ConstIterator it;
 
774
    for (it = d->types.constBegin(); it != d->types.constEnd(); ++it) {
 
775
        if (it.value() != QSql::In)
 
776
            return true;
 
777
    }
 
778
    return false;
 
779
}
 
780
 
 
781
/*!
 
782
    Returns the current record if the query is active; otherwise
 
783
    returns an empty QSqlRecord.
 
784
 
 
785
    The default implementation always returns an empty QSqlRecord.
 
786
 
 
787
    \sa isActive()
 
788
*/
 
789
QSqlRecord QSqlResult::record() const
 
790
{
 
791
    return QSqlRecord();
 
792
}
 
793
 
 
794
/*!
 
795
    Returns the object ID of the most recent inserted row if the
 
796
    database supports it.
 
797
    An invalid QVariant will be returned if the query did not
 
798
    insert any value or if the database does not report the id back.
 
799
    If more than one row was touched by the insert, the behavior is
 
800
    undefined.
 
801
 
 
802
    \sa QSqlDriver::hasFeature()
 
803
*/
 
804
QVariant QSqlResult::lastInsertId() const
 
805
{
 
806
    return QVariant();
 
807
}
 
808
 
 
809
/*! \internal
 
810
*/
 
811
void QSqlResult::virtual_hook(int, void *)
 
812
{
 
813
}
 
814
 
 
815
 
 
816
/*!
 
817
    Returns the low-level database handle for this result set
 
818
    wrapped in a QVariant or an invalid QVariant if there is no handle.
 
819
 
 
820
    \warning Use this with uttermost care and only if you know what you're doing.
 
821
 
 
822
    \warning The handle returned here can become a stale pointer if the result
 
823
    is modified (for example, if you clear it).
 
824
 
 
825
    \warning The handle can be NULL if the result was not executed yet.
 
826
 
 
827
    The handle returned here is database-dependent, you should query the type
 
828
    name of the variant before accessing it.
 
829
 
 
830
    This example retrieves the handle for a sqlite result:
 
831
 
 
832
    \code
 
833
    QSqlQuery query = ...
 
834
    QVariant v = query.result()->handle();
 
835
    if (v.isValid() && v.typeName() == "sqlite3_stmt*") {
 
836
        // v.data() returns a pointer to the handle
 
837
        sqlite3_stmt *handle = *static_cast<sqlite3_stmt **>(v.data());
 
838
        if (handle != 0) { // check that it is not NULL
 
839
            ...
 
840
        }
 
841
    }
 
842
    \endcode
 
843
 
 
844
    This snippet returns the handle for PostgreSQL or MySQL:
 
845
 
 
846
    \code
 
847
    if (v.typeName() == "PGresult*") {
 
848
        PGresult *handle = *static_cast<PGresult **>(v.data());
 
849
        if (handle != 0) ...
 
850
    }
 
851
 
 
852
    if (v.typeName() == "MYSQL_STMT*") {
 
853
        MYSQL_STMT *handle = *static_cast<MYSQL_STMT **>(v.data());
 
854
        if (handle != 0) ...
 
855
    }
 
856
    \endcode
 
857
 
 
858
    \sa QSqlDriver::handle()
 
859
*/
 
860
QVariant QSqlResult::handle() const
 
861
{
 
862
    return QVariant();
 
863
}
 
864