/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt3Support module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <qplatformdefs.h>
#include "q3sqlcursor.h"

#ifndef QT_NO_SQL

#include "qsqldriver.h"
#include "qsqlresult.h"
#include "qdatetime.h"
#include "qsqldatabase.h"
#include "qsql.h"
#include "q3sqlrecordinfo.h"
#include "q3sqlfieldinfo.h"

QT_BEGIN_NAMESPACE

class Q3SqlCursorPrivate
{
public:

    Q3SqlCursorPrivate(const QString& name, QSqlDatabase sdb)
        : lastAt(QSql::BeforeFirst), nm(name), srt(name), md(0), db(sdb), q(0)
    {}
    ~Q3SqlCursorPrivate()
    {
        delete q;
    }

    QSqlQuery* query()
    {
        if (!q)
            q = new QSqlQuery(QString(), db);
        return q;
    }

    int lastAt;
    QString nm;         //name
    QSqlIndex srt;        //sort
    QString ftr;        //filter
    int md;         //mode
    QSqlIndex priIndx;    //primary index
    QSqlRecord editBuffer;
    // the primary index as it was before the user changed the values in editBuffer
    QString editIndex;
    Q3SqlRecordInfo infoBuffer;
    QSqlDatabase db;
    QSqlQuery *q;
};

QString qOrderByClause(const QSqlIndex & i, const QString& prefix = QString())
{
    QString str;
    int k = i.count();
    if(k == 0)
        return QString();
    str = QLatin1String(" order by ") + i.toString(prefix);
    return str;
}

QString qWhereClause(const QString& prefix, QSqlField* field, const QSqlDriver* driver)
{
    QString f;
    if (field && driver) {
        if (!prefix.isEmpty())
            f += prefix + QLatin1Char('.');
        f += field->name();
        if (field->isNull()) {
            f += QLatin1String(" IS NULL");
        } else {
            f += QLatin1String(" = ") + driver->formatValue(field);
        }
    }
    return f;
}

QString qWhereClause(QSqlRecord* rec, const QString& prefix, const QString& sep,
                      const QSqlDriver* driver)
{
    static QString blank(QLatin1Char(' '));
    QString filter;
    bool separator = false;
    for (int j = 0; j < rec->count(); ++j) {
        QSqlField f = rec->field(j);
        if (rec->isGenerated(j)) {
            if (separator)
                filter += sep + blank;
            filter += qWhereClause(prefix, &f, driver);
            filter += blank;
            separator = true;
        }
    }
    return filter;
}

/*!
    \class Q3SqlCursor
    \brief The Q3SqlCursor class provides browsing and editing of SQL
    tables and views.

    \compat

    A Q3SqlCursor is a database record (see \l QSqlRecord) that
    corresponds to a table or view within an SQL database (see \l
    QSqlDatabase). There are two buffers in a cursor, one used for
    browsing and one used for editing records. Each buffer contains a
    list of fields which correspond to the fields in the table or
    view.

    When positioned on a valid record, the browse buffer contains the
    values of the current record's fields from the database. The edit
    buffer is separate, and is used for editing existing records and
    inserting new records.

    For browsing data, a cursor must first select() data from the
    database. After a successful select() the cursor is active
    (isActive() returns true), but is initially not positioned on a
    valid record (isValid() returns false). To position the cursor on
    a valid record, use one of the navigation functions, next(),
    previous(), first(), last(), or seek(). Once positioned on a valid
    record, data can be retrieved from the browse buffer using
    value(). If a navigation function is not successful, it returns
    false, the cursor will no longer be positioned on a valid record
    and the values returned by value() are undefined.

    For example:

    \snippet doc/src/snippets/code/src_qt3support_sql_q3sqlcursor.cpp 0

    In the above example, a cursor is created specifying a table or
    view name in the database. Then, select() is called, which can be
    optionally parameterised to filter and order the records
    retrieved. Each record in the cursor is retrieved using next().
    When next() returns false, there are no more records to process,
    and the loop terminates.

    For editing records (rows of data), a cursor contains a separate
    edit buffer which is independent of the fields used when browsing.
    The functions insert(), update() and del() operate on the edit
    buffer. This allows the cursor to be repositioned to other
    records while simultaneously maintaining a separate buffer for
    edits. You can get a pointer to the edit buffer using
    editBuffer(). The primeInsert(), primeUpdate() and primeDelete()
    functions also return a pointer to the edit buffer and prepare it
    for insert, update and delete respectively. Edit operations only
    affect a single row at a time. Note that update() and del()
    require that the table or view contain a primaryIndex() to ensure
    that edit operations affect a unique record within the database.

    For example:

    \snippet doc/src/snippets/code/src_qt3support_sql_q3sqlcursor.cpp 1

    To edit an existing database record, first move to the record you
    wish to update. Call primeUpdate() to get the pointer to the
    cursor's edit buffer. Then use this pointer to modify the values
    in the edit buffer. Finally, call update() to save the changes to
    the database. The values in the edit buffer will be used to
    locate the appropriate record when updating the database (see
    primaryIndex()).

    Similarly, when deleting an existing database record, first move
    to the record you wish to delete. Then, call primeDelete() to get
    the pointer to the edit buffer. Finally, call del() to delete the
    record from the database. Again, the values in the edit buffer
    will be used to locate and delete the appropriate record.

    To insert a new record, call primeInsert() to get the pointer to
    the edit buffer. Use this pointer to populate the edit buffer
    with new values and then insert() the record into the database.

    After calling insert(), update() or del(), the cursor is no longer
    positioned on a valid record and can no longer be navigated
    (isValid() return false). The reason for this is that any changes
    made to the database will not be visible until select() is called
    to refresh the cursor. You can change this behavior by passing
    false to insert(), update() or del() which will prevent the cursor
    from becoming invalid. The edits will still not be visible when
    navigating the cursor until select() is called.

    Q3SqlCursor contains virtual methods which allow editing behavior
    to be customized by subclasses. This allows custom cursors to be
    created that encapsulate the editing behavior of a database table
    for an entire application. For example, a cursor can be customized
    to always auto-number primary index fields, or provide fields with
    suitable default values, when inserting new records. Q3SqlCursor
    generates SQL statements which are sent to the database engine;
    you can control which fields are included in these statements
    using setGenerated().

    Note that Q3SqlCursor does not inherit from QObject. This means
    that you are responsible for destroying instances of this class
    yourself. However if you create a Q3SqlCursor and use it in a
    \l Q3DataTable, \l Q3DataBrowser or a \l Q3DataView these classes will
    usually take ownership of the cursor and destroy it when they
    don't need it anymore. The documentation for Q3DataTable,
    Q3DataBrowser and Q3DataView explicitly states which calls take
    ownership of the cursor.
*/

