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

📄 qsql_odbc.cpp

📁 qt-x11-free-3.0.3.tar.gz minigui图形界面工具
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************** Implementation of ODBC 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_odbc.h"#include <qsqlrecord.h>#if defined (Q_OS_WIN32)#include <qt_windows.h>#include <qapplication.h>#endif#include <qdatetime.h>// undefine this to prevent initial check of the ODBC driver #define ODBC_CHECK_DRIVERclass QODBCPrivate{public:    QODBCPrivate()    : hEnv(0), hDbc(0), hStmt(0)    {}    SQLHANDLE hEnv;    SQLHANDLE hDbc;    SQLHANDLE hStmt;    bool checkDriver() const;};QString qWarnODBCHandle(int handleType, SQLHANDLE handle){    SQLINTEGER nativeCode_;    SQLSMALLINT tmp;    SQLRETURN r = SQL_ERROR;    SQLCHAR state_[SQL_SQLSTATE_SIZE+1];    SQLCHAR description_[SQL_MAX_MESSAGE_LENGTH];    r = SQLGetDiagRec( handleType,			 handle,			 1,			 (SQLCHAR*)state_,			 &nativeCode_,			 (SQLCHAR*)description_,			 SQL_MAX_MESSAGE_LENGTH-1,			 &tmp);    if ( r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO )	return QString( (const char*)description_ );    return QString::null;}QString qODBCWarn( const QODBCPrivate* odbc){    return ( qWarnODBCHandle( SQL_HANDLE_ENV, odbc->hEnv ) + " " \	     + qWarnODBCHandle( SQL_HANDLE_DBC, odbc->hDbc ) + " " \	     + qWarnODBCHandle( SQL_HANDLE_STMT, odbc->hStmt ) );}void qSqlWarning( const QString& message, const QODBCPrivate* odbc ){#ifdef QT_CHECK_RANGE    qWarning( message + "\tError:" + qODBCWarn( odbc ) );#endif}QSqlError qMakeError( const QString& err, int type, const QODBCPrivate* p ){    return QSqlError( "QODBC3: " + err, qODBCWarn(p), type );}QVariant::Type qDecodeODBCType( SQLSMALLINT sqltype ){    QVariant::Type type = QVariant::Invalid;    switch ( sqltype ) {    case SQL_DECIMAL:    case SQL_NUMERIC:    case SQL_REAL:    case SQL_FLOAT:    case SQL_DOUBLE:	type = QVariant::Double;	break;    case SQL_SMALLINT:    case SQL_INTEGER:    case SQL_BIT:    case SQL_TINYINT:    case SQL_BIGINT:	type = QVariant::Int;	break;//     case SQL_BINARY://     case SQL_VARBINARY://     case SQL_LONGVARBINARY://	type = QSqlFieldInfo::Binary;//	break;    case SQL_DATE:    case SQL_TYPE_DATE:	type = QVariant::Date;	break;    case SQL_TIME:    case SQL_TYPE_TIME:	type = QVariant::Time;	break;    case SQL_TIMESTAMP:    case SQL_TYPE_TIMESTAMP:	type = QVariant::DateTime;	break;    default:    case SQL_CHAR:    case SQL_VARCHAR:    case SQL_LONGVARCHAR:	type = QVariant::String;	break;    }    return type;}QSqlFieldInfo qMakeFieldInfo( const QODBCPrivate* p, int i  ){    SQLSMALLINT colNameLen;    SQLSMALLINT colType;    SQLUINTEGER colSize;    SQLSMALLINT colScale;    SQLSMALLINT nullable;    SQLRETURN r = SQL_ERROR;    QString qColName;    SQLCHAR colName[255];    r = SQLDescribeCol( p->hStmt,			i+1,			colName,			sizeof(colName),			&colNameLen,			&colType,			&colSize,			&colScale,			&nullable);    if ( r != SQL_SUCCESS ) {#ifdef QT_CHECK_RANGE	qSqlWarning( QString("qMakeField: Unable to describe column %1").arg(i), p );#endif	return QSqlFieldInfo();    }    qColName = qstrdup((const char*)colName);    // nullable can be SQL_NO_NULLS, SQL_NULLABLE or SQL_NULLABLE_UNKNOWN    int required = -1;    if ( nullable == SQL_NO_NULLS ) {	required = 1;    } else if ( nullable == SQL_NULLABLE ) {	required = 0;    }    QVariant::Type type = qDecodeODBCType( colType );    return QSqlFieldInfo( qColName,    			  type,    			  required,    			  (int)colSize == 0 ? -1 : (int)colSize,    			  (int)colScale == 0 ? -1 : (int)colScale,    			  QVariant(),    			  (int)colType );}QString qGetStringData( SQLHANDLE hStmt, int column, SQLINTEGER& lengthIndicator, bool& isNull ){    QString fieldVal;    SQLSMALLINT colNameLen;    SQLSMALLINT colType;    SQLUINTEGER colSize;    SQLSMALLINT colScale;    SQLSMALLINT nullable;    SQLRETURN r = SQL_ERROR;    QString qColName;    SQLCHAR colName[255];    r = SQLDescribeCol( hStmt,			column+1,			colName,			sizeof(colName),			&colNameLen,			&colType,			&colSize,			&colScale,			&nullable);    qColName = qstrdup( (const char*)colName );#ifdef QT_CHECK_RANGE    if ( r != SQL_SUCCESS )	qWarning( QString("qGetStringData: Unable to describe column %1").arg(column) );#endif    // SQLDescribeCol may return 0 if size cannot be determined    if (!colSize) {	colSize = 255;    }    SQLCHAR* buf = new SQLTCHAR[ colSize + 1 ];    while ( TRUE ) {	r = SQLGetData( hStmt,			column+1,			SQL_C_CHAR,			(SQLPOINTER)buf,			colSize + 1,			&lengthIndicator );	if ( r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO ) {	    if ( lengthIndicator == SQL_NO_TOTAL ){		fieldVal += QString( (char*)buf );  // keep going	    }	    else if ( lengthIndicator == SQL_NULL_DATA ) {			fieldVal = QString::null;			isNull = TRUE;			break;	    } else {		if ( r == SQL_SUCCESS ) {		    fieldVal += QString( (char*)buf );		    break;		} else {		    if( (int)fieldVal.length() >= lengthIndicator ) // ### HACK - remove asap			break;		    fieldVal += QString( (char*)buf );		}	    }	} else {	    fieldVal += QString::null;	    break;	}    }    delete buf;    return fieldVal;}int qGetIntData( SQLHANDLE hStmt, int column, bool& isNull  ){    SQLINTEGER intbuf;    isNull = FALSE;    SQLINTEGER lengthIndicator = 0;    SQLRETURN r = SQLGetData( hStmt,		    column+1,		    SQL_C_SLONG,		    (SQLPOINTER)&intbuf,		    0,		    &lengthIndicator );    if ( r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO ) {	if ( lengthIndicator == SQL_NULL_DATA )	    isNull = TRUE;    }    return (int)intbuf;}QSqlFieldInfo qMakeFieldInfo( const QODBCPrivate* d, const QString& tablename, const QString& fieldname ){    QSqlFieldInfo fi;    SQLHANDLE hStmt;    SQLRETURN r = SQLAllocHandle( SQL_HANDLE_STMT,				  d->hDbc,				  &hStmt );    if ( r != SQL_SUCCESS ) {#ifdef QT_CHECK_RANGE        qSqlWarning( "qMakeField: Unable to alloc handle", d );#endif	return fi;    }    r = SQLSetStmtAttr( hStmt,			SQL_ATTR_CURSOR_TYPE,			(SQLPOINTER)SQL_CURSOR_FORWARD_ONLY,			SQL_IS_UINTEGER );    r =  SQLColumns( hStmt,		     NULL,		     0,		     NULL,		     0,		     (SQLCHAR*)tablename.local8Bit().data(),		     tablename.length(),		     (SQLCHAR*)fieldname.local8Bit().data(),		     fieldname.length() );    if ( r != SQL_SUCCESS ) {#ifdef QT_CHECK_RANGE	qSqlWarning( "qMakeField: Unable to execute column list", d );#endif	return fi;    }    r = SQLFetchScroll( hStmt,			SQL_FETCH_NEXT,			0);    if ( r == SQL_SUCCESS ) {	bool isNull;	int type = qGetIntData( hStmt, 4, isNull ); // column type	int required = qGetIntData( hStmt, 10, isNull ); // nullable-flag	// required can be SQL_NO_NULLS, SQL_NULLABLE or SQL_NULLABLE_UNKNOWN	if ( required == SQL_NO_NULLS ) {	    required = 1;	} else if ( required == SQL_NULLABLE ) {	    required = 0;	} else {	    required = -1;	}	int size = qGetIntData( hStmt, 6, isNull ); // column size	int prec = qGetIntData( hStmt, 8, isNull ); // precision	fi = QSqlFieldInfo( fieldname, qDecodeODBCType( type ), required, size, prec, QVariant(), type );    }    r = SQLFreeHandle( SQL_HANDLE_STMT, hStmt );#ifdef QT_CHECK_RANGE    if ( r != SQL_SUCCESS )        qSqlWarning( "QODBCDriver: Unable to free statement handle " + QString::number(r), d );#endif    return fi;}QSqlField qMakeField( const QODBCPrivate* d, const QString& tablename, const QString& fieldname ){    QSqlFieldInfo info = qMakeFieldInfo( d, tablename, fieldname );    return QSqlField( info.name(), info.type() );}QSqlField qMakeField( const QODBCPrivate* p, int i  ){    QSqlFieldInfo info = qMakeFieldInfo( p, i );    return QSqlField( info.name(), info.type() );}////////////////////////////////////////////////////////////////////////////QODBCResult::QODBCResult( const QODBCDriver * db, QODBCPrivate* p ): QSqlResult(db){    d = new QODBCPrivate();    (*d) = (*p);}QODBCResult::~QODBCResult(){    if ( d->hStmt && driver()->isOpen() ) {	SQLRETURN r = SQLFreeHandle( SQL_HANDLE_STMT, d->hStmt );#ifdef QT_CHECK_RANGE	if ( r!= SQL_SUCCESS )		qSqlWarning( "QODBCDriver: Unable to free statement handle" + QString::number(r), d );#endif    }    delete d;}bool QODBCResult::reset ( const QString& query ){    setActive( FALSE );    setAt( QSql::BeforeFirst );    SQLRETURN r;    // If a statement handle exists - reuse it    if ( d->hStmt ) {		r = SQLFreeStmt( d->hStmt, SQL_CLOSE );		if ( r != SQL_SUCCESS ) {#ifdef QT_CHECK_RANGE			qSqlWarning( "QODBCResult::reset: Unable to close statement", d );#endif			return FALSE;		}    } else {		r  = SQLAllocHandle( SQL_HANDLE_STMT,				d->hDbc,				&d->hStmt );		if ( r != SQL_SUCCESS ) {#ifdef QT_CHECK_RANGE			qSqlWarning( "QODBCResult::reset: Unable to allocate statement handle", d );#endif			return FALSE;		}		r = SQLSetStmtAttr( d->hStmt,				SQL_ATTR_CURSOR_TYPE,				(SQLPOINTER)SQL_CURSOR_STATIC,				SQL_IS_UINTEGER );		if ( r != SQL_SUCCESS ) {#ifdef QT_CHECK_RANGE			qSqlWarning( "QODBCResult::reset: Unable to set statement attribute", d );#endif			return FALSE;		}    }    r = SQLExecDirect( d->hStmt,			(SQLCHAR*)query.local8Bit().data(),			SQL_NTS );    if ( r != SQL_SUCCESS ) {	setLastError( qMakeError( "Unable to execute statement", QSqlError::Statement, d ) );	return FALSE;    }    SQLSMALLINT count;    r = SQLNumResultCols( d->hStmt, &count );

⌨️ 快捷键说明

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