📄 qsql_odbc.cpp
字号:
SQLTCHAR connOut[1024]; r = SQLDriverConnect(d->hDbc, NULL,#ifdef UNICODE (SQLWCHAR*)connQStr.unicode(),#else (SQLCHAR*)connQStr.toLatin1().constData(),#endif (SQLSMALLINT)connQStr.length(), connOut, 1024, &cb, SQL_DRIVER_NOPROMPT); if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) { setLastError(qMakeError(tr("Unable to connect"), QSqlError::ConnectionError, d)); setOpenError(true); return false; } if (!d->checkDriver()) { setLastError(qMakeError(tr("Unable to connect - Driver doesn't support all " "needed functionality"), QSqlError::ConnectionError, d)); setOpenError(true); return false; } d->checkUnicode(); d->checkSchemaUsage(); d->checkMySqlServer(); setOpen(true); setOpenError(false); return true;}void QODBCDriver::close(){ cleanup(); setOpen(false); setOpenError(false);}void QODBCDriver::cleanup(){ SQLRETURN r; if (!d) return; if(d->hDbc) { // Open statements/descriptors handles are automatically cleaned up by SQLDisconnect if (isOpen()) { r = SQLDisconnect(d->hDbc); if (r != SQL_SUCCESS) qSqlWarning(QLatin1String("QODBCDriver::disconnect: Unable to disconnect datasource"), d); else d->disconnectCount++; } r = SQLFreeHandle(SQL_HANDLE_DBC, d->hDbc); if (r != SQL_SUCCESS) qSqlWarning(QLatin1String("QODBCDriver::cleanup: Unable to free connection handle"), d); d->hDbc = 0; } if (d->hEnv) { r = SQLFreeHandle(SQL_HANDLE_ENV, d->hEnv); if (r != SQL_SUCCESS) qSqlWarning(QLatin1String("QODBCDriver::cleanup: Unable to free environment handle"), d); d->hEnv = 0; }}// checks whether the server can return char, varchar and longvarchar// as two byte unicode charactersvoid QODBCDriverPrivate::checkUnicode(){#if defined(Q_WS_WIN) QT_WA( {}, { unicode = false; return; })#endif SQLRETURN r; SQLUINTEGER fFunc; unicode = false; 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; unicode = true; } 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; unicode = true; } 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; unicode = true; }}bool QODBCDriverPrivate::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); if (r != SQL_SUCCESS) { qSqlWarning(QLatin1String("QODBCDriver::checkDriver: Cannot get list of supported functions"), this); return false; } if (sup == SQL_FALSE) { 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]); return false; } } // these functions are optional and just generate a warning for (i = 0; optFunc[i] != 0; ++i) { r = SQLGetFunctions(hDbc, optFunc[i], &sup); if (r != SQL_SUCCESS) { qSqlWarning(QLatin1String("QODBCDriver::checkDriver: Cannot get list of supported functions"), this); return false; } if (sup == SQL_FALSE) { qWarning("QODBCDriver::checkDriver: Warning - Driver doesn't support some non-critical functions (%d)", optFunc[i]); return true; } }#endif //ODBC_CHECK_DRIVER return true;}void QODBCDriverPrivate::checkSchemaUsage(){ SQLRETURN r; SQLUINTEGER val; r = SQLGetInfo(hDbc, SQL_SCHEMA_USAGE, (SQLPOINTER) &val, sizeof(val), NULL); if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) useSchema = (val != 0);}void QODBCDriverPrivate::checkMySqlServer(){ SQLRETURN r; char serverString[20]; SQLSMALLINT t; r = SQLGetInfo(hDbc, SQL_DBMS_NAME, serverString, sizeof(serverString), &t); if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO)#ifdef UNICODE isMySqlServer = QString(reinterpret_cast<const QChar*>(serverString), t/sizeof(QChar)).contains(QLatin1String("mysql"), Qt::CaseInsensitive);#else isMySqlServer = QString::fromLocal8Bit(serverString, t).contains(QLatin1String("mysql"), Qt::CaseInsensitive);#endif}QSqlResult *QODBCDriver::createResult() const{ return new QODBCResult(this, d);}bool QODBCDriver::beginTransaction(){ if (!isOpen()) { qWarning(" QODBCDriver::beginTransaction: Database not open"); 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(tr("Unable to disable autocommit"), QSqlError::TransactionError, d)); return false; } return true;}bool QODBCDriver::commitTransaction(){ if (!isOpen()) { qWarning(" QODBCDriver::commitTransaction: Database not open"); return false; } SQLRETURN r = SQLEndTran(SQL_HANDLE_DBC, d->hDbc, SQL_COMMIT); if (r != SQL_SUCCESS) { setLastError(qMakeError(tr("Unable to commit transaction"), QSqlError::TransactionError, d)); return false; } return endTrans();}bool QODBCDriver::rollbackTransaction(){ if (!isOpen()) { qWarning(" QODBCDriver::rollbackTransaction: Database not open"); return false; } SQLRETURN r = SQLEndTran(SQL_HANDLE_DBC, d->hDbc, SQL_ROLLBACK); if (r != SQL_SUCCESS) { setLastError(qMakeError(tr("Unable to rollback transaction"), QSqlError::TransactionError, 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(tr("Unable to enable autocommit"), QSqlError::TransactionError, d)); return false; } return true;}QStringList QODBCDriver::tables(QSql::TableType type) const{ QStringList tl; if (!isOpen()) return tl; SQLHANDLE hStmt; SQLRETURN r = SQLAllocHandle(SQL_HANDLE_STMT, d->hDbc, &hStmt); if (r != SQL_SUCCESS) { qSqlWarning(QLatin1String("QODBCDriver::tables: Unable to allocate handle"), d); return tl; } r = SQLSetStmtAttr(hStmt, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER)SQL_CURSOR_FORWARD_ONLY, SQL_IS_UINTEGER); QString tableType; if (type & QSql::Tables) tableType += QLatin1String("TABLE,"); if (type & QSql::Views) tableType += QLatin1String("VIEW,"); if (type & QSql::SystemTables) tableType += QLatin1String("SYSTEM TABLE,"); if (tableType.isEmpty()) return tl; tableType.chop(1); r = SQLTables(hStmt, NULL, 0, NULL, 0, NULL, 0,#ifdef UNICODE (SQLWCHAR*)tableType.unicode(),#else (SQLCHAR*)tableType.toLatin1().constData(),#endif tableType.length() /* characters, not bytes */); if (r != SQL_SUCCESS) qSqlWarning(QLatin1String("QODBCDriver::tables Unable to execute table list"), d); r = SQLFetchScroll(hStmt, SQL_FETCH_NEXT, 0); while (r == SQL_SUCCESS) { QString fieldVal = qGetStringData(hStmt, 2, -1, d->unicode); tl.append(fieldVal); r = SQLFetchScroll(hStmt, SQL_FETCH_NEXT, 0); } r = SQLFreeHandle(SQL_HANDLE_STMT, hStmt); if (r!= SQL_SUCCESS) qSqlWarning(QLatin1String("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) { qSqlWarning(QLatin1String("QODBCDriver::primaryIndex: Unable to list primary key"), d); return index; } QString catalog, schema, table; d->splitTableQualifier(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.toLatin1().constData(),#endif catalog.length(),#ifdef UNICODE schema.length() == 0 ? NULL : (SQLWCHAR*)schema.unicode(),#else schema.length() == 0 ? NULL : (SQLCHAR*)schema.toLatin1().constData(),#endif schema.length(),#ifdef UNICODE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -