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

📄 qsql_odbc.cpp

📁 Linux下的基于X11的图形开发环境。
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		setOpenError( TRUE );		return FALSE;    }    QString connQStr;    // support the "DRIVER={SQL SERVER};SERVER=blah;" syntax//    QRegExp cr( "DRIVER\\s*=\\s*\\{.+\\}\\s*;\\s*SERVER\\s*=\\s*.+;" );    if ( db.contains(".dsn") ) {	connQStr = "FILEDSN=" + db;    } else if ( db.startsWith( "DRIVER" ) && db.contains( "SERVER" ) ) {	connQStr = db;    } else {	connQStr = "DSN=" + db;    }    connQStr += ";UID=" + user + ";PWD=" + password + ";";    SQLSMALLINT cb;    SQLTCHAR connOut[1024];    r = SQLDriverConnect( d->hDbc,			    NULL,#ifdef UNICODE			    (SQLWCHAR*)connQStr.unicode(),#else			    (SQLCHAR*)connQStr.latin1(),#endif			    (SQLSMALLINT)connQStr.length(),			    connOut,			    1024,			    &cb,			    SQL_DRIVER_NOPROMPT);    if ( r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO ) {	setLastError( qMakeError( "Unable to connect", QSqlError::Connection, d ) );	setOpenError( TRUE );	return FALSE;    }    if ( !d->checkDriver() ) {	setLastError( qMakeError( "Unable to connect - Driver doesn't support all needed functionality", QSqlError::Connection, d ) );	setOpenError( TRUE );	return FALSE;    }    d->checkUnicode();    setOpen( TRUE );    return TRUE;}void QODBCDriver::close(){    cleanup();    setOpen( FALSE );    setOpenError( FALSE );}void QODBCDriver::cleanup(){    SQLRETURN r;    if ( (isOpen() || isOpenError()) && (d != 0)) {	if( d->hDbc ) {	    // Open statements/descriptors handles are automatically cleaned up by SQLDisconnect	    r = SQLDisconnect( d->hDbc );#ifdef QT_CHECK_RANGE	    if ( r != SQL_SUCCESS )		qSqlWarning( "QODBCDriver::disconnect: Unable to disconnect datasource", d );#endif		r = SQLFreeHandle( SQL_HANDLE_DBC, d->hDbc );#ifdef QT_CHECK_RANGE		if ( r != SQL_SUCCESS )		    qSqlWarning( "QODBCDriver::cleanup: Unable to free connection handle", d );#endif		    d->hDbc = 0;		}		if ( d->hEnv ) {		    r = SQLFreeHandle( SQL_HANDLE_ENV, d->hEnv );#ifdef QT_CHECK_RANGE		    if ( r != SQL_SUCCESS )			qSqlWarning( "QODBCDriver::cleanup: Unable to free environment handle", d );#endif		    d->hEnv = 0;		}    }}// checks whether the server can return char, varchar and longvarchar// as two byte unicode charactersvoid QODBCPrivate::checkUnicode(){#if defined(Q_WS_WIN)    if ( !qt_winunicode ) {	unicode = FALSE;	return;    }#endif    SQLRETURN   r;    SQLUINTEGER fFunc;    unicode = TRUE;    r = SQLGetInfo( hDbc, 		    SQL_CONVERT_CHAR,		    (SQLPOINTER)&fFunc,		    sizeof(fFunc),		    NULL );    if ( ( r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO ) && ( fFunc & SQL_CVT_WCHAR ) ) {	sql_char_type = QVariant::String;    } else {	unicode = FALSE;    }    r = SQLGetInfo( hDbc, 		    SQL_CONVERT_VARCHAR,		    (SQLPOINTER)&fFunc,		    sizeof(fFunc),		    NULL );    if ( ( r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO ) && ( fFunc & SQL_CVT_WVARCHAR ) ) {	sql_varchar_type = QVariant::String;    } else {	unicode = FALSE;    }    r = SQLGetInfo( hDbc,		    SQL_CONVERT_LONGVARCHAR,		    (SQLPOINTER)&fFunc,		    sizeof(fFunc),		    NULL );    if ( ( r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO ) && ( fFunc & SQL_CVT_WLONGVARCHAR ) ) {	sql_longvarchar_type = QVariant::String;    } else {	unicode = FALSE;    }}bool QODBCPrivate::checkDriver() const{#ifdef ODBC_CHECK_DRIVER    // do not query for SQL_API_SQLFETCHSCROLL because it can't be used at this time    static const SQLUSMALLINT reqFunc[] = {		SQL_API_SQLDESCRIBECOL, SQL_API_SQLGETDATA, SQL_API_SQLCOLUMNS, 		SQL_API_SQLGETSTMTATTR, SQL_API_SQLGETDIAGREC, SQL_API_SQLEXECDIRECT,		SQL_API_SQLGETINFO, SQL_API_SQLTABLES, 0    };    // these functions are optional    static const SQLUSMALLINT optFunc[] = {    		SQL_API_SQLNUMRESULTCOLS, SQL_API_SQLROWCOUNT, 0    };    SQLRETURN r;    SQLUSMALLINT sup;        int i;    // check the required functions    for ( i = 0; reqFunc[ i ] != 0; ++i ) {	r = SQLGetFunctions( hDbc, reqFunc[ i ], &sup );#ifdef QT_CHECK_RANGE        if ( r != SQL_SUCCESS ) {	    qSqlWarning( "QODBCDriver::checkDriver: Cannot get list of supported functions", this );	    return FALSE;	}#endif	if ( sup == SQL_FALSE ) {#ifdef QT_CHECK_RANGE	    qWarning ( "QODBCDriver::open: Warning - Driver doesn't support all needed functionality (%d). "		       "Please look at the Qt SQL Module Driver documentation for more information.", reqFunc[ i ] );#endif	    return FALSE;	}    }    // these functions are optional and just generate a warning    for ( i = 0; optFunc[ i ] != 0; ++i ) {	r = SQLGetFunctions( hDbc, optFunc[ i ], &sup );#ifdef QT_CHECK_RANGE        if ( r != SQL_SUCCESS ) {	    qSqlWarning( "QODBCDriver::checkDriver: Cannot get list of supported functions", this );	    return FALSE;	}#endif	if ( sup == SQL_FALSE ) {#ifdef QT_CHECK_RANGE	    qWarning( "QODBCDriver::checkDriver: Warning - Driver doesn't support some non-critical functions (%d)", optFunc[ i ] );#endif	    return TRUE;	}    }#endif //ODBC_CHECK_DRIVER    return TRUE;}QSqlQuery QODBCDriver::createQuery() const{    return QSqlQuery( new QODBCResult( this, d ) );}bool QODBCDriver::beginTransaction(){    if ( !isOpen() ) {#ifdef QT_CHECK_RANGE	qWarning(" QODBCDriver::beginTransaction: Database not open" );#endif	return FALSE;    }    SQLUINTEGER ac(SQL_AUTOCOMMIT_OFF);    SQLRETURN r  = SQLSetConnectAttr( d->hDbc,				      SQL_ATTR_AUTOCOMMIT,				      (SQLPOINTER)ac,				      sizeof(ac));    if ( r != SQL_SUCCESS ) {	setLastError( qMakeError( "Unable to disable autocommit", QSqlError::Transaction, d ) );	return FALSE;    }    return TRUE;}bool QODBCDriver::commitTransaction(){    if ( !isOpen() ) {#ifdef QT_CHECK_RANGE	qWarning(" QODBCDriver::commitTransaction: Database not open" );#endif	return FALSE;    }    SQLRETURN r = SQLEndTran( SQL_HANDLE_ENV,			      d->hEnv,			      SQL_COMMIT);    if ( r != SQL_SUCCESS ) {	setLastError( qMakeError("Unable to commit transaction", QSqlError::Transaction, d ) );	return FALSE;    }    return endTrans();}bool QODBCDriver::rollbackTransaction(){    if ( !isOpen() ) {#ifdef QT_CHECK_RANGE	qWarning(" QODBCDriver::rollbackTransaction: Database not open" );#endif	return FALSE;    }    SQLRETURN r = SQLEndTran( SQL_HANDLE_ENV,			      d->hEnv,			      SQL_ROLLBACK);    if ( r != SQL_SUCCESS ) {	setLastError( qMakeError( "Unable to rollback transaction", QSqlError::Transaction, d ) );	return FALSE;    }    return endTrans();}bool QODBCDriver::endTrans(){    SQLUINTEGER ac(SQL_AUTOCOMMIT_ON);    SQLRETURN r  = SQLSetConnectAttr( d->hDbc,				      SQL_ATTR_AUTOCOMMIT,				      (SQLPOINTER)ac,				      sizeof(ac));    if ( r != SQL_SUCCESS ) {	setLastError( qMakeError( "Unable to enable autocommit", QSqlError::Transaction, d ) );	return FALSE;    }    return TRUE;}QStringList QODBCDriver::tables( const QString& /* user */ ) const{    QStringList tl;    if ( !isOpen() )	return tl;    SQLHANDLE hStmt;    SQLRETURN r = SQLAllocHandle( SQL_HANDLE_STMT,				  d->hDbc,				  &hStmt );    if ( r != SQL_SUCCESS ) {#ifdef QT_CHECK_RANGE	qSqlWarning( "QODBCDriver::tables: Unable to allocate handle", d );#endif	return tl;    }    r = SQLSetStmtAttr( hStmt,			SQL_ATTR_CURSOR_TYPE,			(SQLPOINTER)SQL_CURSOR_FORWARD_ONLY,			SQL_IS_UINTEGER );    // Prevent SQLTables to display all the system tables    QString tableType = "TABLE";    r = SQLTables( hStmt,		   NULL,		   0,		   NULL,		   0,		   NULL,		   0,#ifdef UNICODE		   (SQLWCHAR*)tableType.unicode(),#else		   (SQLCHAR*)tableType.latin1(),#endif		   tableType.length() /* characters, not bytes */ );#ifdef QT_CHECK_RANGE    if ( r != SQL_SUCCESS )	qSqlWarning( "QODBCDriver::tables Unable to execute table list", d );#endif    r = SQLFetchScroll( hStmt,			SQL_FETCH_NEXT,			0);    while ( r == SQL_SUCCESS ) {	bool isNull;	QString fieldVal = qGetStringData( hStmt, 2, -1, isNull, d->unicode );	tl.append( fieldVal );	r = SQLFetchScroll( hStmt,			    SQL_FETCH_NEXT,			    0);    }    r = SQLFreeHandle( SQL_HANDLE_STMT, hStmt );    if ( r!= SQL_SUCCESS )	qSqlWarning( "QODBCDriver: Unable to free statement handle" + QString::number(r), d );    return tl;}QSqlIndex QODBCDriver::primaryIndex( const QString& tablename ) const{    QSqlIndex index( tablename );    if ( !isOpen() )	return index;    bool usingSpecialColumns = FALSE;    QSqlRecord rec = record( tablename );    SQLHANDLE hStmt;    SQLRETURN r = SQLAllocHandle( SQL_HANDLE_STMT,				  d->hDbc,				  &hStmt );    if ( r != SQL_SUCCESS ) {#ifdef QT_CHECK_RANGE	qSqlWarning( "QODBCDriver::primaryIndex: Unable to list primary key", d );#endif	return index;    }    QString catalog, schema, table;    qSplitTableQualifier( tablename, &catalog, &schema, &table );    r = SQLSetStmtAttr( hStmt,			SQL_ATTR_CURSOR_TYPE,			(SQLPOINTER)SQL_CURSOR_FORWARD_ONLY,			SQL_IS_UINTEGER );    r = SQLPrimaryKeys( hStmt,#ifdef UNICODE			catalog.length() == 0 ? NULL : (SQLWCHAR*)catalog.unicode(),#else			catalog.length() == 0 ? NULL : (SQLCHAR*)catalog.latin1(),#endif			catalog.length(),#ifdef UNICODE			schema.length() == 0 ? NULL : (SQLWCHAR*)schema.unicode(),#else			schema.length() == 0 ? NULL : (SQLCHAR*)schema.latin1(),#endif			schema.length(),#ifdef UNICODE			(SQLWCHAR*)table.unicode(),#else			(SQLCHAR*)table.latin1(),#endif			table.length() /* in characters, not in bytes */);        // if the SQLPrimaryKeys() call does not succeed (e.g the driver    // does not support it) - try an alternative method to get hold of    // the primary index (e.g MS Access and FoxPro)    if ( r != SQL_SUCCESS ) {	    r = SQLSpecialColumns( hStmt,				   SQL_BEST_ROWID,#ifdef UNICODE				   catalog.length() == 0 ? NULL : (SQLWCHAR*)catalog.unicode(),#else				   catalog.length() == 0 ? NULL : (SQLCHAR*)catalog.latin1(),#endif				   catalog.length(),#ifdef UNICODE				   schema.length() == 0 ? NULL : (SQLWCHAR*)schema.unicode(),#else				   schema.length() == 0 ? NULL : (SQLCHAR*)schema.latin1(),#endif				   schema.length(),#ifdef UNICODE				   (SQLWCHAR*)table.unicode(),#else				   (SQLCHAR*)table.latin1(),#endif				   				   table.length(),				   SQL_SCOPE_CURROW,				   SQL_NULLABLE );	    if ( r != SQL_SUCCESS ) {#ifdef QT_CHECK_RANGE		qSqlWarning( "QODBCDriver::primaryIndex: Unable to execute primary key list", d );#endif	    } else {		usingSpecialColumns = TRUE;	    }    }    r = SQLFetchScroll( hStmt,			SQL_FETCH_NEXT,			0 );    bool isNull;    int fakeId = 0;    QString cName, idxName;    // Store all fields in a StringList because some drivers can't detail fields in this FETCH loop    while ( r == SQL_SUCCESS ) {	if ( usingSpecialColumns ) {	    cName = qGetStringData( hStmt, 1, -1, isNull, d->unicode ); // column name	    idxName = QString::number( fakeId++ ); // invent a fake index name	} else {	    cName = qGetStringData( hStmt, 3, -1, isNull, d->unicode ); // column name	    idxName = qGetStringData( hStmt, 5, -1, isNull, d->unicode ); // pk index name	}	index.append( *(rec.field( cName )) );	index.setName( idxName );	r = SQLFetchScroll( hStmt,			    SQL_FETCH_NEXT,			    0 );    }    r = SQLFreeHandle( SQL_HANDLE_STMT, hStmt );    if ( r!= SQL_SUCCESS )	qSqlWarning( "QODBCDriver: Unable to free statement handle" + QString::number(r), d );    return index;}QSqlRecord QODBCDriver::record( const QString& tablename ) const{    return recordInfo( tablename ).toRecord();}QSqlRecord QODBCDriver::record( const QSqlQuery& query ) const{    return recordInfo( query ).toRecord();}QSqlRecordInfo QODBCDriver::recordInfo( const QString& tablename ) const{    QSqlRecordInfo fil;    if ( !isOpen() )	return fil;    SQLHANDLE hStmt;    QString catalog, schema, table;    qSplitTableQualifier( tablename, &catalog, &schema, &table );    SQLRETURN r = SQLAllocHandle( SQL_HANDLE_STMT,				  d->hDbc,				  &hStmt );    if ( r != SQL_SUCCESS ) {#ifdef QT_CHECK_RANGE	qSqlWarning( "QODBCDriver::record: Unable to allocate handle", d );#endif	return fil;    }    r = SQLSetStmtAttr( hStmt,			SQL_ATTR_CURSOR_TYPE,			(SQLPOINTER)SQL_CURSOR_FORWARD_ONLY,			SQL_IS_UINTEGER );    r =  SQLColumns( hStmt,#ifdef UNICODE		     catalog.length() == 0 ? NULL : (SQLWCHAR*)catalog.unicode(),#else		     catalog.length() == 0 ? NULL : (SQLCHAR*)catalog.latin1(),#endif		     catalog.length(),#ifdef UNICODE		     schema.length() == 0 ? NULL : (SQLWCHAR*)schema.unicode(),#else		     schema.length() == 0 ? NULL : (SQLCHAR*)schema.latin1(),#endif		     schema.length(),#ifdef UNICODE		     (SQLWCHAR*)table.unicode(),#else		     (SQLCHAR*)table.latin1(),#endif		     table.length(),		     NULL,		     0 );#ifdef QT_CHECK_RANGE    if ( r != SQL_SUCCESS )	qSqlWarning( "QODBCDriver::record: Unable to execute column list", d );#endif    r = SQLFetchScroll( hStmt,			SQL_FETCH_NEXT,			0);    // Store all fields in a StringList because some drivers can't detail fields in this FETCH loop    while ( r == SQL_SUCCESS ) {	fil.append( qMakeFieldInfo( hStmt, d ) );	r = SQLFetchScroll( hStmt,			    SQL_FETCH_NEXT,			    0);    }    r = SQLFreeHandle( SQL_HANDLE_STMT, hStmt );    if ( r!= SQL_SUCCESS )	qSqlWarning( "QODBCDriver: Unable to free statement handle " + QString::number(r), d );    return fil;}QSqlRecordInfo QODBCDriver::recordInfo( const QSqlQuery& query ) const{    QSqlRecordInfo fil;    if ( !isOpen() )	return fil;    if ( query.isActive() && query.driver() == this ) {	QODBCResult* result = (QODBCResult*)query.result();	fil = result->d->rInf;    }    return fil;}SQLHANDLE QODBCDriver::environment(){    return d->hEnv;}SQLHANDLE QODBCDriver::connection(){    return d->hDbc;}QString QODBCDriver::formatValue( const QSqlField* field,				  bool trimStrings ) const{    QString r;    if ( field->isNull() ) {	r = nullText();    } else if ( field->type() == QVariant::DateTime ) {	// Use an escape sequence for the datetime fields	if ( field->value().toDateTime().isValid() ){	    QDate dt = field->value().toDateTime().date();	    QTime tm = field->value().toDateTime().time();		    // Dateformat has to be "yyyy-MM-dd hh:mm:ss", with leading zeroes if month or day < 10	    r = "{ ts '" +		QString::number(dt.year()) + "-" +		QString::number(dt.month()).rightJustify( 2, '0', TRUE ) + "-" +		QString::number(dt.day()).rightJustify( 2, '0', TRUE ) + " " +		tm.toString() +		"' }";	} else	    r = nullText();    } else if ( field->type() == QVariant::ByteArray ) {		QByteArray ba = field->value().toByteArray();	QString res;	static const char hexchars[] = "0123456789abcdef";	for ( uint i = 0; i < ba.size(); ++i ) {	    uchar s = (uchar) ba[(int)i];	    res += hexchars[s >> 4];	    res += hexchars[s & 0x0f];	}	r = "0x" + res;    } else {	r = QSqlDriver::formatValue( field, trimStrings );    }    return r;}

⌨️ 快捷键说明

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