?? qsql_mysql.cpp
字號:
/******************************************************************************** Implementation of MYSQL driver classes**** Created : 001103**** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.**** This file is part of the sql module of the Qt GUI Toolkit.**** This file may be distributed under the terms of the Q Public License** as defined by Trolltech AS of Norway and appearing in the file** LICENSE.QPL included in the packaging of this file.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** Licensees holding valid Qt Enterprise Edition licenses may use this** file in accordance with the Qt Commercial License Agreement provided** with the Software.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for** information about Qt Commercial License Agreements.** See http://www.trolltech.com/qpl/ for QPL licensing information.** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/#include "qsql_mysql.h"#include <private/qsqlextension_p.h>#include <qdatetime.h>#include <qvaluevector.h>#include <qsqlrecord.h>#define QMYSQL_DRIVER_NAME "QMYSQL3"#ifdef Q_OS_WIN32// comment the next line out if you want to use MySQL/embedded on Win32 systems.// note that it will crash if you don't statically link to the mysql/e library!# define Q_NO_MYSQL_EMBEDDED#endifQPtrDict<QSqlOpenExtension> *qSqlOpenExtDict();class QMYSQLOpenExtension : public QSqlOpenExtension{public: QMYSQLOpenExtension( QMYSQLDriver *dri ) : QSqlOpenExtension(), driver(dri) {} ~QMYSQLOpenExtension() {} bool open( const QString& db, const QString& user, const QString& password, const QString& host, int port, const QString& connOpts ); private: QMYSQLDriver *driver;};bool QMYSQLOpenExtension::open( const QString& db, const QString& user, const QString& password, const QString& host, int port, const QString& connOpts ){ return driver->open( db, user, password, host, port, connOpts );}class QMYSQLDriverPrivate{public: QMYSQLDriverPrivate() : mysql(0) {} MYSQL* mysql;};class QMYSQLResultPrivate : public QMYSQLDriverPrivate{public: QMYSQLResultPrivate() : QMYSQLDriverPrivate(), result(0) {} MYSQL_RES* result; MYSQL_ROW row; QValueVector<QVariant::Type> fieldTypes;};QSqlError qMakeError( const QString& err, int type, const QMYSQLDriverPrivate* p ){ return QSqlError(QMYSQL_DRIVER_NAME ": " + err, QString(mysql_error( p->mysql )), type, mysql_errno( p->mysql ));}QVariant::Type qDecodeMYSQLType( int mysqltype, uint flags ){ QVariant::Type type; switch ( mysqltype ) { case FIELD_TYPE_TINY : case FIELD_TYPE_SHORT : case FIELD_TYPE_LONG : case FIELD_TYPE_INT24 : type = (flags & UNSIGNED_FLAG) ? QVariant::UInt : QVariant::Int; break; case FIELD_TYPE_YEAR : type = QVariant::Int; break; case FIELD_TYPE_LONGLONG : type = (flags & UNSIGNED_FLAG) ? QVariant::ULongLong : QVariant::LongLong; break; case FIELD_TYPE_DECIMAL : case FIELD_TYPE_FLOAT : case FIELD_TYPE_DOUBLE : type = QVariant::Double; break; case FIELD_TYPE_DATE : type = QVariant::Date; break; case FIELD_TYPE_TIME : type = QVariant::Time; break; case FIELD_TYPE_DATETIME : case FIELD_TYPE_TIMESTAMP : type = QVariant::DateTime; break; case FIELD_TYPE_BLOB : case FIELD_TYPE_TINY_BLOB : case FIELD_TYPE_MEDIUM_BLOB : case FIELD_TYPE_LONG_BLOB : type = (flags & BINARY_FLAG) ? QVariant::ByteArray : QVariant::CString; break; default: case FIELD_TYPE_ENUM : case FIELD_TYPE_SET : case FIELD_TYPE_STRING : case FIELD_TYPE_VAR_STRING : type = QVariant::String; break; } return type;}QMYSQLResult::QMYSQLResult( const QMYSQLDriver* db ): QSqlResult( db ){ d = new QMYSQLResultPrivate(); d->mysql = db->d->mysql;}QMYSQLResult::~QMYSQLResult(){ cleanup(); delete d;}MYSQL_RES* QMYSQLResult::result(){ return d->result;}void QMYSQLResult::cleanup(){ if ( d->result ) { mysql_free_result( d->result ); } d->result = NULL; d->row = NULL; setAt( -1 ); setActive( FALSE );}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;}bool QMYSQLResult::fetchNext(){ d->row = mysql_fetch_row( d->result ); if ( !d->row ) return FALSE; setAt( at() + 1 ); return TRUE;}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 );}bool QMYSQLResult::fetchFirst(){ if ( isForwardOnly() ) // again, fake it return fetchNext(); return fetch( 0 );}QVariant QMYSQLResult::data( int field ){ if ( !isSelect() || field >= (int) d->fieldTypes.count() ) { qWarning( "QMYSQLResult::data: column %d out of range", field ); return QVariant(); } QString val( d->row[field] ); switch ( d->fieldTypes.at( field ) ) { case QVariant::LongLong: return QVariant( val.toLongLong() ); case QVariant::ULongLong: return QVariant( val.toULongLong() ); case QVariant::Int: return QVariant( val.toInt() ); case QVariant::UInt: return QVariant( val.toUInt() ); case QVariant::Double: return QVariant( val.toDouble() ); case QVariant::Date: if ( val.isEmpty() ) { return QVariant( QDate() ); } else { return QVariant( QDate::fromString( val, Qt::ISODate ) ); } case QVariant::Time: if ( val.isEmpty() ) { return QVariant( QTime() ); } else { return QVariant( QTime::fromString( val, Qt::ISODate ) ); } case QVariant::DateTime: if ( val.isEmpty() ) return QVariant( QDateTime() ); if ( val.length() == 14u ) // TIMESTAMPS have the format yyyyMMddhhmmss val.insert(4, "-").insert(7, "-").insert(10, 'T').insert(13, ':').insert(16, ':'); return QVariant( QDateTime::fromString( val, Qt::ISODate ) ); case QVariant::ByteArray: { unsigned long* fl = mysql_fetch_lengths( d->result ); QByteArray ba; ba.duplicate( d->row[field], fl[field] ); return QVariant( ba ); } default: case QVariant::String: case QVariant::CString: return QVariant( val ); }#ifdef QT_CHECK_RANGE qWarning("QMYSQLResult::data: unknown data type");#endif return QVariant();}bool QMYSQLResult::isNull( int field ){ if ( d->row[field] == NULL ) return TRUE; return FALSE;}bool QMYSQLResult::reset ( const QString& query ){ if ( !driver() ) return FALSE; if ( !driver()-> isOpen() || driver()->isOpenError() ) return FALSE; cleanup(); if ( mysql_real_query( d->mysql, query, query.length() ) ) { 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;}int QMYSQLResult::size(){ return isSelect() ? (int)mysql_num_rows( d->result ) : -1;}int QMYSQLResult::numRowsAffected(){ return (int)mysql_affected_rows( d->mysql );}/////////////////////////////////////////////////////////static void qServerInit(){#ifndef Q_NO_MYSQL_EMBEDDED# if MYSQL_VERSION_ID >= 40000 static bool init = FALSE; if ( init ) return; // this should only be called once // has no effect on client/server library // but is vital for the embedded lib if ( mysql_server_init( 0, 0, 0 ) ) {# ifdef QT_CHECK_RANGE qWarning( "QMYSQLDriver::qServerInit: unable to start server." );# endif } init = TRUE; # endif // MYSQL_VERSION_ID#endif // Q_NO_MYSQL_EMBEDDED}QMYSQLDriver::QMYSQLDriver( QObject * parent, const char * name ) : QSqlDriver( parent, name ? name : QMYSQL_DRIVER_NAME ){ init(); qServerInit();}/*! Create a driver instance with an already open connection handle.*/QMYSQLDriver::QMYSQLDriver( MYSQL * con, QObject * parent, const char * name ) : QSqlDriver( parent, name ? name : QMYSQL_DRIVER_NAME ){ init(); if ( con ) { d->mysql = (MYSQL *) con;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -