示例#1
0
/*!
  Prepares the SQL query \a query for execution. Returns true if the
  query is prepared successfully; otherwise returns false.

  The query may contain placeholders for binding values. Both Oracle
  style colon-name (e.g., \c{:surname}), and ODBC style (\c{?})
  placeholders are supported; but they cannot be mixed in the same
  query. See the \l{QSqlQuery examples}{Detailed Description} for
  examples.

  Portability note: Some databases choose to delay preparing a query
  until it is executed the first time. In this case, preparing a
  syntactically wrong query succeeds, but every consecutive exec()
  will fail.

  For SQLite, the query string can contain only one statement at a time.
  If more than one statement is given, the function returns false.

  Example:

  \snippet sqldatabase/sqldatabase.cpp 9

  \sa exec(), bindValue(), addBindValue()
*/
bool QSqlQuery::prepare(const QString& query)
{
    if (d->ref.load() != 1) {
        bool fo = isForwardOnly();
        *this = QSqlQuery(driver()->createResult());
        setForwardOnly(fo);
        d->sqlResult->setNumericalPrecisionPolicy(d->sqlResult->numericalPrecisionPolicy());
    } else {
        d->sqlResult->setActive(false);
        d->sqlResult->setLastError(QSqlError());
        d->sqlResult->setAt(QSql::BeforeFirstRow);
        d->sqlResult->setNumericalPrecisionPolicy(d->sqlResult->numericalPrecisionPolicy());
    }
    if (!driver()) {
        qWarning("QSqlQuery::prepare: no driver");
        return false;
    }
    if (!driver()->isOpen() || driver()->isOpenError()) {
        qWarning("QSqlQuery::prepare: database not open");
        return false;
    }
    if (query.isEmpty()) {
        qWarning("QSqlQuery::prepare: empty query");
        return false;
    }
#ifdef QT_DEBUG_SQL
    qDebug("\n QSqlQuery::prepare: %s", query.toLocal8Bit().constData());
#endif
    return d->sqlResult->savePrepare(query);
}
示例#2
0
bool embeddedResult::fetchLast()
{
    if(!d->driver)
        return false;
    if (isForwardOnly()) { // fake this since MySQL can't seek on forward only queries
        bool success = fetchNext(); // did we move at all?
        while (fetchNext()) {};
        return success;
    }

    my_ulonglong numRows;
    if (d->preparedQuery) {
#if MYSQL_VERSION_ID >= 40108
        numRows = mysql_stmt_num_rows(d->stmt);
#else
        numRows = 0;
#endif
    } else {
        numRows = mysql_num_rows(d->result);
    }
    if (at() == int(numRows))
        return true;
    if (!numRows)
        return false;
    return fetch(numRows - 1);
}
示例#3
0
bool QSqlQuery::prev()
{
    if ( !isSelect() || !isActive() )
	return FALSE;
    if ( isForwardOnly() ) {
#ifdef QT_CHECK_RANGE
	qWarning("QSqlQuery::seek: cannot seek backwards in a forward only query" );
#endif
	return FALSE;
    }

    beforeSeek();
    checkDetach();
    bool b = FALSE;
    switch ( at() ) {
    case QSql::BeforeFirst:
	afterSeek();
	return FALSE;
    case QSql::AfterLast:
	b = d->sqlResult->fetchLast();
	afterSeek();
	return b;
    default:
	if ( !d->sqlResult->fetchPrev() ) {
	    d->sqlResult->setAt( QSql::BeforeFirst );
	    afterSeek();
	    return FALSE;
	}
	afterSeek();
	return TRUE;
    }
}
示例#4
0
bool embeddedResult::fetchFirst()
{
    if (at() == 0)
        return true;

    if (isForwardOnly())
        return (at() == QSql::BeforeFirstRow) ? fetchNext() : false;
    return fetch(0);
}
示例#5
0
/*!
  Retrieves the first record in the result, if available, and
  positions the query on the retrieved record. Note that the result
  must be in the \l{isActive()}{active} state and isSelect() must
  return true before calling this function or it will do nothing and
  return false.  Returns true if successful. If unsuccessful the query
  position is set to an invalid position and false is returned.

  \sa next(), previous(), last(), seek(), at(), isActive(), isValid()
 */
