bool QTDSResult::reset (const QString& query) { cleanup(); if (!driver() || !driver()-> isOpen() || driver()->isOpenError()) return false; setActive(false); setAt(QSql::BeforeFirstRow); if (dbcmd(d->dbproc, const_cast<char*>(query.toLocal8Bit().constData())) == FAIL) { setLastError(d->lastError); return false; } if (dbsqlexec(d->dbproc) == FAIL) { setLastError(d->lastError); dbfreebuf(d->dbproc); return false; } if (dbresults(d->dbproc) != SUCCEED) { setLastError(d->lastError); dbfreebuf(d->dbproc); return false; } setSelect((DBCMDROW(d->dbproc) == SUCCEED)); // decide whether or not we are dealing with a SELECT query int numCols = dbnumcols(d->dbproc); if (numCols > 0) { d->buffer.resize(numCols * 2); init(numCols); } for (int i = 0; i < numCols; ++i) { int dbType = dbcoltype(d->dbproc, i+1); QVariant::Type vType = qDecodeTDSType(dbType); QSqlField f(QString::fromAscii(dbcolname(d->dbproc, i+1)), vType); f.setSqlType(dbType); f.setLength(dbcollen(d->dbproc, i+1)); d->rec.append(f); RETCODE ret = -1; void* p = 0; switch (vType) { case QVariant::Int: p = malloc(4); ret = dbbind(d->dbproc, i+1, INTBIND, (DBINT) 4, (unsigned char *)p); break; case QVariant::Double: // use string binding to prevent loss of precision p = malloc(50); ret = dbbind(d->dbproc, i+1, STRINGBIND, 50, (unsigned char *)p); break; case QVariant::String: p = malloc(dbcollen(d->dbproc, i+1) + 1); ret = dbbind(d->dbproc, i+1, STRINGBIND, DBINT(dbcollen(d->dbproc, i+1) + 1), (unsigned char *)p); break; case QVariant::DateTime: p = malloc(8); ret = dbbind(d->dbproc, i+1, DATETIMEBIND, (DBINT) 8, (unsigned char *)p); break; case QVariant::ByteArray: p = malloc(dbcollen(d->dbproc, i+1) + 1); ret = dbbind(d->dbproc, i+1, BINARYBIND, DBINT(dbcollen(d->dbproc, i+1) + 1), (unsigned char *)p); break; default: //don't bind the field since we do not support it qWarning("QTDSResult::reset: Unsupported type for field \"%s\"", dbcolname(d->dbproc, i+1)); break; } if (ret == SUCCEED) { d->buffer[i * 2] = p; ret = dbnullbind(d->dbproc, i+1, (DBINT*)(&d->buffer[i * 2 + 1])); } else { d->buffer[i * 2] = 0; d->buffer[i * 2 + 1] = 0; free(p); } if ((ret != SUCCEED) && (ret != -1)) { setLastError(d->lastError); return false; } } setActive(true); return true; }
RETCODE CDBL_Connection::x_Results(DBPROCESS* pLink) { unsigned int x_Status = 0x1; unique_ptr<CDB_Result> dbres; unique_ptr<impl::CResult> res; while ((x_Status & 0x1) != 0) { if ((x_Status & 0x20) != 0) { // check for return parameters from exec x_Status ^= 0x20; int n; if (GetResultProcessor() && (n = Check(dbnumrets(pLink))) > 0) { res.reset(new CDBL_ParamResult(*this, pLink, n)); dbres.reset(Create_Result(*res)); GetResultProcessor()->ProcessResult(*dbres); dbres.reset(); res.reset(); } continue; } if ((x_Status & 0x40) != 0) { // check for ret status x_Status ^= 0x40; if (GetResultProcessor() && Check(dbhasretstat(pLink))) { res.reset(new CDBL_StatusResult(*this, pLink)); dbres.reset(Create_Result(*res)); GetResultProcessor()->ProcessResult(*dbres); dbres.reset(); res.reset(); } continue; } if ((x_Status & 0x10) != 0) { // we do have a compute result res.reset(new CDBL_ComputeResult(*this, pLink, &x_Status)); dbres.reset(Create_Result(*res)); if(GetResultProcessor()) { GetResultProcessor()->ProcessResult(*dbres); } else { while(dbres->Fetch()) continue; } dbres.reset(); res.reset(); } RETCODE rc = Check(dbresults(pLink)); switch (rc) { case SUCCEED: x_Status |= 0x60; if (DBCMDROW(pLink) == SUCCEED) { // we could get rows in result if(!GetResultProcessor()) { while(1) { switch(Check(dbnextrow(pLink))) { case NO_MORE_ROWS: case FAIL: case BUF_FULL: break; default: continue; } break; } continue; } if (Check(dbnumcols(pLink)) == 1) { int ct = Check(dbcoltype(pLink, 1)); if ((ct == SYBTEXT) || (ct == SYBIMAGE)) { res.reset(new CDBL_BlobResult(*this, pLink)); } } if ( !res.get() ) res.reset(new CDBL_RowResult(*this, pLink, &x_Status)); dbres.reset(Create_Result(*res)); GetResultProcessor()->ProcessResult(*dbres); dbres.reset(); res.reset(); } else { continue; } case NO_MORE_RESULTS: x_Status = 2; break; default: return FAIL; } break; } return SUCCEED; }