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

📄 qsql_odbc.cpp

📁 Linux下的基于X11的图形开发环境。
💻 CPP
📖 第 1 页 / 共 3 页
字号:
bool QODBCResult::fetchNext(){    SQLRETURN r;    fieldCache.clear();    nullCache.clear();    r = SQLFetchScroll( d->hStmt,		       SQL_FETCH_NEXT,		       0 );    if ( r != SQL_SUCCESS )	return FALSE;    setAt( at() + 1 );    return TRUE;}bool QODBCResult::fetchFirst(){    if ( isForwardOnly() && at() != QSql::BeforeFirst )	return FALSE;    SQLRETURN r;    fieldCache.clear();    nullCache.clear();    if ( isForwardOnly() ) {	return fetchNext();    }    r = SQLFetchScroll( d->hStmt,		       SQL_FETCH_FIRST,		       0 );    if ( r != SQL_SUCCESS )	return FALSE;    setAt( 0 );    return TRUE;}bool QODBCResult::fetchPrior(){    if ( isForwardOnly() )	return FALSE;    SQLRETURN r;    fieldCache.clear();    nullCache.clear();    r = SQLFetchScroll( d->hStmt,		       SQL_FETCH_PRIOR,		       0 );    if ( r != SQL_SUCCESS )	return FALSE;    setAt( at() - 1 );    return TRUE;}bool QODBCResult::fetchLast(){    SQLRETURN r;    fieldCache.clear();    nullCache.clear();    if ( isForwardOnly() ) {	// cannot seek to last row in forwardOnly mode, so we have to use brute force	int i = at();	while ( fetchNext() ) 	    ++i;	setAt( i );	return TRUE;    }    r = SQLFetchScroll( d->hStmt,		       SQL_FETCH_LAST,		       0 );    if ( r != SQL_SUCCESS ) {	return FALSE;    }    SQLINTEGER currRow;    r = SQLGetStmtAttr( d->hStmt,			SQL_ROW_NUMBER,			&currRow,			SQL_IS_INTEGER,			0 );    if ( r != SQL_SUCCESS )	return FALSE;    setAt( currRow-1 );    return TRUE;}QVariant QODBCResult::data( int field ){    if ( fieldCache.contains( field ) )	return fieldCache[ field ];    SQLRETURN r(0);    SQLINTEGER lengthIndicator = 0;    bool isNull = FALSE;    int current = fieldCache.count();    for ( ; current < (field + 1); ++current ) {	const QSqlFieldInfo info = d->rInf[ current ];	switch ( info.type() ) {	case QVariant::Int:	    isNull = FALSE;	    fieldCache[ current ] = QVariant( qGetIntData( d->hStmt, current, isNull ) );	    nullCache[ current ] = isNull;	    break;	case QVariant::Date:	    DATE_STRUCT dbuf;	    r = SQLGetData( d->hStmt,			    current+1,			    SQL_C_DATE,			    (SQLPOINTER)&dbuf,			    0,			    &lengthIndicator );	    if ( ( r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO ) && ( lengthIndicator != SQL_NULL_DATA ) ) {		fieldCache[ current ] = QVariant( QDate( dbuf.year, dbuf.month, dbuf.day ) );		nullCache[ current ] = FALSE;	    } else {		fieldCache[ current ] = QVariant( QDate() );		nullCache[ current ] = TRUE;	    }	    break;	case QVariant::Time:	    TIME_STRUCT tbuf;	    r = SQLGetData( d->hStmt,			    current+1,			    SQL_C_TIME,			    (SQLPOINTER)&tbuf,			    0,			    &lengthIndicator );	    if ( ( r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO ) && ( lengthIndicator != SQL_NULL_DATA ) ) {		fieldCache[ current ] = QVariant( QTime( tbuf.hour, tbuf.minute, tbuf.second ) );		nullCache[ current ] = FALSE;	    } else {		fieldCache[ current ] = QVariant( QTime() );		nullCache[ current ] = TRUE;	    }	    break;	case QVariant::DateTime:	    TIMESTAMP_STRUCT dtbuf;	    r = SQLGetData( d->hStmt,			    current+1,			    SQL_C_TIMESTAMP,			    (SQLPOINTER)&dtbuf,			    0,			    &lengthIndicator );	    if ( ( r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO ) && ( lengthIndicator != SQL_NULL_DATA ) ) {		fieldCache[ current ] = QVariant( QDateTime( QDate( dtbuf.year, dtbuf.month, dtbuf.day ), QTime( dtbuf.hour, dtbuf.minute, dtbuf.second ) ) );		nullCache[ current ] = FALSE;	    } else {		fieldCache[ current ] = QVariant( QDateTime() );		nullCache[ current ] = TRUE;	    }	    break;        case QVariant::ByteArray: {	    isNull = FALSE;	    QByteArray val = qGetBinaryData( d->hStmt, current, lengthIndicator, isNull );	    fieldCache[ current ] = QVariant( val );	    nullCache[ current ] = isNull;	    break; }	case QVariant::String:	    isNull = FALSE;	    fieldCache[ current ] = QVariant( qGetStringData( d->hStmt, current,					      info.length(), isNull, TRUE ) );	    nullCache[ current ] = isNull;	    break;	case QVariant::Double:	    // bind Double values as string to prevent loss of precision	    isNull = FALSE;	    // length + 1 for the comma	    fieldCache[ current ] = QVariant( qGetStringData( d->hStmt, current,					      info.length() + 1, isNull, FALSE ) );	    nullCache[ current ] = isNull;	    break;	case QVariant::CString:	default:	    isNull = FALSE;	    fieldCache[ current ] = QVariant( qGetStringData( d->hStmt, current, 					      info.length(), isNull, FALSE ) );	    nullCache[ current ] = isNull;	    break;	}    }    return fieldCache[ --current ];}bool QODBCResult::isNull( int field ){    if ( !fieldCache.contains( field ) ) {	// since there is no good way to find out whether the value is NULL	// without fetching the field we'll fetch it here.	// (data() also sets the NULL flag)	data( field );    }    return nullCache[ field ];}int QODBCResult::size(){    return -1;//     int size(-1);//     int at(0);//     SQLINTEGER currRow(0);//     SQLRETURN r = SQLGetStmtAttr( d->hStmt,//			SQL_ROW_NUMBER,//			&currRow,//			SQL_IS_INTEGER,//			0);//     at = currRow;//     r = SQLFetchScroll( d->hStmt,//                         SQL_FETCH_LAST,//                         0);//     if ( r == SQL_SUCCESS ) {//	r = SQLGetStmtAttr( d->hStmt,//			SQL_ROW_NUMBER,//			&currRow,//			SQL_IS_INTEGER,//			0);//	if ( r == SQL_SUCCESS )//	    size = currRow;//	r = SQLFetchScroll( d->hStmt,//                         SQL_FETCH_ABSOLUTE,//                         currRow);//	if ( r != SQL_SUCCESS )//	    qSqlWarning("QODBCResult::size: Unable to restore position", d );//     }//     return size;}int QODBCResult::numRowsAffected(){    SQLINTEGER affectedRowCount(0);    SQLRETURN r = SQLRowCount( d->hStmt, &affectedRowCount);    if ( r == SQL_SUCCESS )	return affectedRowCount;#ifdef QT_CHECK_RANGE    else	qSqlWarning( "QODBCResult::numRowsAffected: Unable to count affected rows", d );#endif    return -1;}bool QODBCResult::prepare( const QString& query ){    setActive( FALSE );    setAt( QSql::BeforeFirst );    SQLRETURN r;    d->rInf.clear();    // If a statement handle exists - reuse it    if ( d->hStmt ) {	r = SQLFreeHandle( SQL_HANDLE_STMT, d->hStmt );	if ( r != SQL_SUCCESS ) {#ifdef QT_CHECK_RANGE	    qSqlWarning( "QODBCResult::prepare: 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::prepare: Unable to allocate statement handle", d );#endif	    return FALSE;	}//    }    if ( isForwardOnly() ) {	r = SQLSetStmtAttr( d->hStmt,	    		    SQL_ATTR_CURSOR_TYPE,			    (SQLPOINTER)SQL_CURSOR_FORWARD_ONLY,			    SQL_IS_UINTEGER );    } else {	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::prepare: Unable to set 'SQL_CURSOR_STATIC' as statement attribute. Please check your ODBC driver configuration", d );#endif	return FALSE;    }#ifdef UNICODE    r = SQLPrepare( d->hStmt,		    (SQLWCHAR*) query.unicode(),		    (SQLINTEGER) query.length() );#else    QCString query8 = query.local8Bit();    r = SQLPrepare( d->hStmt,		    (SQLCHAR*) query8.data(),		    (SQLINTEGER) query8.length() );#endif    if ( r != SQL_SUCCESS ) {#ifdef QT_CHECK_RANGE	qSqlWarning( "QODBCResult::prepare: Unable to prepare statement", d );#endif	return FALSE;    }        return TRUE;}bool QODBCResult::exec(){    SQLRETURN r;    QPtrList<QVirtualDestructor> tmpStorage; // holds temporary ptrs. which will be deleted on fu exit    tmpStorage.setAutoDelete( TRUE );      // bind parameters - only positional binding allowed    if ( extension()->index.count() > 0 ) {	QMap<int, QString>::Iterator it;	int para = 1;	QVariant val;	for ( it = extension()->index.begin(); it != extension()->index.end(); ++it ) {	    val = extension()->values[ it.data() ].value;	    SQLINTEGER * ind = new SQLINTEGER( SQL_NTS );	    tmpStorage.append( qAutoDeleter(ind) );	    if ( val.isNull() ) {		*ind = SQL_NULL_DATA;	    }	    switch ( val.type() ) {		case QVariant::Date: {		    DATE_STRUCT * dt = new DATE_STRUCT;		    tmpStorage.append( qAutoDeleter(dt) );		    QDate qdt = val.toDate(); 		    dt->year = qdt.year(); 		    dt->month = qdt.month(); 		    dt->day = qdt.day();		    r = SQLBindParameter( d->hStmt,					  para,					  SQL_PARAM_INPUT,					  SQL_C_DATE,					  SQL_DATE,					  0,					  0,					  (void *) dt,					  0,					  *ind == SQL_NULL_DATA ? ind : NULL );		    break; }		case QVariant::Time: {		    TIME_STRUCT * dt = new TIME_STRUCT;		    tmpStorage.append( qAutoDeleter(dt) );		    QTime qdt = val.toTime(); 		    dt->hour = qdt.hour(); 		    dt->minute = qdt.minute(); 		    dt->second = qdt.second();		    r = SQLBindParameter( d->hStmt,					  para,					  SQL_PARAM_INPUT,					  SQL_C_TIME,					  SQL_TIME,					  0,					  0,					  (void *) dt,					  0,	        			  *ind == SQL_NULL_DATA ? ind : NULL );		    break; }		case QVariant::DateTime: {		    TIMESTAMP_STRUCT * dt = new TIMESTAMP_STRUCT; 		    tmpStorage.append( qAutoDeleter(dt) );		    QDateTime qdt = val.toDateTime(); 		    dt->year = qdt.date().year(); 		    dt->month = qdt.date().month(); 		    dt->day = qdt.date().day(); 		    dt->hour = qdt.time().hour(); 		    dt->minute = qdt.time().minute(); 		    dt->second = qdt.time().second();  		    dt->fraction = 0;		    r = SQLBindParameter( d->hStmt,					  para,					  SQL_PARAM_INPUT,					  SQL_C_TIMESTAMP,					  SQL_TIMESTAMP,					  0,					  0,					  (void *) dt,					  0,					  *ind == SQL_NULL_DATA ? ind : NULL );		    break; }	        case QVariant::Int: {		    int * v = new int( val.toInt() );		    tmpStorage.append( qAutoDeleter(v) );		    r = SQLBindParameter( d->hStmt,					  para,					  SQL_PARAM_INPUT,					  SQL_C_SLONG,					  SQL_INTEGER,					  0,					  0,					  (void *) v,					  0,					  *ind == SQL_NULL_DATA ? ind : NULL );		    break; } 	        case QVariant::Double: {		    double * v = new double( val.toDouble() );		    tmpStorage.append( qAutoDeleter(v) );		    r = SQLBindParameter( d->hStmt,					  para,					  SQL_PARAM_INPUT,					  SQL_C_DOUBLE,					  SQL_DOUBLE,					  0,					  0,					  (void *) v,					  0,					  *ind == SQL_NULL_DATA ? ind : NULL );		    break; } 	        case QVariant::ByteArray: {		    QByteArray ba = val.toByteArray();		    if ( *ind != SQL_NULL_DATA ) {			*ind = ba.size();		    }		    r = SQLBindParameter( d->hStmt,					  para,					  SQL_PARAM_INPUT,					  SQL_C_BINARY,					  SQL_LONGVARBINARY,					  ba.size(),					  0,					  (void *) ba.data(),					  ba.size(),					  ind );		    break; }	        case QVariant::String:		    if ( d->unicode ) {			QString * str = new QString( val.asString() );			str->ucs2();			int len = str->length()*2;			tmpStorage.append( qAutoDeleter(str) );			r = SQLBindParameter( d->hStmt,					      para,					      SQL_PARAM_INPUT,					      SQL_C_WCHAR,					      SQL_WVARCHAR,					      str->length(),					      0, 					      (void *) str->unicode(),					      len,					      ind );			break;		    }		    // fall through	        default: {		    QCString * str = new QCString( val.asString().local8Bit() );		    tmpStorage.append( qAutoDeleter(str) );		    r = SQLBindParameter( d->hStmt,					  para,					  SQL_PARAM_INPUT,					  SQL_C_CHAR,					  SQL_VARCHAR,  					  str->length() + 1,					  0,					  (void *) str->data(),					  str->length() + 1,					  ind );		    break; }	    }	    para++;	    if ( r != SQL_SUCCESS ) {#ifdef QT_CHECK_RANGE		qWarning( "QODBCResult::exec: unable to bind variable: " + qODBCWarn( d ) );#endif		setLastError( qMakeError( "Unable to bind variable", QSqlError::Statement, d ) );		return FALSE;	    }	}    }    r = SQLExecute( d->hStmt );    if ( r != SQL_SUCCESS ) {#ifdef QT_CHECK_RANGE	qWarning( "QODBCResult::exec: Unable to execute statement: " + qODBCWarn( d ) );#endif	setLastError( qMakeError( "Unable to execute statement", QSqlError::Statement, d ) );	return FALSE;    }    SQLSMALLINT count;    r = SQLNumResultCols( d->hStmt, &count );    if ( count ) {	setSelect( TRUE );	for ( int i = 0; i < count; ++i ) {	    d->rInf.append( qMakeFieldInfo( d, i ) );	}    } else {	setSelect( FALSE );    }    setActive( TRUE );    return TRUE;}////////////////////////////////////////QODBCDriver::QODBCDriver( QObject * parent, const char * name ): QSqlDriver(parent,name ? name : "QODBC"){    init();}void QODBCDriver::init(){    d = new QODBCPrivate();}QODBCDriver::~QODBCDriver(){    cleanup();    delete d;}bool QODBCDriver::hasFeature( DriverFeature f ) const{    switch ( f ) {    case Transactions: {	if ( !d->hDbc )	    return FALSE;	SQLUSMALLINT txn;	SQLSMALLINT t;	int r = SQLGetInfo( d->hDbc,			(SQLUSMALLINT)SQL_TXN_CAPABLE,			&txn,			sizeof(txn),			&t);	if ( r != SQL_SUCCESS || txn == SQL_TC_NONE )	    return FALSE;	else	    return TRUE;    }    case QuerySize:	return FALSE;    case BLOB:	return TRUE;    case Unicode:	return d->unicode;    case PreparedQueries:	return TRUE;    case PositionalPlaceholders:	return TRUE;    default:	return FALSE;    }}bool QODBCDriver::open( const QString & db,			const QString & user,			const QString & password,			const QString &,			int ){    if ( isOpen() )      close();    SQLRETURN r;    r = SQLAllocHandle( SQL_HANDLE_ENV,			SQL_NULL_HANDLE,			&d->hEnv);    if ( r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO ) {#ifdef QT_CHECK_RANGE	qSqlWarning( "QODBCDriver::open: Unable to allocate environment", d );#endif	setOpenError( TRUE );	return FALSE;    }    r = SQLSetEnvAttr( d->hEnv,			SQL_ATTR_ODBC_VERSION,			(SQLPOINTER)SQL_OV_ODBC2,			SQL_IS_UINTEGER );    r = SQLAllocHandle(SQL_HANDLE_DBC,			d->hEnv,			&d->hDbc);    if ( r != SQL_SUCCESS ) {#ifdef QT_CHECK_RANGE		qSqlWarning( "QODBCDriver::open: Unable to allocate connection", d );#endif

⌨️ 快捷键说明

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