From 413c1ef84753c5ec77bc8300bc0710163605d782 Mon Sep 17 00:00:00 2001 From: velnias75 Date: Sun, 5 Apr 2015 21:45:43 +0200 Subject: [PATCH] using a prepared statement for the SqLite turn counter --- src/engine/stdplayer.cpp | 59 ++++++++++++++++++++++++--------------- src/sqlite/sqliteimpl.cpp | 22 +++++++++------ src/sqlite/sqliteimpl.h | 7 ++++- 3 files changed, 56 insertions(+), 32 deletions(-) diff --git a/src/engine/stdplayer.cpp b/src/engine/stdplayer.cpp index 19d349a..cfae4ac 100644 --- a/src/engine/stdplayer.cpp +++ b/src/engine/stdplayer.cpp @@ -99,6 +99,41 @@ struct _isSpecialRank : std::binary_function < NetMauMau::Common::ICard *, private: bool m_nineIsEight; }; + +struct _pushIfPossible : std::unary_function { + + inline explicit _pushIfPossible(NetMauMau::Player::IPlayer::CARDS &c, + const NetMauMau::Common::ICard *const uc, + const NetMauMau::RuleSet::IRuleSet *const rs, + const NetMauMau::Common::ICard::SUIT *const s) : cards(c), + uncoveredCard(uc), ruleset(rs), suit(s), aceRoundRank(rs->getAceRoundRank()), + ucRank(uc->getRank()), isAceRound(rs->isAceRound()) {} + + inline void operator()(NetMauMau::Common::ICard *card) const { + + if(suit && card->getSuit() != *suit) return; + + const NetMauMau::Common::ICard::RANK rank = card->getRank(); + + const bool accepted = isAceRound ? rank == aceRoundRank : + ruleset->checkCard(card, uncoveredCard); + + const bool jack = (rank == NetMauMau::Common::ICard::JACK && + ucRank != NetMauMau::Common::ICard::JACK) && !isAceRound; + + if(accepted || jack) cards.push_back(card); + } + + NetMauMau::Player::IPlayer::CARDS &cards; + +private: + const NetMauMau::Common::ICard *const uncoveredCard; + const NetMauMau::RuleSet::IRuleSet *const ruleset; + const NetMauMau::Common::ICard::SUIT *const suit; + NetMauMau::Common::ICard::RANK aceRoundRank; + NetMauMau::Common::ICard::RANK ucRank; + bool isAceRound; +}; #pragma GCC diagnostic pop } @@ -624,28 +659,8 @@ IPlayer::CARDS StdPlayer::getPossibleCards(const NetMauMau::Common::ICard *uncov CARDS posCards; posCards.reserve(m_cards.size()); - const NetMauMau::RuleSet::IRuleSet *ruleset = getRuleSet(); - - const bool isAceRound = ruleset->isAceRound(); - const NetMauMau::Common::ICard::RANK aceRoundRank = ruleset->getAceRoundRank(); - const NetMauMau::Common::ICard::RANK ucRank = uncoveredCard->getRank(); - - for(CARDS::const_iterator i(m_cards.begin()); i != m_cards.end(); ++i) { - - if(suit && (*i)->getSuit() != *suit) continue; - - const NetMauMau::Common::ICard::RANK rank = (*i)->getRank(); - - const bool accepted = isAceRound ? rank == aceRoundRank : - ruleset->checkCard(*i, uncoveredCard); - - const bool jack = (rank == NetMauMau::Common::ICard::JACK && - ucRank != NetMauMau::Common::ICard::JACK) && !isAceRound; - - if(accepted || jack) posCards.push_back(*i); - } - - return posCards; + return std::for_each(m_cards.begin(), m_cards.end(), _pushIfPossible(posCards, uncoveredCard, + getRuleSet(), suit)).cards; } void StdPlayer::informAIStat(const IPlayer *, std::size_t count) { diff --git a/src/sqlite/sqliteimpl.cpp b/src/sqlite/sqliteimpl.cpp index 7af2619..2a465bc 100644 --- a/src/sqlite/sqliteimpl.cpp +++ b/src/sqlite/sqliteimpl.cpp @@ -21,6 +21,7 @@ #include "config.h" #endif +#include #include #include @@ -70,6 +71,7 @@ int scoresCallback(void *arg, int cols, char **col_text, char **) { const char *SCHEMA = "PRAGMA journal_mode=OFF;" \ + "PRAGMA synchronous=NORMAL;" \ "CREATE TABLE IF NOT EXISTS \"meta\" (" \ "dbver INTEGER UNIQUE," \ "date INTEGER );"\ @@ -125,7 +127,7 @@ const char *SCHEMA = using namespace NetMauMau::DB; -SQLiteImpl::SQLiteImpl() : m_db(0L) { +SQLiteImpl::SQLiteImpl() : m_db(0L), m_turnStmt(0L) { const std::string &db(getDBFilename()); @@ -135,6 +137,8 @@ SQLiteImpl::SQLiteImpl() : m_db(0L) { if(sqlite3_open(db.c_str(), &m_db) != SQLITE_ERROR) { + sqlite3_prepare_v2(m_db, "UPDATE games SET turns = @TURN WHERE id = @ID;", 100, + &m_turnStmt, NULL); exec(SCHEMA); std::ostringstream sql; @@ -164,6 +168,7 @@ SQLiteImpl::~SQLiteImpl() { exec(sql.str()); exec("VACUUM;"); + sqlite3_finalize(m_turnStmt); sqlite3_close(m_db); } } @@ -223,11 +228,11 @@ std::string SQLiteImpl::getDBFilename() { } #pragma GCC diagnostic pop -bool SQLiteImpl::exec(const std::string &sql) const { +bool SQLiteImpl::exec(const char *sql) const { char *err = 0L; - if(m_db && sqlite3_exec(m_db, sql.c_str(), NULL, NULL, &err) == SQLITE_OK) { + if(m_db && sqlite3_exec(m_db, sql, NULL, NULL, &err) == SQLITE_OK) { return true; } @@ -351,12 +356,11 @@ bool SQLiteImpl::addPlayerToGame(long long int gid, } bool SQLiteImpl::turn(long long int gameIndex, std::size_t t) const { - - std::ostringstream sql; - - sql << "UPDATE games SET turns = " << t << " WHERE id = " << gameIndex << ";"; - - return exec(sql.str()); + return sqlite3_bind_int64(m_turnStmt, 1, t) == SQLITE_OK && + sqlite3_bind_int64(m_turnStmt, 2, gameIndex) == SQLITE_OK && + sqlite3_step(m_turnStmt) == SQLITE_DONE && + sqlite3_clear_bindings(m_turnStmt) == SQLITE_OK && + sqlite3_reset(m_turnStmt) == SQLITE_OK; } bool SQLiteImpl::gamePlayStarted(long long int gameIndex) const { diff --git a/src/sqlite/sqliteimpl.h b/src/sqlite/sqliteimpl.h index 7c2ae92..b35797d 100644 --- a/src/sqlite/sqliteimpl.h +++ b/src/sqlite/sqliteimpl.h @@ -61,10 +61,15 @@ class SQLiteImpl { bool playerWins(long long int gameIndex, const Common::IConnection::NAMESOCKFD &nsf) const; private: - bool exec(const std::string &sql) const; + bool exec(const char *sql) const; + + inline bool exec(const std::string &sql) const { + return exec(sql.c_str()); + } private: sqlite3 *m_db; + sqlite3_stmt *m_turnStmt; }; }