⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 q3sqlmanager_p.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************** 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 "q3sqlmanager_p.h"#ifndef QT_NO_SQL#include "qapplication.h"#include "qcursor.h"#include "qwidget.h"#include "q3sqlcursor.h"#include "qsqlfield.h"#include "q3sqlform.h"#include "qsqldriver.h"#include "qstring.h"#include "qmessagebox.h"#include "qbitarray.h"//#define QT_DEBUG_DATAMANAGERclass Q3SqlCursorManagerPrivate{public:    Q3SqlCursorManagerPrivate()        : cur(0), autoDelete(false)    {}    QString ftr;    QStringList srt;    Q3SqlCursor* cur;    bool autoDelete;};static QSqlIndex indexFromStringList(const QStringList& l, const Q3SqlCursor* cursor){    QSqlIndex newSort;    for (int i = 0; i < l.count(); ++i) {        QString f = l[i];        bool desc = false;        if (f.mid(f.length()-3) == QLatin1String("ASC"))            f = f.mid(0, f.length()-3);        if (f.mid(f.length()-4) == QLatin1String("DESC")) {            desc = true;            f = f.mid(0, f.length()-4);        }        int dot = f.lastIndexOf(QLatin1Char('.'));        if (dot != -1)            f = f.mid(dot+1);        const QSqlField field = cursor->field(f.trimmed());        if (field.isValid())            newSort.append(field, desc);        else            qWarning("QSqlIndex::indexFromStringList: unknown field: '%s'", f.latin1());    }    return newSort;}/*!  \class Q3SqlCursorManager qsqlmanager_p.h  \brief The Q3SqlCursorManager class manages a database cursor.  \compat  \internal  This class provides common cursor management functionality.  This  includes saving and applying sorts and filters, refreshing (i.e.,  re-selecting) the cursor and searching for records within the  cursor.*//*!  \internal  Constructs a cursor manager.*/Q3SqlCursorManager::Q3SqlCursorManager(){    d = new Q3SqlCursorManagerPrivate;}/*! \internal  Destroys the object and frees any allocated resources.*/Q3SqlCursorManager::~Q3SqlCursorManager(){    if (d->autoDelete)        delete d->cur;    delete d;}/*! \internal  Sets the manager's sort to the index \a sort.  To apply the new  sort, use refresh(). */void Q3SqlCursorManager::setSort(const QSqlIndex& sort){    setSort(sort.toStringList());}/*! \internal  Sets the manager's sort to the stringlist \a sort.  To apply the  new sort, use refresh(). */void Q3SqlCursorManager::setSort(const QStringList& sort){    d->srt = sort;}/*! \internal  Returns the current sort, or an empty stringlist if there is none.*/QStringList  Q3SqlCursorManager::sort() const{    return d->srt;}/*! \internal  Sets the manager's filter to the string \a filter.  To apply the  new filter, use refresh().*/void Q3SqlCursorManager::setFilter(const QString& filter){    d->ftr = filter;}/*! \internal  Returns the current filter, or an empty string if there is none.*/QString Q3SqlCursorManager::filter() const{    return d->ftr;}/*! \internal  Sets auto-delete to \a enable.  If true, the default cursor will  be deleted when necessary.  \sa autoDelete()*/void Q3SqlCursorManager::setAutoDelete(bool enable){    d->autoDelete = enable;}/*! \internal  Returns true if auto-deletion is enabled, otherwise false.  \sa setAutoDelete()*/bool Q3SqlCursorManager::autoDelete() const{    return d->autoDelete;}/*! \internal  Sets the default cursor used by the manager to \a cursor.  If \a  autoDelete is true (the default is false), the manager takes  ownership of the \a cursor pointer, which will be deleted when the  manager is destroyed, or when setCursor() is called again. To  activate the \a cursor use refresh().  \sa cursor()*/void Q3SqlCursorManager::setCursor(Q3SqlCursor* cursor, bool autoDelete){    if (d->autoDelete)        delete d->cur;    d->cur = cursor;    d->autoDelete = autoDelete;}/*! \internal  Returns a pointer to the default cursor used for navigation, or 0  if there is no default cursor.  \sa setCursor()*/Q3SqlCursor* Q3SqlCursorManager::cursor() const{    return d->cur;}/*! \internal  Refreshes the manager using the default cursor.  The manager's  filter and sort are applied.  Returns true on success, false if an  error occurred or there is no current cursor.  \sa setFilter() setSort()*/bool Q3SqlCursorManager::refresh(){    Q3SqlCursor* cur = cursor();    if (!cur)        return false;    QString currentFilter = d->ftr;    QStringList currentSort = d->srt;    QSqlIndex newSort = indexFromStringList(currentSort, cur);    return cur->select(currentFilter, newSort);}/* \internal   Returns true if the \a buf field values that correspond to \a idx   match the field values in \a cur that correspond to \a idx.*/static bool index_matches(const Q3SqlCursor* cur, const QSqlRecord* buf,                           const QSqlIndex& idx){    bool indexEquals = false;    for (int i = 0; i < idx.count(); ++i) {        const QString fn(idx.field(i).name());        if (cur->value(fn) == buf->value(fn))            indexEquals = true;        else {            indexEquals = false;            break;        }    }    return indexEquals;}/*  Return less than, equal to or greater than 0 if buf1 is less than,  equal to or greater than buf2 according to fields described in idx.  (### Currently only uses first field.)*/static int compare_recs(const QSqlRecord* buf1, const QSqlRecord* buf2,                         const QSqlIndex& idx){    int cmp = 0;    int i = 0;    const QString fn(idx.field(i).name());    const QSqlField f1 = buf1->field(fn);    if (f1.isValid()) {        switch (f1.type()) { // ### more types?        case QVariant::String:            cmp = f1.value().toString().trimmed().compare(                          buf2->value(fn).toString().trimmed());            break;        default:            if (f1.value().toDouble() < buf2->value(fn).toDouble())                cmp = -1;            else if (f1.value().toDouble() > buf2->value(fn).toDouble())                cmp = 1;        }    }    if (idx.isDescending(i))        cmp = -cmp;    return cmp;}#ifdef QT_DEBUG_DATAMANAGERstatic void debug_datamanager_buffer(const QString& msg, QSqlRecord* cursor){    qDebug("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");    qDebug("%s", msg.latin1());    for (int j = 0; j < cursor->count(); ++j) {        qDebug("%s", (cursor->field(j)->name() + " type:"                       + QString(cursor->field(j)->value().typeName())                       + " value:" + cursor->field(j)->value().toString())                       .latin1());    }}#endif/*! \internal  Relocates the default cursor to the record matching the cursor'sedit buffer.  Only the field names specified by \a idx are used todetermine an exact match of the cursor to the edit buffer. However,other fields in the edit buffer are also used during the search,therefore all fields in the edit buffer should be primed with desiredvalues for the record being sought.  This function is typically usedto relocate a cursor to the correct position after an insert orupdate.  For example:\code    Q3SqlCursor* myCursor = myManager.cursor();    ...    QSqlRecord* buf = myCursor->primeUpdate();    buf->setValue("name", "Ola");    buf->setValue("city", "Oslo");    ...    myCursor->update();  // update current record    myCursor->select();  // refresh the cursor    myManager.findBuffer(myCursor->primaryIndex()); // go to the updated record\endcode*///## possibly add sizeHint parameterbool Q3SqlCursorManager::findBuffer(const QSqlIndex& idx, int atHint){#ifdef QT_DEBUG_DATAMANAGER    qDebug("Q3SqlCursorManager::findBuffer:");#endif    Q3SqlCursor* cur = cursor();    if (!cur)        return false;    if (!cur->isActive())        return false;    if (!idx.count()) {        if (cur->at() == QSql::BeforeFirst)            cur->next();        return false;    }    QSqlRecord* buf = cur->editBuffer();    bool indexEquals = false;#ifdef QT_DEBUG_DATAMANAGER    qDebug(" Checking hint...");#endif    /* check the hint */    if (cur->seek(atHint))        indexEquals = index_matches(cur, buf, idx);    if (!indexEquals) {#ifdef QT_DEBUG_DATAMANAGER        qDebug(" Checking current page...");#endif        /* check current page */        int pageSize = 20;        int startIdx = qMax(atHint - pageSize, 0);        int endIdx = atHint + pageSize;        for (int j = startIdx; j <= endIdx; ++j) {            if (cur->seek(j)) {                indexEquals = index_matches(cur, buf, idx);                if (indexEquals)                    break;            }        }    }    if (!indexEquals && cur->driver()->hasFeature(QSqlDriver::QuerySize)         && cur->sort().count()) {#ifdef QT_DEBUG_DATAMANAGER        qDebug(" Using binary search...");#endif        // binary search based on record buffer and current sort fields        int lo = 0;        int hi = cur->size();        int mid;        if (compare_recs(buf, cur, cur->sort()) >= 0)            lo = cur->at();        while (lo != hi) {            mid = lo + (hi - lo) / 2;            if (!cur->seek(mid))                break;            if (index_matches(cur, buf, idx)) {                indexEquals = true;                break;            }            int c = compare_recs(buf, cur, cur->sort());            if (c < 0) {                hi = mid;            } else if (c == 0) {                // found it, but there may be duplicates                int at = mid;                do {                    mid--;                    if (!cur->seek(mid))                        break;                    if (index_matches(cur, buf, idx)) {                        indexEquals = true;                        break;                    }                } while (compare_recs(buf, cur, cur->sort()) == 0);                if (!indexEquals) {                    mid = at;                    do {                        mid++;                        if (!cur->seek(mid))                            break;                        if (index_matches(cur, buf, idx)) {                            indexEquals = true;                            break;                        }                    } while (compare_recs(buf, cur, cur->sort()) == 0);                }                break;            } else if (c > 0) {                lo = mid + 1;            }        }    }    if (!indexEquals) {#ifdef QT_DEBUG_DATAMANAGER        qDebug(" Using brute search...");#endif#ifndef QT_NO_CURSOR        QApplication::setOverrideCursor(Qt::WaitCursor);#endif        /* give up, use brute force */        int startIdx = 0;        if (cur->at() != startIdx) {            cur->seek(startIdx);        }        for (;;) {            indexEquals = false;            indexEquals = index_matches(cur, buf, idx);            if (indexEquals)                break;            if (!cur->next())                break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -