void setResults( const MySqlPreparedStatement& statement, std::vector<std::tuple<Args...>>* const results ) { OutputBinderPrivate::Friend::throwIfParameterCountWrong( sizeof...(Args), statement ); std::vector<MYSQL_BIND> parameters(statement.getFieldCount()); std::vector<std::vector<char>> buffers(statement.getFieldCount()); std::vector<mysql_bind_length_t> lengths(statement.getFieldCount()); std::vector<my_bool> nullFlags(statement.getFieldCount()); // bindParameters needs to know the type of the tuples, and it does this by // taking an example tuple, so just create a dummy // TODO(bskari|2013-03-17) There has to be a better way than this std::tuple<Args...> unused; bindParameters( unused, ¶meters, &buffers, &nullFlags, OutputBinderPrivate::int_<sizeof...(Args) - 1>{}); for (size_t i = 0; i < statement.getFieldCount(); ++i) { // This doesn't need to be set on every type, but it won't hurt // anything, and it will make the OutputBinderParameterSetter // specializations simpler parameters.at(i).length = &lengths.at(i); } int fetchStatus = OutputBinderPrivate::Friend::bindAndExecuteStatement( ¶meters, statement); while (0 == fetchStatus || MYSQL_DATA_TRUNCATED == fetchStatus) { if (MYSQL_DATA_TRUNCATED == fetchStatus) { OutputBinderPrivate::Friend::refetchTruncatedColumns( statement, ¶meters, &buffers, &lengths); } std::tuple<Args...> rowTuple; setResultTuple( &rowTuple, parameters, OutputBinderPrivate::int_<sizeof...(Args) - 1>{}); results->push_back(std::move(rowTuple)); fetchStatus = OutputBinderPrivate::Friend::fetch(statement); } OutputBinderPrivate::Friend::throwIfFetchError(fetchStatus, statement); }
uint32 MySQLPreparedStatement::execute(PreparedStatement *data) { if (m_paramCount) { bindParameters(data); if (mysql_stmt_bind_param(m_stmt, m_bind) != 0) return mysql_stmt_errno(m_stmt); } return (mysql_stmt_execute(m_stmt) != 0) ? mysql_stmt_errno(m_stmt) : 0; }
bool SQLiteCommand::prepareStatements(SQLiteConnection &conn) { sqlite3 *db = conn.database(); if (myLocked) { return false; } if (myStatements.size() != 0) { const size_t size = myStatements.size(); int res = SQLITE_OK; for (size_t i = 0; i < size && res == SQLITE_OK; ++i) { res = sqlite3_reset(myStatements[i]); } if (res == SQLITE_OK) { bindParameters(); return true; } finalizeStatements(); } const std::string sql = commandString(); const int length = -1; const char *tail = sql.c_str(); while (true) { sqlite3_stmt *statement; int res = sqlite3_prepare_v2(db, tail, length, &statement, &tail); if (res != SQLITE_OK) { dumpError(); finalizeStatements(); return false; } if (statement == 0) { break; } myStatements.push_back(statement); conn.addStatement(statement); } if (!bindParameters()) { finalizeStatements(); return false; } return true; }
void bindParameters( const Tuple& tuple, // We only need this so we can access the element types std::vector<MYSQL_BIND>* const mysqlBindParameters, std::vector<std::vector<char>>* const buffers, std::vector<my_bool>* const nullFlags, int_<I> ) { OutputBinderParameterSetter< typename std::tuple_element<I, Tuple>::type >::setParameter( &mysqlBindParameters->at(I), &buffers->at(I), &nullFlags->at(I)); bindParameters( tuple, mysqlBindParameters, buffers, nullFlags, int_<I - 1>()); }