void ODBCStatementImpl::makeStep() { _extractors[currentDataSet()]->reset(); _nextResponse = SQLFetch(_stmt); checkError(_nextResponse); _stepCalled = true; }
void ODBCStatementImpl::doPrepare() { if (session().getFeature("autoExtract") && hasData()) { Poco::UInt32 curDataSet = currentDataSet(); poco_check_ptr (_preparations[curDataSet]); Extractions& extracts = extractions(); Extractions::iterator it = extracts.begin(); Extractions::iterator itEnd = extracts.end(); if (it != itEnd && (*it)->isBulk()) { Poco::UInt32 limit = getExtractionLimit(); if (limit == Limit::LIMIT_UNLIMITED) throw InvalidArgumentException("Bulk operation not allowed without limit."); checkError(SQLSetStmtAttr(_stmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER) limit, 0), "SQLSetStmtAttr(SQL_ATTR_ROW_ARRAY_SIZE)"); } for (std::size_t pos = 0; it != itEnd; ++it) { AbstractPrepare* pAP = (*it)->createPrepareObject(_preparations[curDataSet], pos); pAP->prepare(); pos += (*it)->numOfColumnsHandled(); delete pAP; } _prepared = true; } }
void ODBCStatementImpl::fillColumns() { Poco::UInt32 colCount = columnsReturned(); Poco::UInt32 curDataSet = currentDataSet(); if (curDataSet >= _columnPtrs.size()) _columnPtrs.resize(curDataSet + 1); for (int i = 0; i < colCount; ++i) _columnPtrs[curDataSet].push_back(new ODBCMetaColumn(_stmt, i)); }
void SQLiteStatementImpl::clear() { _columns[currentDataSet()].clear(); _affectedRowCount = POCO_SQLITE_INV_ROW_CNT; if (_pStmt) { sqlite3_finalize(_pStmt); _pStmt=0; } _pLeftover = 0; }
const MetaColumn& ODBCStatementImpl::metaColumn(Poco::UInt32 pos) const { Poco::UInt32 curDataSet = currentDataSet(); poco_assert_dbg (curDataSet < _columnPtrs.size()); std::size_t sz = _columnPtrs[curDataSet].size(); if (0 == sz || pos > sz - 1) throw InvalidAccessException(format("Invalid column number: %u", pos)); return *_columnPtrs[curDataSet][pos]; }
void SQLiteStatementImpl::compileImpl() { if (!_pLeftover) { _bindBegin = bindings().begin(); } std::string statement(toString()); sqlite3_stmt* pStmt = 0; const char* pSql = _pLeftover ? _pLeftover->c_str() : statement.c_str(); if (0 == std::strlen(pSql)) throw InvalidSQLStatementException("Empty statements are illegal"); int rc = SQLITE_OK; const char* pLeftover = 0; bool queryFound = false; do { rc = sqlite3_prepare_v2(_pDB, pSql, -1, &pStmt, &pLeftover); if (rc != SQLITE_OK) { if (pStmt) sqlite3_finalize(pStmt); pStmt = 0; std::string errMsg = sqlite3_errmsg(_pDB); Utility::throwException(_pDB, rc, errMsg); } else if (rc == SQLITE_OK && pStmt) { queryFound = true; } else if (rc == SQLITE_OK && !pStmt) // comment/whitespace ignore { pSql = pLeftover; if (std::strlen(pSql) == 0) { // empty statement or an conditional statement! like CREATE IF NOT EXISTS // this is valid queryFound = true; } } } while (rc == SQLITE_OK && !pStmt && !queryFound); //Finalization call in clear() invalidates the pointer, so the value is remembered here. //For last statement in a batch (or a single statement), pLeftover == "", so the next call // to compileImpl() shall return false immediately when there are no more statements left. std::string leftOver(pLeftover); trimInPlace(leftOver); clear(); _pStmt = pStmt; if (!leftOver.empty()) { _pLeftover = new std::string(leftOver); _canCompile = true; } else _canCompile = false; _pBinder = new Binder(_pStmt); _pExtractor = new Extractor(_pStmt); if (SQLITE_DONE == _nextResponse && _isExtracted) { //if this is not the first compile and there has already been extraction //during previous step, switch to the next set if there is one provided if (hasMoreDataSets()) { activateNextDataSet(); _isExtracted = false; } } int colCount = sqlite3_column_count(_pStmt); if (colCount) { std::size_t curDataSet = currentDataSet(); if (curDataSet >= _columns.size()) _columns.resize(curDataSet + 1); for (int i = 0; i < colCount; ++i) { MetaColumn mc(i, sqlite3_column_name(_pStmt, i), Utility::getColumnType(_pStmt, i)); _columns[curDataSet].push_back(mc); } } }
const MetaColumn& SQLiteStatementImpl::metaColumn(std::size_t pos) const { std::size_t curDataSet = currentDataSet(); poco_assert (pos >= 0 && pos <= _columns[curDataSet].size()); return _columns[curDataSet][pos]; }
std::size_t SQLiteStatementImpl::columnsReturned() const { return (std::size_t) _columns[currentDataSet()].size(); }