diff --git a/src/core/util/Database.cc b/src/core/util/Database.cc index 88324339..19094b48 100644 --- a/src/core/util/Database.cc +++ b/src/core/util/Database.cc @@ -21,6 +21,14 @@ Database::Database(const std::string &username, const std::string &host, const s LOG << "opened MYSQL connection" << std::endl; } +Database::~Database() +{ + // flush cached INSERTs if available + insert_multiple(); + + mysql_close(handle); +} + MYSQL_RES* Database::query(char const *query, bool get_result) { #ifndef __puma boost::lock_guard guard(m_handle_lock); @@ -67,6 +75,43 @@ MYSQL_RES* Database::query_stream(char const *query) return res; } +bool Database::insert_multiple(char const *insertquery, char const *values) +{ + // different insertquery, but still cached values? + if (insertquery && m_insertquery != insertquery && m_insertquery_values.size() > 0) { + // flush cache + insert_multiple(); + } else if (!insertquery && m_insertquery.size() == 0) { + // don't know how to INSERT, no insertquery available! + return false; + } + + if (insertquery) { + m_insertquery = insertquery; + } + + if (values) { + m_insertquery_values.push_back(values); + } + + if ((!values && m_insertquery_values.size() > 0) || m_insertquery_values.size() >= 32) { + std::stringstream sql; + sql << m_insertquery; + bool first = true; + for (std::vector::const_iterator it = m_insertquery_values.begin(); + it != m_insertquery_values.end(); ++it) { + if (!first) { + sql << ","; + } + first = false; + sql << *it; + } + m_insertquery_values.clear(); + return query(sql.str().c_str()); + } + + return true; +} my_ulonglong Database::affected_rows() { diff --git a/src/core/util/Database.hpp b/src/core/util/Database.hpp index 5365fa5b..ff234f7f 100644 --- a/src/core/util/Database.hpp +++ b/src/core/util/Database.hpp @@ -24,13 +24,15 @@ namespace fail { #ifndef __puma boost::mutex m_handle_lock; #endif + std::string m_insertquery; + std::vector m_insertquery_values; public: /** * Constructor that connects instantly to the database */ Database(const std::string &username, const std::string &host, const std::string &database); - ~Database() { mysql_close(handle); } + ~Database(); struct Variant { int id; @@ -80,6 +82,12 @@ namespace fail { */ MYSQL_RES *query_stream(char const *query); + /** + * Caches multiple value tuples to combine into multi-value INSERTs. + * Call without parameters to flush the cache. + */ + bool insert_multiple(char const *insertquery = 0, char const *values = 0); + /** * How many rows were affected by the last query */