/*!
    \enum Q3SqlCursor::Mode

    This enum type describes how Q3SqlCursor operates on records in the
    database.

    \value ReadOnly  the cursor can only SELECT records from the
    database.

    \value Insert  the cursor can INSERT records into the database.

    \value Update  the cursor can UPDATE records in the database.

    \value Delete  the cursor can DELETE records from the database.

    \value Writable  the cursor can INSERT, UPDATE and DELETE records
    in the database.
*/

/*!
    \fn QVariant Q3SqlCursor::value(const QString &name) const

    \overload

    Returns the value of the field named \a name.
*/

/*!
    \fn void Q3SqlCursor::setValue(const QString &name, const QVariant &val)

    \overload

    Sets the value for the field named \a name to \a val.
*/

/*!
    Constructs a cursor on database \a db using table or view \a name.

    If \a autopopulate is true (the default), the \a name of the
    cursor must correspond to an existing table or view name in the
    database so that field information can be automatically created.
    If the table or view does not exist, the cursor will not be
    functional.

    The cursor is created with an initial mode of Q3SqlCursor::Writable
    (meaning that records can be inserted, updated or deleted using
    the cursor). If the cursor does not have a unique primary index,
    update and deletes cannot be performed.

    Note that \a autopopulate refers to populating the cursor with
    meta-data, e.g. the names of the table's fields, not with
    retrieving data. The select() function is used to populate the
    cursor with data.

    \sa setName() setMode()
*/

Q3SqlCursor::Q3SqlCursor(const QString & name, bool autopopulate, QSqlDatabase db)
    : QSqlRecord(), QSqlQuery(QString(), db)
{
    d = new Q3SqlCursorPrivate(name, db);
    setMode(Writable);
    if (!d->nm.isEmpty())
        setName(d->nm, autopopulate);
}

/*!
    Constructs a copy of \a other.
*/

Q3SqlCursor::Q3SqlCursor(const Q3SqlCursor & other)
    : QSqlRecord(other), QSqlQuery(other)
{
    d = new Q3SqlCursorPrivate(other.d->nm, other.d->db);
    d->lastAt = other.d->lastAt;
    d->nm = other.d->nm;
    d->srt = other.d->srt;
    d->ftr = other.d->ftr;
    d->priIndx = other.d->priIndx;
    d->editBuffer = other.d->editBuffer;
    d->infoBuffer = other.d->infoBuffer;
    d->q = 0; // do not share queries
    setMode(other.mode());
}

/*!
    Destroys the object and frees any allocated resources.
*/

Q3SqlCursor::~Q3SqlCursor()
{
    delete d;
}

/*!
    Sets the cursor equal to \a other.
*/

Q3SqlCursor& Q3SqlCursor::operator=(const Q3SqlCursor& other)
{
    QSqlRecord::operator=(other);
    QSqlQuery::operator=(other);
    delete d;
    d = new Q3SqlCursorPrivate(other.d->nm, other.d->db);
    d->lastAt = other.d->lastAt;
    d->nm = other.d->nm;
    d->srt = other.d->srt;
    d->ftr = other.d->ftr;
    d->priIndx = other.d->priIndx;
    d->editBuffer = other.d->editBuffer;
    d->infoBuffer = other.d->infoBuffer;
    d->q = 0; // do not share queries
    setMode(other.mode());
    return *this;
}

/*!
    Sets the current sort to \a sort. Note that no new records are
    selected. To select new records, use select(). The \a sort will
    apply to any subsequent select() calls that do not explicitly
    specify a sort.
*/

void Q3SqlCursor::setSort(const QSqlIndex& sort)
{
    d->srt = sort;
}

/*!
    Returns the current sort, or an empty index if there is no current
    sort.
*/
QSqlIndex Q3SqlCursor::sort() const
{
    return d->srt;
}

/*!
    Sets the current filter to \a filter. Note that no new records are
    selected. To select new records, use select(). The \a filter will
    apply to any subsequent select() calls that do not explicitly
    specify a filter.

    The filter is a SQL \c WHERE clause without the keyword 'WHERE',
    e.g. \c{name='Dave'} which will be processed by the DBMS.
*/
void Q3SqlCursor::setFilter(const QString& filter)
{
    d->ftr = filter;
}

