Esempio n. 1
0
/*!
 * \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;
}
Esempio n. 2
0
int ODBCWrapper::fetch(int stmtId)
{
    Statement *stmt = stmts[stmtId];
    if (!stmt) return MOB_INVALID_STMTID;
    int rc = stmt->fetch();
    return (rc);
}
Esempio n. 3
0
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;
}