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

📄 qsql_odbc.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                r = SQLBindParameter(d->hStmt,                                      i + 1,                                      qParamType[(QFlag)(bindValueType(i)) & QSql::InOut],                                      SQL_C_BINARY,                                      SQL_LONGVARBINARY,                                      val.toByteArray().size(),                                      0,                                      (void *) val.toByteArray().constData(),                                      val.toByteArray().size(),                                      ind);                break;#ifndef Q_ODBC_VERSION_2            case QVariant::String:                if (d->unicode) {                    QString str = val.toString();                    str.utf16();                    if (*ind != SQL_NULL_DATA)                        *ind = str.length() * sizeof(QChar);                    if (bindValueType(i) & QSql::Out) {                        QByteArray ba((char*)str.constData(), str.capacity() * sizeof(QChar));                        r = SQLBindParameter(d->hStmt,                                            i + 1,                                            qParamType[(QFlag)(bindValueType(i)) & QSql::InOut],                                            SQL_C_WCHAR,                                            str.length() > 4000 ? SQL_WLONGVARCHAR : SQL_WVARCHAR,                                            0, // god knows... don't change this!                                            0,                                            (void *)ba.constData(),                                            ba.size(),                                            ind);                        tmpStorage.append(ba);                        break;                    }                    r = SQLBindParameter(d->hStmt,                                          i + 1,                                          qParamType[(QFlag)(bindValueType(i)) & QSql::InOut],                                          SQL_C_WCHAR,                                          str.length() > 4000 ? SQL_WLONGVARCHAR : SQL_WVARCHAR,                                          str.length() * sizeof(QChar),                                          0,                                          (void *)str.constData(),                                          str.length() * sizeof(QChar),                                          ind);                    break;                }#endif            // fall through            default: {                QByteArray ba = val.toString().toAscii();                if (*ind != SQL_NULL_DATA)                    *ind = ba.size();                r = SQLBindParameter(d->hStmt,                                      i + 1,                                      qParamType[(QFlag)(bindValueType(i)) & QSql::InOut],                                      SQL_C_CHAR,                                      ba.length() > 4000 ? SQL_LONGVARCHAR : SQL_VARCHAR,                                      ba.length() + 1,                                      0,                                      (void *) ba.constData(),                                      ba.length() + 1,                                      ind);                tmpStorage.append(ba);                break; }        }        if (r != SQL_SUCCESS) {            qWarning("QODBCResult::exec: unable to bind variable: %s",                     qODBCWarn(d).toLocal8Bit().constData());            setLastError(qMakeError(QCoreApplication::translate("QODBCResult",                         "Unable to bind variable"), QSqlError::StatementError, d));            return false;        }    }    r = SQLExecute(d->hStmt);    if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) {        qWarning("QODBCResult::exec: Unable to execute statement: %s",                 qODBCWarn(d).toLocal8Bit().constData());        setLastError(qMakeError(QCoreApplication::translate("QODBCResult",                     "Unable to execute statement"), QSqlError::StatementError, 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));        }	d->fieldCache.resize(count);    } else {        setSelect(false);    }    setActive(true);    //get out parameters    if (!hasOutValues())        return true;    for (i = 0; i < values.count(); ++i) {        switch (values.at(i).type()) {            case QVariant::Date: {                DATE_STRUCT ds = *((DATE_STRUCT *)tmpStorage.takeFirst().constData());                values[i] = QVariant(QDate(ds.year, ds.month, ds.day));                break; }            case QVariant::Time: {                TIME_STRUCT dt = *((TIME_STRUCT *)tmpStorage.takeFirst().constData());                values[i] = QVariant(QTime(dt.hour, dt.minute, dt.second));                break; }            case QVariant::DateTime: {                TIMESTAMP_STRUCT dt = *((TIMESTAMP_STRUCT*)                                        tmpStorage.takeFirst().constData());                values[i] = QVariant(QDateTime(QDate(dt.year, dt.month, dt.day),                               QTime(dt.hour, dt.minute, dt.second, dt.fraction / 1000000)));                break; }            case QVariant::Int:            case QVariant::Double:            case QVariant::ByteArray:                //nothing to do                break;            case QVariant::String:                if (d->unicode) {                    if (bindValueType(i) & QSql::Out)                        values[i] = QString::fromUtf16((ushort*)tmpStorage.takeFirst().constData());                    break;                }                // fall through            default: {                QByteArray ba = tmpStorage.takeFirst();                if (bindValueType(i) & QSql::Out)                    values[i] = QString::fromAscii(tmpStorage.takeFirst().constData());                break; }        }        if (indicators[i] == SQL_NULL_DATA)            values[i] = QVariant(values[i].type());    }    return true;}QSqlRecord QODBCResult::record() const{    if (!isActive() || !isSelect())        return QSqlRecord();    return d->rInf;}QVariant QODBCResult::handle() const{    return QVariant(qRegisterMetaType<SQLHANDLE>("SQLHANDLE"), &d->hStmt);}////////////////////////////////////////QODBCDriver::QODBCDriver(QObject *parent)    : QSqlDriver(parent){    init();}QODBCDriver::QODBCDriver(SQLHANDLE env, SQLHANDLE con, QObject * parent)    : QSqlDriver(parent){    init();    d->hEnv = env;    d->hDbc = con;    if (env && con) {        setOpen(true);        setOpenError(false);    }}void QODBCDriver::init(){    d = new QODBCDriverPrivate();}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 Unicode:        return d->unicode;    case PreparedQueries:    case BLOB:    case PositionalPlaceholders:        return true;    case QuerySize:    case NamedPlaceholders:    case LastInsertId:    case BatchOperations:        return false;    }    return false;}bool QODBCDriver::open(const QString & db,                        const QString & user,                        const QString & password,                        const QString &,                        int,                        const QString& connOpts){    if (isOpen())      close();    SQLRETURN r;    r = SQLAllocHandle(SQL_HANDLE_ENV,                        SQL_NULL_HANDLE,                        &d->hEnv);    if (r != SQL_SUCCESS && r != SQL_SUCCESS_WITH_INFO) {        qSqlWarning(QLatin1String("QODBCDriver::open: Unable to allocate environment"), d);        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 && r != SQL_SUCCESS_WITH_INFO) {        qSqlWarning(QLatin1String("QODBCDriver::open: Unable to allocate connection"), d);        setOpenError(true);        return false;    }    if (!d->setConnectionOptions(connOpts))        return false;    // Create the connection string    QString connQStr;    // support the "DRIVER={SQL SERVER};SERVER=blah" syntax    if (db.contains(QLatin1String(".dsn")))        connQStr = QLatin1String("FILEDSN=") + db;    else if (db.contains(QLatin1String("DRIVER")) || db.contains(QLatin1String("SERVER")))        connQStr = db;    else        connQStr = QLatin1String("DSN=") + db;    connQStr += QLatin1String(";UID=") + user + QLatin1String(";PWD=") + password;    SQLSMALLINT cb;    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();    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);        }        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,

⌨️ 快捷键说明

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