/*!
    Returns the current filter, or an empty string if there is no
    current filter.
*/
QString Q3SqlCursor::filter() const
{
    return d->ftr;
}

/*!
    Sets the name of the cursor to \a name. If \a autopopulate is true
    (the default), the \a name must correspond to a valid table or
    view name in the database. Also, note that all references to the
    cursor edit buffer become invalidated when fields are
    auto-populated. See the Q3SqlCursor constructor documentation for
    more information.
*/
void Q3SqlCursor::setName(const QString& name, bool autopopulate)
{
    d->nm = name;
    if (autopopulate) {
        if (driver()) {
            d->infoBuffer = driver()->record(name);
            *this = d->infoBuffer.toRecord();
            d->editBuffer = *this;
            d->priIndx = driver()->primaryIndex(name);
        }
        if (isEmpty())
            qWarning("Q3SqlCursor::setName: unable to build record, does '%s' exist?", name.latin1());
    }
}

/*!
    Returns the name of the cursor.
*/

QString Q3SqlCursor::name() const
{
    return d->nm;
}

/*! \internal
*/

QString Q3SqlCursor::toString(const QString& prefix, const QString& sep) const
{
    QString pflist;
    QString pfix =  prefix.isEmpty() ? prefix : prefix + QLatin1Char('.');
    bool comma = false;

    for (int i = 0; i < count(); ++i) {
        const QString fname = fieldName(i);
        if (isGenerated(i)) {
            if(comma)
                pflist += sep + QLatin1Char(' ');
            pflist += pfix + driver()->escapeIdentifier(fname, QSqlDriver::FieldName);
            comma = true;
        }
    }
    return pflist;
}

/*!
  \internal

  Assigns the record \a list.

*/
QSqlRecord & Q3SqlCursor::operator=(const QSqlRecord & list)
{
    return QSqlRecord::operator=(list);
}

/*!
    Append a copy of field \a fieldInfo to the end of the cursor. Note
    that all references to the cursor edit buffer become invalidated.
*/

void Q3SqlCursor::append(const Q3SqlFieldInfo& fieldInfo)
{
    d->editBuffer.append(fieldInfo.toField());
    d->infoBuffer.append(fieldInfo);
    QSqlRecord::append(fieldInfo.toField());
}

/*!
    Removes all fields from the cursor. Note that all references to
    the cursor edit buffer become invalidated.
*/
void Q3SqlCursor::clear()
{
    d->editBuffer.clear();
    d->infoBuffer.clear();
    QSqlRecord::clear();
}


/*!
    Insert a copy of \a fieldInfo at position \a pos. If a field
    already exists at \a pos, it is removed. Note that all references
    to the cursor edit buffer become invalidated.
*/

void  Q3SqlCursor::insert(int pos, const Q3SqlFieldInfo& fieldInfo)
{
    d->editBuffer.replace(pos, fieldInfo.toField());
    d->infoBuffer[pos] = fieldInfo;
    QSqlRecord::replace(pos, fieldInfo.toField());
}

/*!
    Removes the field at \a pos. If \a pos does not exist, nothing
    happens. Note that all references to the cursor edit buffer become
    invalidated.
*/

void Q3SqlCursor::remove(int pos)
{
    d->editBuffer.remove(pos);
    d->infoBuffer[pos] = Q3SqlFieldInfo();
    QSqlRecord::remove(pos);
}

/*!
    Sets the generated flag for the field \a name to \a generated. If
    the field does not exist, nothing happens. Only fields that have
    \a generated set to true are included in the SQL that is
    generated by insert(), update() or del().
*/

void Q3SqlCursor::setGenerated(const QString& name, bool generated)
{
    int pos = indexOf(name);
    if (pos == -1)
        return;
    QSqlRecord::setGenerated(name, generated);
    d->editBuffer.setGenerated(name, generated);
    d->infoBuffer[pos].setGenerated(generated);
}

/*!
    \overload

    Sets the generated flag for the field \a i to \a generated.
*/
void Q3SqlCursor::setGenerated(int i, bool generated)
{
    if (i < 0 || i >= (int)d->infoBuffer.count())
        return;
    QSqlRecord::setGenerated(i, generated);
    d->editBuffer.setGenerated(i, generated);
    d->infoBuffer[i].setGenerated(generated);
}

/*!
    Returns the primary index associated with the cursor as defined in
    the database, or an empty index if there is no primary index. If
    \a setFromCursor is true (the default), the index fields are
    populated with the corresponding values in the cursor's current
    record.
*/

QSqlIndex Q3SqlCursor::primaryIndex(bool setFromCursor) const
{
    if (setFromCursor) {
        for (int i = 0; i < d->priIndx.count(); ++i) {
            const QString fn = d->priIndx.fieldName(i);
            if (contains(fn))
                d->priIndx.setValue(i, QSqlRecord::value(fn));
        }
    }
    return d->priIndx;
}

/*!
    Sets the primary index associated with the cursor to the index \a
    idx. Note that this index must contain a field or set of fields
    which identify a unique record within the underlying database
    table or view so that update() and del() will execute as expected.

    \sa update() del()
*/

void Q3SqlCursor::setPrimaryIndex(const QSqlIndex& idx)
{
    d->priIndx = idx;
}


