DBResult_ptr DatabaseODBC::internalSelectQuery(const std::string &query)
{
  if(!m_connected)
    return DBResult_ptr();

  #ifdef __DEBUG_SQL__
  std::cout << "ODBC QUERY: " << query << std::endl;
  #endif

  std::string buf = _parse(query);

  SQLHSTMT stmt;

  SQLRETURN ret = SQLAllocHandle(SQL_HANDLE_STMT, m_handle, &stmt);
  if(!RETURN_SUCCESS(ret)){
    std::cout << "Failed to allocate ODBC SQLHSTMT statement." << std::endl;
    return DBResult_ptr();
  }

  ret = SQLExecDirect(stmt, (SQLCHAR*)buf.c_str(), buf.length() );

  if(!RETURN_SUCCESS(ret)){
    std::cout << "SQLExecDirect(): " << query << ": ODBC ERROR." << std::endl;
    return DBResult_ptr();
  }

  DBResult_ptr results(new ODBCResult(stmt), boost::bind(&DatabaseDriver::freeResult, this, _1));
  return verifyResult(results);
}
DBResult_ptr Database::storeQuery(const std::string& query)
{
	// executes the query
	database_lock.lock();

	retry:
	while (mysql_real_query(m_handle, query.c_str(), query.length()) != 0) {
		std::cout << "[Error - mysql_real_query] Query: " << query << std::endl << "Message: " << mysql_error(m_handle) << std::endl;
		auto error = mysql_errno(m_handle);
		if (error != CR_SERVER_LOST && error != CR_SERVER_GONE_ERROR && error != CR_CONN_HOST_ERROR && error != 1053/*ER_SERVER_SHUTDOWN*/ && error != CR_CONNECTION_ERROR) {
			break;
		}
		std::this_thread::sleep_for(std::chrono::seconds(1));
	}

	// we should call that every time as someone would call executeQuery('SELECT...')
	// as it is described in MySQL manual: "it doesn't hurt" :P
	MYSQL_RES* m_res = mysql_store_result(m_handle);

	// error occured
	if (!m_res) {
		std::cout << "[Error - mysql_store_result] Query: " << query << std::endl << "Message: " << mysql_error(m_handle) << std::endl;
		int error = mysql_errno(m_handle);
		if (error != CR_SERVER_LOST && error != CR_SERVER_GONE_ERROR && error != CR_CONN_HOST_ERROR && error != 1053/*ER_SERVER_SHUTDOWN*/ && error != CR_CONNECTION_ERROR) {
			database_lock.unlock();
			return nullptr;
		}
		goto retry;
	}
	database_lock.unlock();

	// retriving results of query
	return verifyResult(DBResult_ptr(new DBResult(m_res)));
}
Exemple #3
0
DBResult_ptr DatabaseDriver::verifyResult(DBResult_ptr result)
{
	if(!result->advance()){
		return DBResult_ptr();
	}
	else{
		return result;
	}
}
DBResult_ptr DatabaseMySQL::internalSelectQuery(const std::string &query)
{
	if(!m_connected)
		return DBResult_ptr();

	#ifdef __DEBUG_SQL__
	std::cout << "MYSQL QUERY: " << query << std::endl;
	#endif

	// executes the query
	if(mysql_real_query(&m_handle, query.c_str(), query.length()) != 0){
		std::cout << "mysql_real_query(): " << query << ": MYSQL ERROR: " << mysql_error(&m_handle) << std::endl;
		int error = mysql_errno(&m_handle);

		if(error == CR_SERVER_LOST || error == CR_SERVER_GONE_ERROR){
			m_connected = false;
		}

	}

	// we should call that every time as someone would call executeQuery('SELECT...')
	// as it is described in MySQL manual: "it doesn't hurt" :P
	MYSQL_RES* m_res = mysql_store_result(&m_handle);

	// error occured
	if(!m_res){
		std::cout << "mysql_store_result(): " << query.substr(0, 256) << ": MYSQL ERROR: " << mysql_error(&m_handle) << std::endl;
		int error = mysql_errno(&m_handle);

		if(error == CR_SERVER_LOST || error == CR_SERVER_GONE_ERROR){
			m_connected = false;
		}

		return DBResult_ptr();
	}

	// retriving results of query
	DBResult_ptr res(new MySQLResult(m_res), boost::bind(&DatabaseDriver::freeResult, this, _1));
	return verifyResult(res);
}
DBResult_ptr DatabaseSQLite::internalSelectQuery(const std::string &query)
{
  boost::recursive_mutex::scoped_lock lockClass(sqliteLock);

  if(!m_connected)
    return DBResult_ptr();

  #ifdef __DEBUG_SQL__
  std::cout << "SQLITE QUERY: " << query << std::endl;
  #endif

  std::string buf = _parse(query);
  sqlite3_stmt* stmt;
  // prepares statement
  if( OTS_SQLITE3_PREPARE(m_handle, buf.c_str(), buf.length(), &stmt, NULL) != SQLITE_OK){
    sqlite3_finalize(stmt);
    std::cout << "OTS_SQLITE3_PREPARE(): SQLITE ERROR: " << sqlite3_errmsg(m_handle)  << " (" << buf << ")" << std::endl;
    return DBResult_ptr();
  }

  DBResult_ptr results(new SQLiteResult(stmt), boost::bind(&DatabaseDriver::freeResult, this, _1));
  return verifyResult(results);
}
DBResult_ptr SQLiteResult::advance()
{
  // checks if after moving to next step we have a row result
  bool m_rowAvailable = (sqlite3_step(m_handle) == SQLITE_ROW);
  return m_rowAvailable ? shared_from_this() : DBResult_ptr();
}
DBResult_ptr MySQLResult::advance()
{
	m_row = mysql_fetch_row(m_handle);
	return m_row != NULL ? shared_from_this() : DBResult_ptr();
}
DBResult_ptr ODBCResult::advance()
{
  SQLRETURN ret = SQLFetch(m_handle);
  m_rowAvailable = RETURN_SUCCESS(ret);
  return m_rowAvailable ? shared_from_this() : DBResult_ptr();
}