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

📄 qsql_ibase.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    return buffer;}QVariant QIBaseResultPrivate::fetchArray(int pos, ISC_QUAD *arr){    QList<QVariant> list;    ISC_ARRAY_DESC desc;    if (!arr)        return list;    QByteArray relname(sqlda->sqlvar[pos].relname, sqlda->sqlvar[pos].relname_length);    QByteArray sqlname(sqlda->sqlvar[pos].aliasname, sqlda->sqlvar[pos].aliasname_length);    isc_array_lookup_bounds(status, &ibase, &trans, relname.data(), sqlname.data(), &desc);    if (isError(QT_TRANSLATE_NOOP("QIBaseResult", "Could not find array"),                QSqlError::StatementError))        return list;    int arraySize = 1, subArraySize;    short dimensions = desc.array_desc_dimensions;    short *numElements = new short[dimensions];    for(int i = 0; i < dimensions; ++i) {        subArraySize = (desc.array_desc_bounds[i].array_bound_upper -                      desc.array_desc_bounds[i].array_bound_lower + 1);        numElements[i] = subArraySize;        arraySize = subArraySize * arraySize;    }    ISC_LONG bufLen;    QByteArray ba;    /* varying arrayelements are stored with 2 trailing null bytes       indicating the length of the string     */    if (desc.array_desc_dtype == blr_varying        || desc.array_desc_dtype == blr_varying2) {        desc.array_desc_length += 2;        bufLen = desc.array_desc_length * arraySize * sizeof(short);    } else {        bufLen = desc.array_desc_length *  arraySize;    }    ba.resize(int(bufLen));    isc_array_get_slice(status, &ibase, &trans, arr, &desc, ba.data(), &bufLen);    if (isError(QT_TRANSLATE_NOOP("QIBaseResult", "Could not get array data"),                QSqlError::StatementError))        return list;    readArrayBuffer(list, ba.data(), 0, numElements, &desc);    delete[] numElements;    return QVariant(list);}template<typename T>static char* fillList(char *buffer, const QList<QVariant> &list, T* = 0){    for (int i = 0; i < list.size(); ++i) {        T val;        val = qvariant_cast<T>(list.at(i));        memcpy(buffer, &val, sizeof(T));        buffer += sizeof(T);    }    return buffer;}template<>static char* fillList<float>(char *buffer, const QList<QVariant> &list, float*){    for (int i = 0; i < list.size(); ++i) {        double val;        float val2 = 0;        val = qvariant_cast<double>(list.at(i));        val2 = (float)val;        memcpy(buffer, &val2, sizeof(float));        buffer += sizeof(float);    }    return buffer;}static char* qFillBufferWithString(char *buffer, const QString& string, short buflen, bool varying, bool array){    QByteArray str = string.toUtf8(); // keep a copy of the string alive in this scope    if (varying) {        short tmpBuflen = buflen;        if (str.length() < buflen)            buflen = str.length();        if (array) { // interbase stores varying arrayelements different than normal varying elements            memcpy(buffer, str.data(), buflen);            memset(buffer + buflen, 0, tmpBuflen - buflen);        } else {            *(short*)buffer = buflen; // first two bytes is the length            memcpy(buffer + sizeof(short), str.data(), buflen);        }        buffer += tmpBuflen;    } else {        str = str.leftJustified(buflen, ' ', true);        memcpy(buffer, str.data(), buflen);        buffer += buflen;    }    return buffer;}static char* createArrayBuffer(char *buffer, const QList<QVariant> &list,                               QVariant::Type type, short curDim, ISC_ARRAY_DESC *arrayDesc,                               QString& error){    int i;    ISC_ARRAY_BOUND *bounds = arrayDesc->array_desc_bounds;    short dim = arrayDesc->array_desc_dimensions - 1;    int elements = (bounds[curDim].array_bound_upper -                    bounds[curDim].array_bound_lower + 1);    if (list.size() != elements) { // size mismatch        error = QLatin1String("Expected size: %1. Supplied size: %2");        error = QLatin1String("Array size mismatch. Fieldname: %1 ")                + error.arg(elements).arg(list.size());        return 0;    }    if (curDim != dim) {        for(i = 0; i < list.size(); ++i) {          if (list.at(i).type() != QVariant::List) { // dimensions mismatch              error = QLatin1String("Array dimensons mismatch. Fieldname: %1");              return 0;          }          buffer = createArrayBuffer(buffer, list.at(i).toList(), type, curDim + 1, arrayDesc,                                     error);          if (!buffer)              return 0;        }    } else {        switch(type) {        case QVariant::Int:        case QVariant::UInt:            if (arrayDesc->array_desc_dtype == blr_short)                buffer = fillList<short>(buffer, list);            else                buffer = fillList<int>(buffer, list);            break;        case QVariant::Double:            if (arrayDesc->array_desc_dtype == blr_float)                buffer = fillList<float>(buffer, list, static_cast<float *>(0));            else                buffer = fillList<double>(buffer, list);            break;        case QVariant::LongLong:            buffer = fillList<qint64>(buffer, list);            break;        case QVariant::ULongLong:            buffer = fillList<quint64>(buffer, list);            break;        case QVariant::String:            for (i = 0; i < list.size(); ++i)                buffer = qFillBufferWithString(buffer, list.at(i).toString(),                                               arrayDesc->array_desc_length,                                               arrayDesc->array_desc_dtype == blr_varying, true);            break;        case QVariant::Date:            for (i = 0; i < list.size(); ++i) {                *((ISC_DATE*)buffer) = toDate(list.at(i).toDate());                buffer += sizeof(ISC_DATE);            }            break;        case QVariant::Time:            for (i = 0; i < list.size(); ++i) {                *((ISC_TIME*)buffer) = toTime(list.at(i).toTime());                buffer += sizeof(ISC_TIME);            }            break;        case QVariant::DateTime:            for (i = 0; i < list.size(); ++i) {                *((ISC_TIMESTAMP*)buffer) = toTimeStamp(list.at(i).toDateTime());                buffer += sizeof(ISC_TIMESTAMP);            }            break;        default:            break;        }    }    return buffer;}bool QIBaseResultPrivate::writeArray(int column, const QList<QVariant> &list){    QString error;    ISC_QUAD *arrayId = (ISC_QUAD*) inda->sqlvar[column].sqldata;    ISC_ARRAY_DESC desc;    QByteArray relname(inda->sqlvar[column].relname, inda->sqlvar[column].relname_length);    QByteArray sqlname(inda->sqlvar[column].aliasname, inda->sqlvar[column].aliasname_length);    isc_array_lookup_bounds(status, &ibase, &trans, relname.data(), sqlname.data(), &desc);    if (isError(QT_TRANSLATE_NOOP("QIBaseResult", "Could not find array"),                QSqlError::StatementError))        return false;    short arraySize = 1;    ISC_LONG bufLen;    QList<QVariant> subList = list;    short dimensions = desc.array_desc_dimensions;    for(int i = 0; i < dimensions; ++i) {        arraySize *= (desc.array_desc_bounds[i].array_bound_upper -                      desc.array_desc_bounds[i].array_bound_lower + 1);    }    /* varying arrayelements are stored with 2 trailing null bytes       indicating the length of the string     */    if (desc.array_desc_dtype == blr_varying ||       desc.array_desc_dtype == blr_varying2)        desc.array_desc_length += 2;    bufLen = desc.array_desc_length * arraySize;    QByteArray ba;    ba.resize(int(bufLen));    if (list.size() > arraySize) {        error = QLatin1String("Array size missmatch: size of %1 is %2, size of provided list is %3");        error = error.arg(QLatin1String(sqlname)).arg(arraySize).arg(list.size());        q->setLastError(QSqlError(error, QLatin1String(""), QSqlError::StatementError));        return false;    }    if (!createArrayBuffer(ba.data(), list, qIBaseTypeName(desc.array_desc_dtype),                           0, &desc, error)) {        q->setLastError(QSqlError(error.arg(QLatin1String(sqlname)), QLatin1String(""),                        QSqlError::StatementError));        return false;    }    /* readjust the buffer size*/    if (desc.array_desc_dtype == blr_varying        || desc.array_desc_dtype == blr_varying2)        desc.array_desc_length -= 2;    isc_array_put_slice(status, &ibase, &trans, arrayId, &desc, ba.data(), &bufLen);    return true;}bool QIBaseResultPrivate::isSelect(){    char acBuffer[9];    char qType = isc_info_sql_stmt_type;    isc_dsql_sql_info(status, &stmt, 1, &qType, sizeof(acBuffer), acBuffer);    if (isError(QT_TRANSLATE_NOOP("QIBaseResult", "Could not get query info"),                QSqlError::StatementError))        return false;    int iLength = isc_vax_integer(&acBuffer[1], 2);    queryType = isc_vax_integer(&acBuffer[3], iLength);    return (queryType == isc_info_sql_stmt_select);}bool QIBaseResultPrivate::transaction(){    if (trans)        return true;    if (db->d->trans) {        localTransaction = false;        trans = db->d->trans;        return true;    }    localTransaction = true;    isc_start_transaction(status, &trans, 1, &ibase, 0, NULL);    if (isError(QT_TRANSLATE_NOOP("QIBaseResult", "Could not start transaction"),                QSqlError::TransactionError))        return false;    return true;}// does nothing if the transaction is on the// driver levelbool QIBaseResultPrivate::commit(){    if (!trans)        return false;    // don't commit driver's transaction, the driver will do it for us    if (!localTransaction)        return true;    isc_commit_transaction(status, &trans);    trans = 0;    return !isError(QT_TRANSLATE_NOOP("QIBaseResult", "Unable to commit transaction"),                    QSqlError::TransactionError);}//////////QIBaseResult::QIBaseResult(const QIBaseDriver* db):    QSqlCachedResult(db){    d = new QIBaseResultPrivate(this, db);}QIBaseResult::~QIBaseResult(){    delete d;}bool QIBaseResult::prepare(const QString& query){    //qDebug("prepare: %s\n", qPrintable(query));    if (!driver() || !driver()->isOpen() || driver()->isOpenError())        return false;    d->cleanup();    setActive(false);    setAt(QSql::BeforeFirstRow);    createDA(d->sqlda);    createDA(d->inda);    if (!d->transaction())        return false;    isc_dsql_allocate_statement(d->status, &d->ibase, &d->stmt);    if (d->isError(QT_TRANSLATE_NOOP("QIBaseResult", "Could not allocate statement"),                   QSqlError::StatementError))        return false;    isc_dsql_prepare(d->status, &d->trans, &d->stmt, 0,                     const_cast<char*>(query.toUtf8().constData()), FBVERSION, d->sqlda);    if (d->isError(QT_TRANSLATE_NOOP("QIBaseResult", "Could not prepare statement"),                   QSqlError::StatementError))        return false;    isc_dsql_describe_bind(d->status, &d->stmt, FBVERSION, d->inda);    if (d->isError(QT_TRANSLATE_NOOP("QIBaseResult",                    "Could not describe input statement"), QSqlError::StatementError))        return false;    if (d->inda->sqld > d->inda->sqln) {        enlargeDA(d->inda, d->inda->sqld);        isc_dsql_describe_bind(d->status, &d->stmt, FBVERSION, d->inda);        if (d->isError(QT_TRANSLATE_NOOP("QIBaseResult",                        "Could not describe input statement"), QSqlError::StatementError))            return false;    }    initDA(d->inda);    if (d->sqlda->sqld > d->sqlda->sqln) {        // need more field descriptors        enlargeDA(d->sqlda, d->sqlda->sqld);        isc_dsql_describe(d->status, &d->stmt, FBVERSION, d->sqlda);        if (d->isError(QT_TRANSLATE_NOOP("QIBaseResult", "Could not describe statement"),                       QSqlError::StatementError))            return false;    }    initDA(d->sqlda);    setSelect(d->isSelect());    if (!isSelect()) {        free(d->sqlda);        d->sqlda = 0;    }    return true;}bool QIBaseResult::exec(){    bool ok = true;    if (!d->trans)        d->transaction();    if (!driver() || !driver()->isOpen() || driver()->isOpenError())        return false;    setActive(false);    setAt(QSql::BeforeFirstRow);    if (d->inda) {        QVector<QVariant>& values = boundValues();        int i;        if (values.count() > d->inda->sqld) {            qWarning("QIBaseResult::exec: Parameter mismatch, expected %d, got %d parameters",                     d->inda->sqld, values.count());            return false;        }        int para = 0;        for (i = 0; i < values.count(); ++i) {            para = i;            if (!d->inda->sqlvar[para].sqldata)                // skip unknown datatypes                continue;            const QVariant val(values[i]);            if (d->inda->sqlvar[para].sqltype & 1) {                if (val.isNull()) {                    // set null indicator                    *(d->inda->sqlvar[para].sqlind) = -1;                    // and set the value to 0, otherwise it would count as empty string.                    // it seems to be working with just setting sqlind to -1                    //*((char*)d->inda->sqlvar[para].sqldata) = 0;                    continue;                }                // a value of 0 means non-null.                *(d->inda->sqlvar[para].sqlind) = 0;            }            switch(d->inda->sqlvar[para].sqltype & ~1) {            case SQL_INT64:                if (d->inda->sqlvar[para].sqlscale < 0)                    *((qint64*)d->inda->sqlvar[para].sqldata) =                        qint64(val.toDouble() * pow(10.0, d->inda->sqlvar[para].sqlscale * -1));                else                    *((qint64*)d->inda->sqlvar[para].sqldata) = val.toLongLong();                break;            case SQL_LONG:                *((long*)d->inda->sqlvar[para].sqldata) = (long)val.toLongLong();                break;            case SQL_SHORT:                *((short*)d->inda->sqlvar[para].sqldata) = (short)val.toInt();                break;            case SQL_FLOAT:                *((float*)d->inda->sqlvar[para].sqldata) = (float)val.toDouble();                break;            case SQL_DOUBLE:                *((double*)d->inda->sqlvar[para].sqldata) = val.toDouble();                break;            case SQL_TIMESTAMP:                *((ISC_TIMESTAMP*)d->inda->sqlvar[para].sqldata) = toTimeStamp(val.toDateTime());                break;            case SQL_TYPE_TIME:                *((ISC_TIME*)d->inda->sqlvar[para].sqldata) = toTime(val.toTime());                break;            case SQL_TYPE_DATE:                qDebug() << "bindig date";                *((ISC_DATE*)d->inda->sqlvar[para].sqldata) = toDate(val.toDate());                break;            case SQL_VARYING:            case SQL_TEXT:                qFillBufferWithString(d->inda->sqlvar[para].sqldata, val.toString(),                                      d->inda->sqlvar[para].sqllen,                                      (d->inda->sqlvar[para].sqltype & ~1) == SQL_VARYING, false);                break;            case SQL_BLOB:                    ok &= d->writeBlob(para, val.toByteArray());                    break;            case SQL_ARRAY:                    ok &= d->writeArray(para, val.toList());                    break;            default:                    qWarning("QIBaseResult::exec: Unknown datatype %d",                             d->inda->sqlvar[para].sqltype & ~1);                    break;            }        }    }    if (ok) {        if (colCount()) {            isc_dsql_free_statement(d->status, &d->stmt, DSQL_close);            if (d->isError(QT_TRANSLATE_NOOP("QIBaseResult", "Unable to close statement")))                return false;            cleanup();        }        isc_dsql_execute(d->status, &d->trans, &d->stmt, FBVERSION, d->inda);        if (d->isError(QT_TRANSLATE_NOOP("QIBaseResult", "Unable to execute query")))            return false;        if (d->sqlda)            init(d->sqlda->sqld);        if (d->queryType != isc_info_sql_stmt_select)             d->commit();        setActive(true);        return true;    }    return false;}bool QIBaseResult::reset (const QString& query){

⌨️ 快捷键说明

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