/*!
    Returns an index composed of \a fieldNames, all in ASCending
    order. Note that all field names must exist in the cursor,
    otherwise an empty index is returned.

    \sa QSqlIndex
*/

QSqlIndex Q3SqlCursor::index(const QStringList& fieldNames) const
{
    QSqlIndex idx;
    for (QStringList::ConstIterator it = fieldNames.begin(); it != fieldNames.end(); ++it) {
        QSqlField f = field((*it));
        if (!f.isValid()) { /* all fields must exist */
            idx.clear();
            break;
        }
        idx.append(f);
    }
    return idx;
}

/*!
    \overload

    Returns an index based on \a fieldName.
*/

QSqlIndex Q3SqlCursor::index(const QString& fieldName) const
{
    QStringList fl(fieldName);
    return index(fl);
}

/*!
    Selects all fields in the cursor from the database matching the
    filter criteria \a filter. The data is returned in the order
    specified by the index \a sort. Returns true if the data was
    successfully selected; otherwise returns false.

    The \a filter is a string containing a SQL \c WHERE clause but
    without the 'WHERE' keyword. The cursor is initially positioned at
    an invalid row after this function is called. To move to a valid
    row, use seek(), first(), last(), previous() or next().

    Example:
    \snippet doc/src/snippets/code/src_qt3support_sql_q3sqlcursor.cpp 2

    The filter will apply to any subsequent select() calls that do not
    explicitly specify another filter. Similarly the sort will apply
    to any subsequent select() calls that do not explicitly specify
    another sort.

    \snippet doc/src/snippets/code/src_qt3support_sql_q3sqlcursor.cpp 3

*/

bool Q3SqlCursor::select(const QString & filter, const QSqlIndex & sort)
{
    QString fieldList(toString(d->nm));
    if (fieldList.isEmpty())
        return false;
    QString str(QLatin1String("select ") + fieldList);
    str += QLatin1String(" from ") + d->nm;
    if (!filter.isEmpty()) {
        d->ftr = filter;
        str += QLatin1String(" where ") + filter;
    } else
        d->ftr.clear();
    if (sort.count() > 0)
        str += QLatin1String(" order by ") + sort.toString(d->nm);
    d->srt = sort;
    return exec(str);
}

/*!
    \overload

    Selects all fields in the cursor from the database. The rows are
    returned in the order specified by the last call to setSort() or
    the last call to select() that specified a sort, whichever is the
    most recent. If there is no current sort, the order in which the
    rows are returned is undefined. The records are filtered according
    to the filter specified by the last call to setFilter() or the
    last call to select() that specified a filter, whichever is the
    most recent. If there is no current filter, all records are
    returned. The cursor is initially positioned at an invalid row. To
    move to a valid row, use seek(), first(), last(), previous() or
    next().

    \sa setSort() setFilter()
*/

bool Q3SqlCursor::select()
{
    return select(filter(), sort());
}

/*!
    \overload

    Selects all fields in the cursor from the database. The data is
    returned in the order specified by the index \a sort. The records
    are filtered according to the filter specified by the last call to
    setFilter() or the last call to select() that specified a filter,
    whichever is the most recent. The cursor is initially positioned
    at an invalid row. To move to a valid row, use seek(), first(),
    last(), previous() or next().
*/

bool Q3SqlCursor::select(const QSqlIndex& sort)
{
    return select(filter(), sort);
}

/*!
    \overload

    Selects all fields in the cursor matching the filter index \a
    filter. The data is returned in the order specified by the index
    \a sort. The \a filter index works by constructing a WHERE clause
    using the names of the fields from the \a filter and their values
    from the current cursor record. The cursor is initially positioned
    at an invalid row. To move to a valid row, use seek(), first(),
    last(), previous() or next(). This function is useful, for example,
    for retrieving data based upon a table's primary index:

    \snippet doc/src/snippets/code/src_qt3support_sql_q3sqlcursor.cpp 4

    In this example the QSqlIndex, pk, is used for two different
    purposes. When used as the filter (first) argument, the field
    names it contains are used to construct the WHERE clause, each set
    to the current cursor value, \c{WHERE id=10}, in this case. When
    used as the sort (second) argument the field names it contains are
    used for the ORDER BY clause, \c{ORDER BY id} in this example.
*/

bool Q3SqlCursor::select(const QSqlIndex & filter, const QSqlIndex & sort)
{
    return select(toString(filter, this, d->nm, QString(QLatin1Char('=')), QLatin1String("and")), sort);
}

/*!
    Sets the cursor mode to \a mode. This value can be an OR'ed
    combination of \l Q3SqlCursor::Mode values. The default mode for a
    cursor is Q3SqlCursor::Writable.

    \snippet doc/src/snippets/code/src_qt3support_sql_q3sqlcursor.cpp 5
*/

void Q3SqlCursor::setMode(int mode)
{
    d->md = mode;
}

/*!
    Returns the current cursor mode.

    \sa setMode()
*/

int Q3SqlCursor::mode() const
{
    return d->md;
}

/*!
    Sets field \a name to \a calculated. If the field \a name does not
    exist, nothing happens. The value of a calculated field is set by
    the calculateField() virtual function which you must reimplement
    (or the field value will be an invalid QVariant). Calculated
    fields do not appear in generated SQL statements sent to the
    database.

    \sa calculateField()
*/

