📄 q3sqlcursor.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the Qt3Support module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.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 GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#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"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 q3sqlcursor.h \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: \code Q3SqlCursor cur( "staff" ); // Specify the table/view name cur.select(); // We'll retrieve every record while ( cur.next() ) { qDebug( cur.value( "id" ).toString() + ": " + cur.value( "surname" ).toString() + " " + cur.value( "salary" ).toString() ); } \endcode 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: \code Q3SqlCursor cur( "prices" ); cur.select( "id=202" ); if ( cur.next() ) { QSqlRecord *buffer = cur.primeUpdate(); double price = buffer->value( "price" ).toDouble(); double newprice = price * 1.05; buffer->setValue( "price", newprice ); cur.update(); } \endcode 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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -