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

📄 qsql_odbc.cpp

📁 这个是Linux的qt源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	int idx;	if ( (idx = tmp.find( '=' )) != -1 )	    connMap[ tmp.left( idx ) ] = tmp.mid( idx + 1 ).simplifyWhiteSpace();	else	    qWarning( "QODBCDriver::open: Illegal connect option value '%s'", tmp.latin1() );    }    if ( connMap.count() ) {	QMap<QString, QString>::ConstIterator it;	QString opt, val;	SQLUINTEGER v = 0;	for ( it = connMap.begin(); it != connMap.end(); ++it ) {	    opt = it.key().upper();	    val = it.data().upper();	    r = SQL_SUCCESS;	    if ( opt == "SQL_ATTR_ACCESS_MODE" ) {		if ( val == "SQL_MODE_READ_ONLY" ) {		    v = SQL_MODE_READ_ONLY;		} else if ( val == "SQL_MODE_READ_WRITE" ) {		    v = SQL_MODE_READ_WRITE;		} else {		    qWarning( QString( "QODBCDriver::open: Unknown option value '%1'" ).arg( *it ) );		    break;		}		r = SQLSetConnectAttr( hDbc, SQL_ATTR_ACCESS_MODE, (SQLPOINTER) v, 0 );	    } else if ( opt == "SQL_ATTR_CONNECTION_TIMEOUT" ) {		v = val.toUInt();		r = SQLSetConnectAttr( hDbc, SQL_ATTR_CONNECTION_TIMEOUT, (SQLPOINTER) v, 0 );	    } else if ( opt == "SQL_ATTR_LOGIN_TIMEOUT" ) {		v = val.toUInt();		r = SQLSetConnectAttr( hDbc, SQL_ATTR_LOGIN_TIMEOUT, (SQLPOINTER) v, 0 );	    } else if ( opt == "SQL_ATTR_CURRENT_CATALOG" ) {		val.ucs2(); // 0 terminate		r = SQLSetConnectAttr( hDbc, SQL_ATTR_CURRENT_CATALOG,#ifdef UNICODE				       (SQLWCHAR*) val.unicode(),#else				       (SQLCHAR*) val.latin1(),#endif				       SQL_NTS );	    } else if ( opt == "SQL_ATTR_METADATA_ID" ) {		if ( val == "SQL_TRUE" ) {		    v = SQL_TRUE;		} else if ( val == "SQL_FALSE" ) {		    v = SQL_FALSE;		} else {		    qWarning( QString( "QODBCDriver::open: Unknown option value '%1'" ).arg( *it ) );		    break;		}		r = SQLSetConnectAttr( hDbc, SQL_ATTR_METADATA_ID, (SQLPOINTER) v, 0 );	    } else if ( opt == "SQL_ATTR_PACKET_SIZE" ) {		v = val.toUInt();		r = SQLSetConnectAttr( hDbc, SQL_ATTR_PACKET_SIZE, (SQLPOINTER) v, 0 );	    } else if ( opt == "SQL_ATTR_TRACEFILE" ) {		val.ucs2(); // 0 terminate		r = SQLSetConnectAttr( hDbc, SQL_ATTR_TRACEFILE,#ifdef UNICODE				       (SQLWCHAR*) val.unicode(),#else				       (SQLCHAR*) val.latin1(),#endif				       SQL_NTS );	    } else if ( opt == "SQL_ATTR_TRACE" ) {		if ( val == "SQL_OPT_TRACE_OFF" ) {		    v = SQL_OPT_TRACE_OFF;		} else if ( val == "SQL_OPT_TRACE_ON" ) {		    v = SQL_OPT_TRACE_ON;		} else {		    qWarning( QString( "QODBCDriver::open: Unknown option value '%1'" ).arg( *it ) );		    break;		}		r = SQLSetConnectAttr( hDbc, SQL_ATTR_TRACE, (SQLPOINTER) v, 0 );	    }#ifdef QT_CHECK_RANGE              else {		  qWarning( QString("QODBCDriver::open: Unknown connection attribute '%1'").arg( opt ) );	    }#endif	    if ( r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO ) {#ifdef QT_CHECK_RANGE		qSqlWarning( QString("QODBCDriver::open: Unable to set connection attribute '%1'").arg( opt ), this );#endif		return FALSE;	    }	}    }    return TRUE;}void QODBCPrivate::splitTableQualifier(const QString & qualifier, QString &catalog,				       QString &schema, QString &table){    if (!useSchema) {	table = qualifier;	return;    }    QStringList l = QStringList::split( ".", qualifier, TRUE );    if ( l.count() > 3 )	return; // can't possibly be a valid table qualifier    int i = 0, n = l.count();    if ( n == 1 ) {	table = qualifier;    } else {	for ( QStringList::Iterator it = l.begin(); it != l.end(); ++it ) {	    if ( n == 3 ) {		if ( i == 0 ) {		    catalog = *it;		} else if ( i == 1 ) {		    schema = *it;		} else if ( i == 2 ) {		    table = *it;		}	    } else if ( n == 2 ) {		if ( i == 0 ) {		    schema = *it;		} else if ( i == 1 ) {		    table = *it;		}	    }	    i++;	}    }}////////////////////////////////////////////////////////////////////////////QODBCResult::QODBCResult( const QODBCDriver * db, QODBCPrivate* p ): QSqlResult(db){    d = new QODBCPrivate();    (*d) = (*p);    setExtension( new QODBCPreparedExtension( this ) );}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;    d->rInf.clear();    // Always reallocate the statement handle - the statement attributes    // are not reset if SQLFreeStmt() is called which causes some problems.    if ( d->hStmt ) {	r = SQLFreeHandle( SQL_HANDLE_STMT, d->hStmt );	if ( r != SQL_SUCCESS ) {#ifdef QT_CHECK_RANGE	    qSqlWarning( "QODBCResult::reset: Unable to free statement handle", d );#endif	    return FALSE;	}    }    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;    }    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::reset: Unable to set 'SQL_CURSOR_STATIC' as statement attribute. Please check your ODBC driver configuration", d );#endif	return FALSE;    }#ifdef UNICODE    r = SQLExecDirect( d->hStmt,		       (SQLWCHAR*) query.unicode(),		       (SQLINTEGER) query.length() );#else    QCString query8 = query.local8Bit();    r = SQLExecDirect( d->hStmt,                       (SQLCHAR*) query8.data(),                       (SQLINTEGER) query8.length() );#endif    if ( r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO ) {	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;}bool QODBCResult::fetch(int i){    if ( isForwardOnly() && i < at() )	return FALSE;    if ( i == at() )	return TRUE;    fieldCache.clear();    nullCache.clear();    int actualIdx = i + 1;    if ( actualIdx <= 0 ) {	setAt( QSql::BeforeFirst );	return FALSE;    }    SQLRETURN r;    if ( isForwardOnly() ) {	bool ok = TRUE;	while ( ok && i > at() )	    ok = fetchNext();	return ok;    } else {	r = SQLFetchScroll( d->hStmt,			    SQL_FETCH_ABSOLUTE,			    actualIdx );    }    if ( r != SQL_SUCCESS ){ 	return FALSE;    }    setAt( i );    return TRUE;}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();	if ( i == QSql::AfterLast )	    return FALSE;	if ( i == QSql::BeforeFirst )	    i = 0;	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 ( field >= (int) d->rInf.count() ) {	qWarning( "QODBCResult::data: column %d out of range", field );	return QVariant();    }    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::LongLong:	    fieldCache[ current ] = QVariant( (Q_LLONG) qGetBigIntData( d->hStmt, current, isNull ) );	    nullCache[ current ] = isNull;	    break;	case QVariant::Int:	    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:	    if ( info.typeID() == SQL_DECIMAL || info.typeID() == SQL_NUMERIC )		// bind Double values as string to prevent loss of precision		fieldCache[ current ] = QVariant( qGetStringData( d->hStmt, current,						  info.length() + 1, isNull, FALSE ) ); // length + 1 for the comma	    else		fieldCache[ current ] = QVariant( qGetDoubleData( d->hStmt, current, isNull ) );	    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 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 ( 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;	}    }    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,

⌨️ 快捷键说明

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