void Q3SqlCursor::setCalculated(const QString& name, bool calculated)
{
    int pos = indexOf(name);
    if (pos < 0)
        return;
    d->infoBuffer[pos].setCalculated(calculated);
    if (calculated)
        setGenerated(pos, false);
}

/*!
    Returns true if the field \a name exists and is calculated;
    otherwise returns false.

    \sa setCalculated()
*/

bool Q3SqlCursor::isCalculated(const QString& name) const
{
    int pos = indexOf(name);
    if (pos < 0)
        return false;
    return d->infoBuffer[pos].isCalculated();
}

/*!
    Sets field \a{name}'s trimmed status to \a trim. If the field \a
    name does not exist, nothing happens.

    When a trimmed field of type string is read from the
    database any trailing (right-most) spaces are removed.

    \sa isTrimmed() QVariant
*/

void Q3SqlCursor::setTrimmed(const QString& name, bool trim)
{
    int pos = indexOf(name);
    if (pos < 0)
        return;
    d->infoBuffer[pos].setTrim(trim);
}

/*!
    Returns true if the field \a name exists and is trimmed; otherwise
    returns false.

    When a trimmed field of type string or cstring is read from the
    database any trailing (right-most) spaces are removed.

    \sa setTrimmed()
*/

bool Q3SqlCursor::isTrimmed(const QString& name) const
{
    int pos = indexOf(name);
    if (pos < 0)
        return false;
    return d->infoBuffer[pos].isTrim();
}

/*!
    Returns true if the cursor is read-only; otherwise returns false.
    The default is false. Read-only cursors cannot be edited using
    insert(), update() or del().

    \sa setMode()
*/

bool Q3SqlCursor::isReadOnly() const
{
    return d->md == 0;
}

/*!
    Returns true if the cursor will perform inserts; otherwise returns
    false.

    \sa setMode()
*/

bool Q3SqlCursor::canInsert() const
{
    return ((d->md & Insert) == Insert) ;
}


/*!
    Returns true if the cursor will perform updates; otherwise returns
    false.

    \sa setMode()
*/

bool Q3SqlCursor::canUpdate() const
{
    return ((d->md & Update) == Update) ;
}

/*!
    Returns true if the cursor will perform deletes; otherwise returns
    false.

    \sa setMode()
*/

bool Q3SqlCursor::canDelete() const
{
    return ((d->md & Delete) == Delete) ;
}

/*!
    \overload

    Returns a formatted string composed of the \a prefix (e.g. table
    or view name), ".", the \a field name, the \a fieldSep and the
    field value. If the \a prefix is empty then the string will begin
    with the \a field name. This function is useful for generating SQL
    statements.
*/

QString Q3SqlCursor::toString(const QString& prefix, QSqlField* field, const QString& fieldSep) const
{
    QString f;
    if (field && driver()) {
        f = (prefix.length() > 0 ? prefix + QLatin1Char('.') : QString()) + driver()->escapeIdentifier(field->name(), QSqlDriver::FieldName);
        f += QLatin1Char(' ') + fieldSep + QLatin1Char(' ');
        if (field->isNull()) {
            f += QLatin1String("NULL");
        } else {
            f += driver()->formatValue(field);
        }
    }
    return f;
}

/*!
    Returns a formatted string composed of all the fields in \a rec.
    Each field is composed of the \a prefix (e.g. table or view name),
    ".", the field name, the \a fieldSep and the field value. If the
    \a prefix is empty then each field will begin with the field name.
    The fields are then joined together separated by \a sep. Fields
    where isGenerated() returns false are not included. This function
    is useful for generating SQL statements.
*/

QString Q3SqlCursor::toString(QSqlRecord* rec, const QString& prefix, const QString& fieldSep,
                              const QString& sep) const
{
    static QString blank(QLatin1Char(' '));
    QString filter;
    bool separator = false;
    for (int j = 0; j < count(); ++j) {
        QSqlField f = rec->field(j);
        if (rec->isGenerated(j)) {
            if (separator)
                filter += sep + blank;
            filter += toString(prefix, &f, fieldSep);
            filter += blank;
            separator = true;
        }
    }
    return filter;
}

/*!
    \overload

    Returns a formatted string composed of all the fields in the index
    \a i. Each field is composed of the \a prefix (e.g. table or view
    name), ".", the field name, the \a fieldSep and the field value.
    If the \a prefix is empty then each field will begin with the field
    name. The field values are taken from \a rec. The fields are then
    joined together separated by \a sep. Fields where isGenerated()
    returns false are ignored. This function is useful for generating
    SQL statements.
*/

QString Q3SqlCursor::toString(const QSqlIndex& i, QSqlRecord* rec, const QString& prefix,
                                const QString& fieldSep, const QString& sep) const
{
    QString filter;
    bool separator = false;
    for(int j = 0; j < i.count(); ++j){
        if (rec->isGenerated(j)) {
            if(separator) {
                filter += QLatin1Char(' ') + sep + QLatin1Char(' ') ;
            }
            QString fn = i.fieldName(j);
            QSqlField f = rec->field(fn);
            filter += toString(prefix, &f, fieldSep);
            separator = true;
        }
    }
    return filter;
}