bool QSqlQuery::first()
{
    if (!isSelect() || !isActive())
        return false;
    if (isForwardOnly() && at() > QSql::BeforeFirstRow) {
        qWarning("QSqlQuery::seek: cannot seek backwards in a forward only query");
        return false;
    }
    bool b = false;
    b = d->sqlResult->fetchFirst();
    return b;
}
示例#6
0
bool QMYSQLResult::fetchLast()
{
    if ( isForwardOnly() ) { // fake this since MySQL can't seek on forward only queries
	bool success = fetchNext(); // did we move at all?
	while ( fetchNext() );
	return success;
    }
    my_ulonglong numRows = mysql_num_rows( d->result );
    if ( !numRows )
	return FALSE;
    return fetch( numRows - 1 );
}
示例#7
0
bool QSqlQuery::first()
{
    if ( !isSelect() || !isActive() )
	return FALSE;
    if ( isForwardOnly() && at() > QSql::BeforeFirst ) {
#ifdef QT_CHECK_RANGE
	qWarning("QSqlQuery::seek: cannot seek backwards in a forward only query" );
#endif
	return FALSE;
    }
    beforeSeek();
    checkDetach();
    bool b = FALSE;
    b = d->sqlResult->fetchFirst();
    afterSeek();
    return b;
}
bool ZSqliteCipherCachedResult::cacheNext()
{
    if (d->atEnd)
        return false;

    if(isForwardOnly()) {
        d->cache.clear();
        d->cache.resize(d->colCount);
    }

    if (!gotoNext(d->cache, d->nextIndex())) {
        d->revertLast();
        d->atEnd = true;
        return false;
    }
    setAt(at() + 1);
    return true;
}
示例#9
0
bool embeddedResult::fetch(int i)
{
    if(!d->driver)
        return false;
    if (isForwardOnly()) { // fake a forward seek
        if (at() < i) {
            int x = i - at();
            while (--x && fetchNext()) {};
            return fetchNext();
        } else {
            return false;
        }
    }
    if (at() == i)
        return true;
    if (d->preparedQuery) {
#if MYSQL_VERSION_ID >= 40108
        mysql_stmt_data_seek(d->stmt, i);

        int nRC = mysql_stmt_fetch(d->stmt);
        if (nRC) {
#ifdef MYSQL_DATA_TRUNCATED
            if (nRC == 1 || nRC == MYSQL_DATA_TRUNCATED)
#else
            if (nRC == 1)
#endif
                setLastError(qMakeStmtError(QCoreApplication::translate("embeddedResult",
                         "Unable to fetch data"), QSqlError::StatementError, d->stmt));
            return false;
        }
#else
        return false;
#endif
    } else {
        mysql_data_seek(d->result, i);
        d->row = mysql_fetch_row(d->result);
        if (!d->row)
            return false;
    }

    setAt(i);
    return true;
}
示例#10
0
bool QMYSQLResult::fetch( int i )
{
    if ( isForwardOnly() ) { // fake a forward seek
	if ( at() < i ) {
	    int x = i - at();
	    while ( --x && fetchNext() );
	    return fetchNext();
	} else {
	    return FALSE;
	}
    }    
    if ( at() == i )
	return TRUE;
    mysql_data_seek( d->result, i );
    d->row = mysql_fetch_row( d->result );
    if ( !d->row )
	return FALSE;
    setAt( i );
    return TRUE;
}
示例#11
0
bool QMYSQLResult::reset ( const QString& query )
{
    if ( !driver() )
	return FALSE;
    if ( !driver()-> isOpen() || driver()->isOpenError() )
	return FALSE;
    cleanup();

    const char *encQuery = query.ascii();
    if ( mysql_real_query( d->mysql, encQuery, qstrlen(encQuery) ) ) {
	setLastError( qMakeError("Unable to execute query", QSqlError::Statement, d ) );
	return FALSE;
    }
    if ( isForwardOnly() ) {
	if ( isActive() || isValid() ) // have to empty the results from previous query
	    fetchLast();
	d->result = mysql_use_result( d->mysql );
    } else {
	d->result = mysql_store_result( d->mysql );
    }
    if ( !d->result && mysql_field_count( d->mysql ) > 0 ) {
	setLastError( qMakeError( "Unable to store result", QSqlError::Statement, d ) );
	return FALSE;
    }
    int numFields = mysql_field_count( d->mysql );
    setSelect( !( numFields == 0) );
    d->fieldTypes.resize( numFields );
    if ( isSelect() ) {
	for( int i = 0; i < numFields; i++) {
	    MYSQL_FIELD* field = mysql_fetch_field_direct( d->result, i );
	    if ( field->type == FIELD_TYPE_DECIMAL )
		d->fieldTypes[i] = QVariant::String;
	    else
		d->fieldTypes[i] = qDecodeMYSQLType( field->type, field->flags );
	}
    }
    setActive( TRUE );
    return TRUE;
}
示例#12
0
bool QSqlQuery::exec(const QString& query)
{
#ifdef QT_DEBUG_SQL
    QElapsedTimer t;
    t.start();
#endif
    if (d->ref.load() != 1) {
        bool fo = isForwardOnly();
        *this = QSqlQuery(driver()->createResult());
        d->sqlResult->setNumericalPrecisionPolicy(d->sqlResult->numericalPrecisionPolicy());
        setForwardOnly(fo);
    } else {
        d->sqlResult->clear();
        d->sqlResult->setActive(false);
        d->sqlResult->setLastError(QSqlError());
        d->sqlResult->setAt(QSql::BeforeFirstRow);
        d->sqlResult->setNumericalPrecisionPolicy(d->sqlResult->numericalPrecisionPolicy());
    }
    d->sqlResult->setQuery(query.trimmed());
    if (!driver()->isOpen() || driver()->isOpenError()) {
        qWarning("QSqlQuery::exec: database not open");
        return false;
    }
    if (query.isEmpty()) {
        qWarning("QSqlQuery::exec: empty query");
        return false;
    }

    bool retval = d->sqlResult->reset(query);
#ifdef QT_DEBUG_SQL
    qDebug().nospace() << "Executed query (" << t.elapsed() << "ms, " << d->sqlResult->size()
                       << " results, " << d->sqlResult->numRowsAffected()
                       << " affected): " << d->sqlResult->lastQuery();
#endif
    return retval;
}
示例#13
0
/*!

  Retrieves the previous record in the result, if available, and
  positions the query on the retrieved record. Note that the result
  must be in the \l{isActive()}{active} state and isSelect() must
  return true before calling this function or it will do nothing and
  return false.

  The following rules apply:

  \list

  \li If the result is currently located before the first record, there
  is no change and false is returned.

  \li If the result is currently located after the last record, an
  attempt is made to retrieve the last record.

  \li If the result is somewhere in the middle, an attempt is made to
  retrieve the previous record.

  \endlist

  If the record could not be retrieved, the result is positioned
  before the first record and false is returned. If the record is
  successfully retrieved, true is returned.

  \sa next(), first(), last(), seek(), at(), isActive(), isValid()
*/
bool QSqlQuery::previous()
{
    if (!isSelect() || !isActive())
        return false;
    if (isForwardOnly()) {
        qWarning("QSqlQuery::seek: cannot seek backwards in a forward only query");
        return false;
    }

    bool b = false;
    switch (at()) {
    case QSql::BeforeFirstRow:
        return false;
    case QSql::AfterLastRow:
        b = d->sqlResult->fetchLast();
        return b;
    default:
        if (!d->sqlResult->fetchPrevious()) {
            d->sqlResult->setAt(QSql::BeforeFirstRow);
            return false;
        }
        return true;
    }
}
void ZSqliteCipherCachedResult::init(int colCount)
{
    d->init(colCount, isForwardOnly());
}
示例#15
0
bool QMYSQLResult::fetchFirst()
{
    if ( isForwardOnly() ) // again, fake it
	return fetchNext();
    return fetch( 0 );
}
示例#16
0
/*!
  Retrieves the record at position \a index, if available, and
  positions the query on the retrieved record. The first record is at
  position 0. Note that the query must be in an \l{isActive()}
  {active} state and isSelect() must return true before calling this
  function.

  If \a relative is false (the default), the following rules apply:

  \list

  \li If \a index is negative, the result is positioned before the
  first record and false is returned.

  \li Otherwise, an attempt is made to move to the record at position
  \a index. If the record at position \a index could not be retrieved,
  the result is positioned after the last record and false is
  returned. If the record is successfully retrieved, true is returned.

  \endlist

  If \a relative is true, the following rules apply:

  \list

  \li If the result is currently positioned before the first record or
  on the first record, and \a index is negative, there is no change,
  and false is returned.

  \li If the result is currently located after the last record, and \a
  index is positive, there is no change, and false is returned.

  \li If the result is currently located somewhere in the middle, and
  the relative offset \a index moves the result below zero, the result
  is positioned before the first record and false is returned.

  \li Otherwise, an attempt is made to move to the record \a index
  records ahead of the current record (or \a index records behind the
  current record if \a index is negative). If the record at offset \a
  index could not be retrieved, the result is positioned after the
  last record if \a index >= 0, (or before the first record if \a
  index is negative), and false is returned. If the record is
  successfully retrieved, true is returned.

  \endlist

  \sa next(), previous(), first(), last(), at(), isActive(), isValid()
*/
bool QSqlQuery::seek(int index, bool relative)
{
    if (!isSelect() || !isActive())
        return false;
    int actualIdx;
    if (!relative) { // arbitrary seek
        if (index < 0) {
            d->sqlResult->setAt(QSql::BeforeFirstRow);
            return false;
        }
        actualIdx = index;
    } else {
        switch (at()) { // relative seek
        case QSql::BeforeFirstRow:
            if (index > 0)
                actualIdx = index;
            else {
                return false;
            }
            break;
        case QSql::AfterLastRow:
            if (index < 0) {
                d->sqlResult->fetchLast();
                actualIdx = at() + index;
            } else {
                return false;
            }
            break;
        default:
            if ((at() + index) < 0) {
                d->sqlResult->setAt(QSql::BeforeFirstRow);
                return false;
            }
            actualIdx = at() + index;
            break;
        }
    }
    // let drivers optimize
    if (isForwardOnly() && actualIdx < at()) {
        qWarning("QSqlQuery::seek: cannot seek backwards in a forward only query");
        return false;
    }
    if (actualIdx == (at() + 1) && at() != QSql::BeforeFirstRow) {
        if (!d->sqlResult->fetchNext()) {
            d->sqlResult->setAt(QSql::AfterLastRow);
            return false;
        }
        return true;
    }
    if (actualIdx == (at() - 1)) {
        if (!d->sqlResult->fetchPrevious()) {
            d->sqlResult->setAt(QSql::BeforeFirstRow);
            return false;
        }
        return true;
    }
    if (!d->sqlResult->fetch(actualIdx)) {
        d->sqlResult->setAt(QSql::AfterLastRow);
        return false;
    }
    return true;
}
示例#17
0
/*!
    Retrieves the record at position (offset) \a i, if available, and
    positions the query on the retrieved record. The first record is
    at position 0. Note that the query must be in an active state and
    isSelect() must return TRUE before calling this function.

    If \a relative is FALSE (the default), the following rules apply:

    \list
    \i If \a i is negative, the result is positioned before the
    first record and FALSE is returned.
    \i Otherwise, an attempt is made to move to the record at position
    \a i. If the record at position \a i could not be retrieved, the
    result is positioned after the last record and FALSE is returned. If
    the record is successfully retrieved, TRUE is returned.
    \endlist

    If \a relative is TRUE, the following rules apply:

    \list
    \i If the result is currently positioned before the first
    record or on the first record, and \a i is negative, there is no
    change, and FALSE is returned.
    \i If the result is currently located after the last record, and
    \a i is positive, there is no change, and FALSE is returned.
    \i If the result is currently located somewhere in the middle,
    and the relative offset \a i moves the result below zero, the
    result is positioned before the first record and FALSE is
    returned.
    \i Otherwise, an attempt is made to move to the record \a i
    records ahead of the current record (or \a i records behind the
    current record if \a i is negative). If the record at offset \a i
    could not be retrieved, the result is positioned after the last
    record if \a i >= 0, (or before the first record if \a i is
    negative), and FALSE is returned. If the record is successfully
    retrieved, TRUE is returned.
    \endlist

    \sa next() prev() first() last() at() isActive() isValid()
*/
bool QSqlQuery::seek( int i, bool relative )
{
    if ( !isSelect() || !isActive() )
	return FALSE;
    beforeSeek();
    checkDetach();
    int actualIdx;
    if ( !relative ) { // arbitrary seek
	if ( i < 0 ) {
	    d->sqlResult->setAt( QSql::BeforeFirst );
	    afterSeek();
	    return FALSE;
	}
	actualIdx = i;
    } else {
	switch ( at() ) { // relative seek
	case QSql::BeforeFirst:
	    if ( i > 0 )
		actualIdx = i;
	    else {
		afterSeek();
		return FALSE;
	    }
	    break;
	case QSql::AfterLast:
	    if ( i < 0 ) {
		d->sqlResult->fetchLast();
		actualIdx = at() + i;
	    } else {
		afterSeek();
		return FALSE;
	    }
	    break;
	default:
	    if ( ( at() + i ) < 0  ) {
		d->sqlResult->setAt( QSql::BeforeFirst );
		afterSeek();
		return FALSE;
	    }
	    actualIdx = at() + i;
	    break;
	}
    }
    // let drivers optimize
    if ( isForwardOnly() && actualIdx < at() ) {
#ifdef QT_CHECK_RANGE
	qWarning("QSqlQuery::seek: cannot seek backwards in a forward only query" );
#endif
	afterSeek();
	return FALSE;
    }
    if ( actualIdx == ( at() + 1 ) && at() != QSql::BeforeFirst ) {
	if ( !d->sqlResult->fetchNext() ) {
	    d->sqlResult->setAt( QSql::AfterLast );
	    afterSeek();
	    return FALSE;
	}
	afterSeek();
	return TRUE;
    }
    if ( actualIdx == ( at() - 1 ) ) {
	if ( !d->sqlResult->fetchPrev() ) {
	    d->sqlResult->setAt( QSql::BeforeFirst );
	    afterSeek();
	    return FALSE;
	}
	afterSeek();
	return TRUE;
    }
    if ( !d->sqlResult->fetch( actualIdx ) ) {
	d->sqlResult->setAt( QSql::AfterLast );
	afterSeek();
	return FALSE;
    }
    afterSeek();
    return TRUE;
}
示例#18
0
void QtSqlCachedResult::init(int colCount)
{
    d->init(colCount, isForwardOnly());
}