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

📄 qsql_ibase.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 4 页
字号:
{    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*>(encodeString(d->tc, query).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:                if (d->inda->sqlvar[para].sqlscale < 0)                    *((long*)d->inda->sqlvar[para].sqldata) =                         (long)(val.toDouble() * pow(10.0, d->inda->sqlvar[para].sqlscale * -1));                else                    *((long*)d->inda->sqlvar[para].sqldata) = (long)val.toLongLong();                break;            case SQL_SHORT:                if (d->inda->sqlvar[para].sqlscale < 0)                    *((short*)d->inda->sqlvar[para].sqldata) =                         (short)(val.toDouble() * pow(10.0, d->inda->sqlvar[para].sqlscale * -1));                else                    *((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:                *((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, d->tc);                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();        }        if (d->queryType == isc_info_sql_stmt_exec_procedure)            isc_dsql_execute2(d->status, &d->trans, &d->stmt, FBVERSION, d->inda, d->sqlda);        else            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;        // Not all stored procedures necessarily return values.        if (d->queryType == isc_info_sql_stmt_exec_procedure && d->sqlda->sqld == 0)            delDA(d->sqlda);        if (d->sqlda)            init(d->sqlda->sqld);        if (!isSelect())             d->commit();        setActive(true);        return true;    }    return false;}bool QIBaseResult::reset (const QString& query){    if (!prepare(query))        return false;    return exec();}bool QIBaseResult::gotoNext(QSqlCachedResult::ValueCache& row, int rowIdx){    ISC_STATUS stat = 0;    // Stored Procedures are special - they populate our d->sqlda when executing,    // so we don't have to call isc_dsql_fetch    if (d->queryType == isc_info_sql_stmt_exec_procedure) {        // the first "fetch" shall succeed, all consecutive ones will fail since        // we only have one row to fetch for stored procedures        if (rowIdx != 0)            stat = 100;    } else {        stat = isc_dsql_fetch(d->status, &d->stmt, FBVERSION, d->sqlda);    }    if (stat == 100) {        // no more rows        setAt(QSql::AfterLastRow);        return false;    }    if (d->isError(QT_TRANSLATE_NOOP("QIBaseResult", "Could not fetch next item"),                   QSqlError::StatementError))        return false;    if (rowIdx < 0) // not interested in actual values        return true;    for (int i = 0; i < d->sqlda->sqld; ++i) {        int idx = rowIdx + i;        char *buf = d->sqlda->sqlvar[i].sqldata;        int size = d->sqlda->sqlvar[i].sqllen;        Q_ASSERT(buf);        if ((d->sqlda->sqlvar[i].sqltype & 1) && *d->sqlda->sqlvar[i].sqlind) {            // null value            QVariant v;            v.convert(qIBaseTypeName2(d->sqlda->sqlvar[i].sqltype, d->sqlda->sqlvar[i].sqlscale < 0));            row[idx] = v;            continue;        }        switch(d->sqlda->sqlvar[i].sqltype & ~1) {        case SQL_VARYING:            // pascal strings - a short with a length information followed by the data            if (d->tc)                row[idx] = d->tc->toUnicode(buf + sizeof(short), *(short*)buf);            else                row[idx] = QString::fromUtf8(buf + sizeof(short), *(short*)buf);            break;        case SQL_INT64:            if (d->sqlda->sqlvar[i].sqlscale < 0)                row[idx] = *(qint64*)buf * pow(10.0, d->sqlda->sqlvar[i].sqlscale);            else                row[idx] = QVariant(*(qint64*)buf);            break;        case SQL_LONG:            if (d->sqlda->sqlvar[i].sqllen == 4)                if (d->sqlda->sqlvar[i].sqlscale < 0)                    row[idx] = QVariant(*(qint32*)buf * pow(10.0, d->sqlda->sqlvar[i].sqlscale));                else                    row[idx] = QVariant(*(qint32*)buf);            else                row[idx] = QVariant(*(qint64*)buf);            break;        case SQL_SHORT:            if (d->sqlda->sqlvar[i].sqlscale < 0)                row[idx] = QVariant(long((*(short*)buf)) * pow(10.0, d->sqlda->sqlvar[i].sqlscale));            else                row[idx] = QVariant(int((*(short*)buf)));            break;        case SQL_FLOAT:            row[idx] = QVariant(double((*(float*)buf)));            break;        case SQL_DOUBLE:            row[idx] = QVariant(*(double*)buf);            break;        case SQL_TIMESTAMP:            row[idx] = fromTimeStamp(buf);            break;        case SQL_TYPE_TIME:            row[idx] = fromTime(buf);            break;        case SQL_TYPE_DATE:            row[idx] = fromDate(buf);            break;        case SQL_TEXT:            if (d->tc)                row[idx] = d->tc->toUnicode(buf, size);            else                row[idx] = QString::fromUtf8(buf, size);            break;        case SQL_BLOB:            row[idx] = d->fetchBlob((ISC_QUAD*)buf);            break;        case SQL_ARRAY:            row[idx] = d->fetchArray(i, (ISC_QUAD*)buf);            break;        default:            // unknown type - don't even try to fetch            row[idx] = QVariant();            break;        }    }    return true;}int QIBaseResult::size(){    return -1;#if 0 /// ### FIXME    static char sizeInfo[] = {isc_info_sql_records};    char buf[64];    //qDebug() << sizeInfo;    if (!isActive() || !isSelect())        return -1;        char ct;        short len;        int val = 0;//    while(val == 0) {        isc_dsql_sql_info(d->status, &d->stmt, sizeof(sizeInfo), sizeInfo, sizeof(buf), buf);//        isc_database_info(d->status, &d->ibase, sizeof(sizeInfo), sizeInfo, sizeof(buf), buf);        for(int i = 0; i < 66; ++i)            qDebug() << QString::number(buf[i]);        for (char* c = buf + 3; *c != isc_info_end; /*nothing*/) {            ct = *(c++);            len = isc_vax_integer(c, 2);            c += 2;            val = isc_vax_integer(c, len);            c += len;            qDebug() << "size" << val;            if (ct == isc_info_req_select_count)                return val;        }        //qDebug() << "size -1";        return -1;        unsigned int i, result_size;        if (buf[0] == isc_info_sql_records) {            i = 3;            result_size = isc_vax_integer(&buf[1],2);            while (buf[i] != isc_info_end && i < result_size) {                len = (short)isc_vax_integer(&buf[i+1],2);                if (buf[i] == isc_info_req_select_count)                     return (isc_vax_integer(&buf[i+3],len));                i += len+3;           }        }//    }

⌨️ 快捷键说明

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