/*!
    Inserts the current contents of the cursor's edit record buffer
    into the database, if the cursor allows inserts. Returns the
    number of rows affected by the insert. For error information, use
    lastError().

    If \a invalidate is true (the default), the cursor will no longer
    be positioned on a valid record and can no longer be navigated. A
    new select() call must be made before navigating to a valid
    record.

    \snippet doc/src/snippets/code/src_qt3support_sql_q3sqlcursor.cpp 6

    In the above example, a cursor is created on the 'prices' table
    and a pointer to the insert buffer is acquired using primeInsert().
    Each field's value is set to the desired value and then insert()
    is called to insert the data into the database. Remember: all edit
    operations (insert(), update() and delete()) operate on the
    contents of the cursor edit buffer and not on the contents of the
    cursor itself.

    \sa setMode() lastError()
*/

int Q3SqlCursor::insert(bool invalidate)
{
    if ((d->md & Insert) != Insert || !driver())
        return false;
    int k = d->editBuffer.count();
    if (k == 0)
        return 0;

    QString fList;
    QString vList;
    bool comma = false;
    // use a prepared query if the driver supports it
    if (driver()->hasFeature(QSqlDriver::PreparedQueries)) {
        int cnt = 0;
        bool oraStyle = driver()->hasFeature(QSqlDriver::NamedPlaceholders);
        for(int j = 0; j < k; ++j) {
            QSqlField f = d->editBuffer.field(j);
            if (d->editBuffer.isGenerated(j)) {
                if (comma) {
                    fList += QLatin1Char(',');
                    vList += QLatin1Char(',');
                }
                fList += driver()->escapeIdentifier(f.name(), QSqlDriver::FieldName);
                vList += (oraStyle == true) ? QLatin1String(":f") + QString::number(cnt) : QString(QLatin1Char('?'));
                cnt++;
                comma = true;
            }
        }
        if (!comma) {
            return 0;
        }
        QString str;
        str.append(QLatin1String("insert into ")).append(name())
           .append(QLatin1String(" (")).append(fList)
           .append(QLatin1String(") values (")).append(vList). append(QLatin1Char(')'));

        return applyPrepared(str, invalidate);
    } else {
        for(int j = 0; j < k; ++j) {
            QSqlField f = d->editBuffer.field(j);
            if (d->editBuffer.isGenerated(j)) {
                if (comma) {
                    fList += QLatin1Char(',');
                    vList += QLatin1Char(',');
                }
                fList += driver()->escapeIdentifier(f.name(), QSqlDriver::FieldName);
                vList += driver()->formatValue(&f);
                comma = true;
            }
        }

        if (!comma) {
            // no valid fields found
            return 0;
        }
        QString str;
        str.append(QLatin1String("insert into ")).append(name()).append(QLatin1String(" ("))
           .append(fList).append(QLatin1String(") values (")).append(vList). append (QLatin1String(")"));
        return apply(str, invalidate);
    }
}

/*!
    Returns the current internal edit buffer. If \a copy is true (the
    default is false), the current cursor field values are first
    copied into the edit buffer. The edit buffer is valid as long as
    the cursor remains valid. The cursor retains ownership of the
    returned pointer, so it must not be deleted or modified.

    \sa primeInsert(), primeUpdate() primeDelete()
*/

QSqlRecord* Q3SqlCursor::editBuffer(bool copy)
{
    sync();
    if (copy) {
        for(int i = 0; i < d->editBuffer.count(); i++) {
            if (QSqlRecord::isNull(i)) {
                d->editBuffer.setNull(i);
            } else {
                d->editBuffer.setValue(i, value(i));
            }
        }
    }
    return &d->editBuffer;
}

/*!
    This function primes the edit buffer's field values for update and
    returns the edit buffer. The default implementation copies the
    field values from the current cursor record into the edit buffer
    (therefore, this function is equivalent to calling editBuffer(
    true)). The cursor retains ownership of the returned pointer, so
    it must not be deleted or modified.

    \sa editBuffer() update()
*/

QSqlRecord* Q3SqlCursor::primeUpdate()
{
    // memorize the primary keys as they were before the user changed the values in editBuffer
    QSqlRecord* buf = editBuffer(true);
    QSqlIndex idx = primaryIndex(false);
    if (!idx.isEmpty())
        d->editIndex = toString(idx, buf, d->nm, QString(QLatin1Char('=')), QLatin1String("and"));
    else
        d->editIndex = qWhereClause(buf, d->nm, QLatin1String("and"), driver());
    return buf;
}

/*!
    This function primes the edit buffer's field values for delete and
    returns the edit buffer. The default implementation copies the
    field values from the current cursor record into the edit buffer
    (therefore, this function is equivalent to calling editBuffer(
    true)). The cursor retains ownership of the returned pointer, so
    it must not be deleted or modified.

    \sa editBuffer() del()
*/

QSqlRecord* Q3SqlCursor::primeDelete()
{
    return editBuffer(true);
}

/*!
    This function primes the edit buffer's field values for insert and
    returns the edit buffer. The default implementation clears all
    field values in the edit buffer. The cursor retains ownership of
    the returned pointer, so it must not be deleted or modified.

    \sa editBuffer() insert()
*/

QSqlRecord* Q3SqlCursor::primeInsert()
{
    d->editBuffer.clearValues();
    return &d->editBuffer;
}


