Snake/SnakeServer/Server/sqldbcache.cpp

335 lines
7.6 KiB
C++
Raw Normal View History

#include "sqldbcache.h"
2019-04-17 15:16:11 +03:00
#include "quasarapp.h"
2019-04-29 14:39:48 +03:00
#include "playerdbdata.h"
2019-04-17 15:16:11 +03:00
#include <qtconcurrentrun.h>
#include <clientprotocol.h>
#include <QDateTime>
2019-04-29 14:39:48 +03:00
#include <basenetworkobject.h>
2019-04-16 18:01:55 +03:00
int SqlDBCache::generateIdForItem() const {
2019-04-16 18:01:55 +03:00
if (items.isEmpty()) {
return 0;
}
return items.lastKey() + 1;
}
int SqlDBCache::generateIdForPalyer() const {
2019-04-16 18:01:55 +03:00
if (players.isEmpty()) {
return 0;
}
return players.lastKey() + 1;
}
bool SqlDBCache::checkPlayer(int id) {
2019-04-17 15:16:11 +03:00
if (players.contains(id)) {
return true;
}
if (SqlDBWriter::checkPlayer(id)) {
2019-04-29 14:39:48 +03:00
PlayerDBData *player = getPlayer(id);
2019-05-01 20:13:44 +03:00
if (savePlayer(*player) < 0) {
2019-04-17 15:16:11 +03:00
QuasarAppUtils::Params::verboseLog("not saved data into cache "
" SqlDBCashe::checkPlayer");
}
return true;
}
return false;
}
bool SqlDBCache::checkItem(int idItem, int idOwner) {
2019-04-17 15:16:11 +03:00
if (idOwner >= 0 ) {
if (owners.contains(idOwner)) {
auto items = owners.value(idOwner);
return items.contains(idItem);
}
if (SqlDBWriter::checkItem(idItem)) {
QSet<int> items;
if (!SqlDBWriter::getAllItemsOfPalyer(idOwner, items)) {
2019-04-30 17:25:36 +03:00
QuasarAppUtils::Params::verboseLog("not loaded owners data from cache "
2019-04-17 15:16:11 +03:00
" SqlDBCashe::checkItem");
}
owners.insert(idOwner, items);
return true;
}
return false;
}
if (items.contains(idItem)) {
return true;
}
if (SqlDBWriter::checkItem(idItem)) {
2019-04-29 14:39:48 +03:00
ClientProtocol::BaseNetworkObject *item = getItem(idItem);
2019-04-17 15:16:11 +03:00
if (saveItem(item) < 0) {
QuasarAppUtils::Params::verboseLog("not saved data into cache "
" SqlDBCashe::checkItem");
}
return true;
}
return false;
}
void SqlDBCache::globalUpdateDataBasePrivate(qint64 currentTime) {
2019-04-17 15:16:11 +03:00
QList<int> removeIds;
for (auto item = items.begin(); item != items.end(); ++item) {
if (SqlDBWriter::saveItem(item.value()) < 0) {
removeIds.push_back(item.key());
QuasarAppUtils::Params::verboseLog("writeUpdateItemIntoDB failed when"
" work globalUpdateDataRelease!!! id=" +
QString::number(item.key()));
}
}
for (int id : removeIds) {
items.remove(id);
}
for (auto player = players.begin(); player != players.end(); ++player) {
if (SqlDBWriter::savePlayer(player.value()) < 0) {
2019-04-17 15:16:11 +03:00
removeIds.push_back(player.key());
QuasarAppUtils::Params::verboseLog("writeUpdatePlayerIntoDB failed when"
" work globalUpdateDataRelease!!! id=" +
QString::number(player.key()));
}
}
for (auto owner = owners.begin(); owner != owners.end(); ++owner) {
if (!SqlDBWriter::saveowners(owner.key(), owner.value())) {
2019-04-30 17:25:36 +03:00
QuasarAppUtils::Params::verboseLog("UpdateInfoOfowners failed when"
2019-04-17 15:16:11 +03:00
" work globalUpdateDataRelease!!! id=" +
QString::number(owner.key()));
}
}
lastUpdateTime = currentTime;
}
void SqlDBCache::globalUpdateDataBase(SqlDBCasheWriteMode mode) {
2019-04-17 15:16:11 +03:00
qint64 currentTime = QDateTime::currentMSecsSinceEpoch();
if (currentTime - lastUpdateTime > updateInterval ||
2019-04-18 17:47:54 +03:00
static_cast<bool>(mode & SqlDBCasheWriteMode::Force)) {
if (static_cast<bool>(mode & SqlDBCasheWriteMode::On_New_Thread)) {
QtConcurrent::run([currentTime, this](){
globalUpdateDataBasePrivate(currentTime);
});
} else {
2019-04-17 15:16:11 +03:00
globalUpdateDataBasePrivate(currentTime);
2019-04-18 17:47:54 +03:00
}
2019-04-17 15:16:11 +03:00
}
}
bool SqlDBCache::itemIsFreeFrom(int item) const {
2019-04-17 15:16:11 +03:00
return SqlDBWriter::itemIsFreeFrom(item);
}
SqlDBCache::SqlDBCache(qint64 updateInterval) {
lastUpdateTime = QDateTime::currentMSecsSinceEpoch();
this->updateInterval = updateInterval;
2019-04-17 15:16:11 +03:00
}
SqlDBCache::~SqlDBCache() {
2019-04-18 17:47:54 +03:00
globalUpdateDataBase(SqlDBCasheWriteMode::Force);
2019-04-17 15:16:11 +03:00
}
bool SqlDBCache::initDb(const QString &sql, const QString &path) {
2019-04-17 15:16:11 +03:00
if (!SqlDBWriter::initDb(sql, path)) {
return false;
}
getItem(getLastIdItems());
getPlayer(getLastIdPlayers());
2019-04-17 15:16:11 +03:00
return true;
}
ClientProtocol::BaseNetworkObject * SqlDBCache::getItem(int id) {
if (!isValid()) {
return nullptr;
}
2019-04-29 14:39:48 +03:00
auto item = items.value(id, nullptr);
if (item && item->isValid()) {
return item;
2019-04-17 15:16:11 +03:00
}
2019-04-29 14:39:48 +03:00
if ((item = SqlDBWriter::getItem(id))) {
items.insert(id, item);
return item;
2019-04-17 15:16:11 +03:00
}
2019-04-29 14:39:48 +03:00
return nullptr;
2019-04-17 15:16:11 +03:00
}
2019-05-01 20:13:44 +03:00
int SqlDBCache::saveItem(const Item &item) {
if (!isValid()) {
return -1;
}
2019-04-17 15:16:11 +03:00
2019-05-01 20:13:44 +03:00
int id = item->id();
2019-04-17 15:16:11 +03:00
if (id < 0) {
id = generateIdForItem();
2019-05-01 20:13:44 +03:00
item->setId(id);
2019-04-17 15:16:11 +03:00
}
2019-05-01 20:13:44 +03:00
if (!item->isValid()) {
2019-04-29 14:39:48 +03:00
return -1;
}
2019-05-01 20:13:44 +03:00
items.insert(id, item);
2019-04-17 15:16:11 +03:00
2019-04-18 17:47:54 +03:00
globalUpdateDataBase(SqlDBCasheWriteMode::On_New_Thread);
2019-04-17 15:16:11 +03:00
return id;
}
PlayerDBData* SqlDBCache::getPlayer(int id) {
if (!isValid()) {
return nullptr;
}
2019-04-29 14:39:48 +03:00
auto player = players.value(id, nullptr);
if (player && player->isValid()) {
return player;
2019-04-17 15:16:11 +03:00
}
2019-04-29 14:39:48 +03:00
if ((player = SqlDBWriter::getPlayer(id))) {
items.insert(id, player);
return player;
2019-04-17 15:16:11 +03:00
}
2019-04-16 18:01:55 +03:00
2019-04-29 14:39:48 +03:00
return nullptr;
2019-04-16 18:01:55 +03:00
}
2019-05-01 20:13:44 +03:00
int SqlDBCache::savePlayer(const PlayerDBData &player) {
if (!isValid()) {
2019-04-17 15:16:11 +03:00
return -1;
}
int id = player->id();
2019-04-17 15:16:11 +03:00
if (id < 0) {
id = generateIdForPalyer();
player->setId(id);
}
if (!player->isValid()) {
return -1;
}
int curSnake = player->getCureentSnake();
if (curSnake >= 0 && !checkItem(curSnake, id)) {
return -1;
2019-04-17 15:16:11 +03:00
}
2019-04-16 18:01:55 +03:00
players.insert(id, player);
2019-04-17 15:16:11 +03:00
2019-04-18 17:47:54 +03:00
globalUpdateDataBase(SqlDBCasheWriteMode::On_New_Thread);
2019-04-17 15:16:11 +03:00
return id;
2019-04-16 18:01:55 +03:00
}
bool SqlDBCache::giveAwayItem(int player, int item) {
2019-04-17 15:16:11 +03:00
if (!isValid()) {
return false;
}
if (!checkItem(item, player)) {
return false;
}
if (owners.contains(player)) {
auto &owner = owners[player];
owner.remove(item);
2019-04-18 17:47:54 +03:00
globalUpdateDataBase(SqlDBCasheWriteMode::On_New_Thread);
2019-04-17 15:16:11 +03:00
return true;
}
return false;
}
bool SqlDBCache::getItem(int player, int item, bool check) {
2019-04-17 15:16:11 +03:00
if (!isValid()) {
return false;
}
if (!(checkPlayer(player) && checkItem(item))) {
return false;
}
if (check && !itemIsFreeFrom(item)) {
return false;
}
if (owners.contains(player)) {
auto &owner = owners[player];
owner.insert(item);
2019-04-18 17:47:54 +03:00
globalUpdateDataBase(SqlDBCasheWriteMode::On_New_Thread);
2019-04-17 15:16:11 +03:00
return true;
}
QSet<int> items;
if (!getAllItemsOfPalyer(player, items)) {
return false;
}
if (owners.contains(player)) {
auto &owner = owners[player];
owner.insert(item);
2019-04-18 17:47:54 +03:00
globalUpdateDataBase(SqlDBCasheWriteMode::On_New_Thread);
2019-04-17 15:16:11 +03:00
return true;
}
return false;
}
bool SqlDBCache::moveItem(int owner, int receiver, int item) {
2019-04-17 15:16:11 +03:00
return giveAwayItem(owner, item) && getItem(receiver, item, false);
}
bool SqlDBCache::getAllItemsOfPalyer(int player, QSet<int> &items) {
2019-04-17 15:16:11 +03:00
if (owners.contains(player)) {
items = owners[player];
return true;
}
if (SqlDBWriter::getAllItemsOfPalyer(player, items) &&
checkPlayer(player)) {
owners.insert(player, items);
return true;
}
2019-04-16 18:01:55 +03:00
2019-04-17 15:16:11 +03:00
return false;
2019-04-16 18:01:55 +03:00
}