/*! * \brief データベースバージョン取得 * * \return データベースバージョン */ int32_t SequenceLogServiceDB::getVersion() const { SLOG(CLS_NAME, "getVersion"); int32_t version = 0; Statement* stmt = nullptr; try { const char* sql = "select version from version_info"; stmt = newStatement(); stmt->prepare(sql); stmt->setIntResult(0, &version); stmt->bind(); stmt->execute(); stmt->fetch(); } catch (Exception e) { // 初回起動時などテーブルが存在しない場合もあるので、 // 例外が発生しても何もすることはない SMSG(slog::DEBUG, "%s", e.getMessage()); } delete stmt; return version; }
int ODBCWrapper::fetch(int stmtId) { Statement *stmt = stmts[stmtId]; if (!stmt) return MOB_INVALID_STMTID; int rc = stmt->fetch(); return (rc); }
bool DatabaseClient::execute(SqlExecutableRef& se, Connection* c) { bool rval = false; if(se.isNull()) { // typical usage will involve generating an SQL executable and then // passing it to this method ... the generation might result in a // NULL SQL executable which would be passed here and caught for // convenience ... if that's the case a relevant exception is already // set -- for the degenerate/unusual case nothing is set yet so we set // something here if(!Exception::isSet()) { ExceptionRef e = new Exception( "Could not execute SQL. SqlExecutable is NULL.", DBC_EXCEPTION ".NullSqlExecutable"); Exception::set(e); } } else { // FIXME: this is for mysql only, see FIXME below if(se->returnRowsFound) { size_t i = se->sql.find("SELECT "); if(i != string::npos) { se->sql.insert(i + 7, "SQL_CALC_FOUND_ROWS "); } } if(mDebugLogging) { MO_CAT_DEBUG_DATA(MO_SQL_CAT, "SqlExecutable:\n" "sql: %s\n" "write: %s\n" "params: %s\n" "columnSchemas: %s\n" "whereFilter: %s\n", se->sql.c_str(), se->write ? "true" : "false", JsonWriter::writeToString(se->params, false, false).c_str(), JsonWriter::writeToString(se->columnSchemas, false, false).c_str(), JsonWriter::writeToString(se->whereFilter, false, false).c_str()); } // get a connection from the pool if one wasn't passed in Connection* conn = (c == NULL) ? (se->write ? getWriteConnection() : getReadConnection()) : c; if(conn != NULL) { // prepare statement, set parameters, and execute Statement* s = conn->prepare(se->sql.c_str()); rval = (s != NULL) && setParams(s, se->params) && s->execute(); // if we wrote to the database, get affected rows and last insert ID if(rval && se->write) { s->getRowsChanged(se->rowsAffected); se->lastInsertRowId = s->getLastInsertRowId(); } // else we read, so get row results else if(rval && !se->result.isNull()) { // get results as an array if(se->result->getType() == Array) { // FIXME: we intentionally do not check rval in this while() // loop right now because there are some issues where if // if we don't retrieve the entire result set (fetch each row) // then we run into problems -- this needs to be double checked // so we can handle this case better // iterate over rows int index = 0; Row* r; while((r = s->fetch()) != NULL) { // pull out data DynamicObject& row = se->result[index++]; rval = getRowData(se->columnSchemas, r, row); } // save number of rows retrieved se->rowsRetrieved = se->result->length(); } // get results as a single map else { Row* r = s->fetch(); if(r == NULL) { // the value doesn't exist se->rowsRetrieved = 0; } else { // row found, pull out data se->rowsRetrieved = 1; rval = getRowData(se->columnSchemas, r, se->result); // finish out result set s->fetch(); } } // get total rows found if requested if(rval && se->returnRowsFound) { // FIXME: we want to abstract this better but aren't sure how // we want to yet ... this implementation is mysql only ... // in sqlite3 you do a select without a limit and then only // return the rows up to the limit and then keep counting // past it with fetch() ... in postgresql you have to do a // SELECT COUNT(*) as total within a transaction // select found rows const char* sql = "SELECT FOUND_ROWS() AS total"; Statement* statement = conn->prepare(sql); rval = (statement != NULL) && statement->execute(); if(rval) { // fetch total row Row* row = statement->fetch(); if(row != NULL) { row->getUInt64("total", se->rowsFound); } else { ExceptionRef e = new Exception( "Could not get the total number of found rows.", DBC_EXCEPTION ".GetFoundRowsFailed"); Exception::push(e); rval = false; } } } } // close connection if it was not passed in if(c == NULL) { conn->close(); } } } return rval; }