/*!
    Updates the database with the current contents of the edit buffer.
    Returns the number of records which were updated.
    For error information, use lastError().

    Only records which meet the filter criteria specified by the
    cursor's primary index are updated. If the cursor does not contain
    a primary index, no update is performed and 0 is returned.

    If \a invalidate is true (the default), the current cursor can no
    longer be navigated. A new select() call must be made before you
    can move to a valid record. For example:

    \snippet doc/src/snippets/code/src_qt3support_sql_q3sqlcursor.cpp 7

    In the above example, a cursor is created on the 'prices' table
    and is positioned on the record to be updated. Then a pointer to
    the cursor's edit buffer is acquired using primeUpdate(). A new
    value is calculated and placed into the edit buffer with the
    setValue() call. Finally, an update() call is made on the cursor
    which uses the tables's primary index to update the record in the
    database with the contents of the cursor's edit buffer. Remember:
    all edit operations (insert(), update() and delete()) operate on
    the contents of the cursor edit buffer and not on the contents of
    the cursor itself.

    Note that if the primary index does not uniquely distinguish
    records the database may be changed into an inconsistent state.

    \sa setMode() lastError()
*/

int Q3SqlCursor::update(bool invalidate)
{
    if (d->editIndex.isEmpty())
        return 0;
    return update(d->editIndex, invalidate);
}

/*!
    \overload

    Updates the database with the current contents of the cursor edit
    buffer using the specified \a filter. Returns the number of
    records which were updated.
    For error information, use lastError().

    Only records which meet the filter criteria are updated, otherwise
    all records in the table are updated.

    If \a invalidate is true (the default), the cursor can no longer
    be navigated. A new select() call must be made before you can move
    to a valid record.

    \sa primeUpdate() setMode() lastError()
*/

int Q3SqlCursor::update(const QString & filter, bool invalidate)
{
    if ((d->md & Update) != Update) {
        return false;
    }
    int k = count();
    if (k == 0) {
        return 0;
    }
    
    // use a prepared query if the driver supports it
    if (driver()->hasFeature(QSqlDriver::PreparedQueries)) {
        QString fList;
        bool comma = false;
        int cnt = 0;
        bool oraStyle = driver()->hasFeature(QSqlDriver::NamedPlaceholders);
        for(int j = 0; j < k; ++j) {
            QSqlField f = d->editBuffer.field(j);
            if (d->editBuffer.isGenerated(j)) {
                if (comma) {
                    fList += QLatin1Char(',');
                }
                fList += f.name() + QLatin1String(" = ") + (oraStyle == true ? QLatin1String(":f") + QString::number(cnt) : QString(QLatin1Char('?')));
                cnt++;
                comma = true;
            }
        }
        if (!comma) {
            return 0;
        }
        QString str(QLatin1String("update ") + name() + QLatin1String(" set ") + fList);
        if (filter.length()) {
            str+= QLatin1String(" where ") + filter;
        }
        return applyPrepared(str, invalidate);
    } else {
        QString str = QLatin1String("update ") + name();
        str += QLatin1String(" set ") + toString(&d->editBuffer, QString(), QString(QLatin1Char('=')), QString(QLatin1Char(',')));
        if (filter.length()) {
            str+= QLatin1String(" where ") + filter;
        }
        return apply(str, invalidate);
    }
}

/*!
    Deletes a record from the database using the cursor's primary
    index and the contents of the cursor edit buffer. Returns the
    number of records which were deleted.
    For error information, use lastError().

    Only records which meet the filter criteria specified by the
    cursor's primary index are deleted. If the cursor does not contain
    a primary index, no delete is performed and 0 is returned. If \a
    invalidate is true (the default), the current cursor can no longer
    be navigated. A new select() call must be made before you can move
    to a valid record. For example:

    \snippet doc/src/snippets/code/src_qt3support_sql_q3sqlcursor.cpp 8

    In the above example, a cursor is created on the 'prices' table
    and positioned to the record to be deleted. First primeDelete() is
    called to populate the edit buffer with the current cursor values,
    e.g. with an id of 999, and then del() is called to actually
    delete the record from the database. Remember: all edit operations
    (insert(), update() and delete()) operate on the contents of the
    cursor edit buffer and not on the contents of the cursor itself.

    \sa primeDelete() setMode() lastError()
*/

int Q3SqlCursor::del(bool invalidate)
{
    QSqlIndex idx = primaryIndex(false);
    if (idx.isEmpty())
        return del(qWhereClause(&d->editBuffer, d->nm, QLatin1String("and"), driver()), invalidate);
    return del(toString(primaryIndex(), &d->editBuffer, d->nm, QString(QLatin1Char('=')), QLatin1String("and")), invalidate);
}

/*!
    \overload

    Deletes the current cursor record from the database using the
    filter \a filter. Only records which meet the filter criteria are
    deleted. Returns the number of records which were deleted. If \a
    invalidate is true (the default), the current cursor can no longer
    be navigated. A new select() call must be made before you can move
    to a valid record. For error information, use lastError().

    The \a filter is an SQL \c WHERE clause, e.g. \c{id=500}.

    \sa setMode() lastError()
*/

int Q3SqlCursor::del(const QString & filter, bool invalidate)
{
    if ((d->md & Delete) != Delete)
        return 0;
    int k = count();
    if(k == 0) return 0;
    QString str = QLatin1String("delete from ") + name();
    if (filter.length())
        str+= QLatin1String(" where ") + filter;
    return apply(str, invalidate);
}

/*
  \internal
*/

int Q3SqlCursor::apply(const QString& q, bool invalidate)
{
    int ar = 0;
    if (invalidate) {
        if (exec(q))
            ar = numRowsAffected();
    } else if (driver()) {
        QSqlQuery* sql = d->query();
        if (sql && sql->exec(q))
            ar = sql->numRowsAffected();
    }
    return ar;
}

/*
  \internal
*/

int Q3SqlCursor::applyPrepared(const QString& q, bool invalidate)
{
    int ar = 0;
    QSqlQuery* sql = 0;

    if (invalidate) {
        sql = (QSqlQuery*)this;
        d->lastAt = QSql::BeforeFirst;
    } else {
        sql = d->query();
    }
    if (!sql)
        return 0;

    if (invalidate || sql->lastQuery() != q) {
        if (!sql->prepare(q))
            return 0;
    }

    int cnt = 0;
    int fieldCount = (int)count();
    for (int j = 0; j < fieldCount; ++j) {
        const QSqlField f = d->editBuffer.field(j);
        if (d->editBuffer.isGenerated(j)) {
            if (f.type() == QVariant::ByteArray)
                sql->bindValue(cnt, f.value(), QSql::In | QSql::Binary);
            else
                sql->bindValue(cnt, f.value());
            cnt++;
        }
    }
    if (sql->exec()) {
        ar = sql->numRowsAffected();
    }
    return ar;
}

/*!
  Executes the SQL query \a sql. Returns true of the cursor is
  active, otherwise returns false.
*/
bool Q3SqlCursor::exec(const QString & sql)
{
    d->lastAt = QSql::BeforeFirst;
    QSqlQuery::exec(sql);
    return isActive();
}

/*!
    Protected virtual function which is called whenever a field needs
    to be calculated. If calculated fields are being used, derived
    classes must reimplement this function and return the appropriate
    value for field \a name. The default implementation returns an
    invalid QVariant.

    \sa setCalculated()
*/

QVariant Q3SqlCursor::calculateField(const QString&)
{
    return QVariant();
}

/*! \internal
   Ensure fieldlist is synced with query.

*/

static QString qTrim(const QString& s)
{
    QString result = s;
    int end = result.length() - 1;
    while (end >= 0 && result[end].isSpace()) // skip white space from end
        end--;
    result.truncate(end + 1);
    return result;
}

/*! \internal
 */

void Q3SqlCursor::sync()
{
    if (isActive() && isValid() && d->lastAt != at()) {
        d->lastAt = at();
        int i = 0;
        int j = 0;
        bool haveCalculatedFields = false;
        for (; i < count(); ++i) {
            if (!haveCalculatedFields && d->infoBuffer[i].isCalculated()) {
                haveCalculatedFields = true;
            }
            if (QSqlRecord::isGenerated(i)) {
                QVariant v = QSqlQuery::value(j);
                if ((v.type() == QVariant::String) &&
                        d->infoBuffer[i].isTrim()) {
                    v = qTrim(v.toString());
                }
                QSqlRecord::setValue(i, v);
                if (QSqlQuery::isNull(j))
                    QSqlRecord::field(i).clear();
                j++;
            }
        }
        if (haveCalculatedFields) {
            for (i = 0; i < count(); ++i) {
                if (d->infoBuffer[i].isCalculated())
                    QSqlRecord::setValue(i, calculateField(fieldName(i)));
            }
        }
    }
}

/*!
    Returns the value of field number \a i.
*/

QVariant Q3SqlCursor::value(int i) const
{
    const_cast<Q3SqlCursor *>(this)->sync();
    return QSqlRecord::value(i);
}

/*! \internal
  cursors should be filled with Q3SqlFieldInfos...
*/
void Q3SqlCursor::append(const QSqlField& field)
{
    append(Q3SqlFieldInfo(field));
}

/*!
    Returns true if the field \a i is NULL or if there is no field at
    position \a i; otherwise returns false.

    This is the same as calling QSqlRecord::isNull(\a i)
*/
bool Q3SqlCursor::isNull(int i) const
{
    const_cast<Q3SqlCursor *>(this)->sync();
    return QSqlRecord::isNull(i);
}
/*!
    \overload

    Returns true if the field called \a name is NULL or if there is no
    field called \a name; otherwise returns false.

    This is the same as calling QSqlRecord::isNull(\a name)
*/
bool Q3SqlCursor::isNull(const QString& name) const
{
    const_cast<Q3SqlCursor *>(this)->sync();
    return QSqlRecord::isNull(name);
}

/*! \internal */
void Q3SqlCursor::setValue(int i, const QVariant& val)
{
    sync();
#ifdef QT_DEBUG
    qDebug("Q3SqlCursor::setValue(): This will not affect actual database values. Use primeInsert(), primeUpdate() or primeDelete().");
#endif
    QSqlRecord::setValue(i, val);
}

/*! \internal */
bool Q3SqlCursor::seek(int i, bool relative)
{
    bool res = QSqlQuery::seek(i, relative);
    sync();
    return res;
}

/*! \internal */
bool Q3SqlCursor::next()
{
    bool res = QSqlQuery::next();
    sync();
    return res;
}

/*!
    \fn Q3SqlCursor::previous()

    \internal
*/

/*! \internal */
bool Q3SqlCursor::prev()
{
    bool res = QSqlQuery::previous();
    sync();
    return res;
}

/*! \internal */
bool Q3SqlCursor::first()
{
    bool res = QSqlQuery::first();
    sync();
    return res;
}

/*! \internal */
bool Q3SqlCursor::last()
{
    bool res = QSqlQuery::last();
    sync();
    return res;
}

QT_END_NAMESPACE

#endif
