Play-/Source/ui_shared/BootablesDbClient.cpp

181 lines
5.7 KiB
C++
Raw Normal View History

#include <cassert>
#include "../AppConfig.h"
#include "string_format.h"
#include "PathUtils.h"
#include "BootablesDbClient.h"
#include "sqlite/SqliteStatement.h"
using namespace BootablesDb;
#define DATABASE_VERSION 2
static const char* g_dbFileName = "bootables.db";
2018-08-29 13:53:51 -04:00
static const char* g_bootablesTableCreateStatement =
"CREATE TABLE IF NOT EXISTS bootables"
"("
" path TEXT PRIMARY KEY,"
" discId VARCHAR(10) DEFAULT '',"
" title TEXT DEFAULT '',"
" coverUrl TEXT DEFAULT '',"
" lastBootedTime INTEGER DEFAULT 0,"
" overview TEXT DEFAULT ''"
2018-08-29 13:53:51 -04:00
")";
CClient::CClient()
{
m_dbPath = CAppConfig::GetInstance().GetBasePath() / g_dbFileName;
CheckDbVersion();
m_db = Framework::CSqliteDb(Framework::PathUtils::GetNativeStringFromPath(m_dbPath).c_str(),
2018-08-29 13:53:51 -04:00
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
{
auto query = string_format("PRAGMA user_version = %d", DATABASE_VERSION);
Framework::CSqliteStatement statement(m_db, query.c_str());
statement.StepNoResult();
}
{
Framework::CSqliteStatement statement(m_db, g_bootablesTableCreateStatement);
statement.StepNoResult();
}
}
bool CClient::BootableExist(const fs::path& path)
{
Framework::CSqliteStatement statement(m_db, "SELECT * FROM bootables WHERE path = ?");
statement.BindText(1, Framework::PathUtils::GetNativeStringFromPath(path).c_str());
return statement.Step();
}
2019-10-16 20:51:11 -04:00
Bootable CClient::GetBootable(const fs::path& path)
{
Framework::CSqliteStatement statement(m_db, "SELECT * FROM bootables WHERE path = ?");
statement.BindText(1, Framework::PathUtils::GetNativeStringFromPath(path).c_str());
statement.StepWithResult();
return ReadBootable(statement);
}
std::vector<Bootable> CClient::GetBootables(int32_t sortMethod)
{
2019-01-06 13:44:16 +00:00
std::string query = "SELECT * FROM bootables ";
switch(sortMethod)
2019-01-06 13:44:16 +00:00
{
case SORT_METHOD_RECENT:
2019-01-06 12:27:31 +00:00
query += "WHERE lastBootedTime != 0 Order By lastBootedTime DESC ";
break;
case SORT_METHOD_HOMEBREW:
2019-01-06 12:27:31 +00:00
query += "WHERE path LIKE '%.elf' COLLATE NOCASE ";
break;
case SORT_METHOD_NONE:
break;
2019-01-06 13:44:16 +00:00
}
std::vector<Bootable> bootables;
2019-01-06 13:44:16 +00:00
Framework::CSqliteStatement statement(m_db, query.c_str());
while(statement.Step())
{
auto bootable = ReadBootable(statement);
bootables.push_back(bootable);
}
return bootables;
}
2019-10-16 20:51:11 -04:00
void CClient::RegisterBootable(const fs::path& path, const char* title, const char* discId)
{
Framework::CSqliteStatement statement(m_db, "INSERT OR IGNORE INTO bootables (path, title, discId) VALUES (?,?,?)");
statement.BindText(1, Framework::PathUtils::GetNativeStringFromPath(path).c_str());
statement.BindText(2, title, true);
statement.BindText(3, discId, true);
statement.StepNoResult();
}
2019-10-16 20:51:11 -04:00
void CClient::UnregisterBootable(const fs::path& path)
2017-10-27 18:06:59 -04:00
{
Framework::CSqliteStatement statement(m_db, "DELETE FROM bootables WHERE path = ?");
statement.BindText(1, Framework::PathUtils::GetNativeStringFromPath(path).c_str());
statement.StepNoResult();
}
2019-10-16 20:51:11 -04:00
void CClient::SetDiscId(const fs::path& path, const char* discId)
{
Framework::CSqliteStatement statement(m_db, "UPDATE bootables SET discId = ? WHERE path = ?");
statement.BindText(1, discId, true);
statement.BindText(2, Framework::PathUtils::GetNativeStringFromPath(path).c_str());
statement.StepNoResult();
}
2019-10-16 20:51:11 -04:00
void CClient::SetTitle(const fs::path& path, const char* title)
{
Framework::CSqliteStatement statement(m_db, "UPDATE bootables SET title = ? WHERE path = ?");
statement.BindText(1, title, true);
statement.BindText(2, Framework::PathUtils::GetNativeStringFromPath(path).c_str());
statement.StepNoResult();
}
2019-10-16 20:51:11 -04:00
void CClient::SetCoverUrl(const fs::path& path, const char* coverUrl)
2017-10-23 07:27:42 -04:00
{
Framework::CSqliteStatement statement(m_db, "UPDATE bootables SET coverUrl = ? WHERE path = ?");
statement.BindText(1, coverUrl, true);
statement.BindText(2, Framework::PathUtils::GetNativeStringFromPath(path).c_str());
statement.StepNoResult();
}
2019-10-16 20:51:11 -04:00
void CClient::SetLastBootedTime(const fs::path& path, time_t lastBootedTime)
{
Framework::CSqliteStatement statement(m_db, "UPDATE bootables SET lastBootedTime = ? WHERE path = ?");
statement.BindInteger(1, lastBootedTime);
statement.BindText(2, Framework::PathUtils::GetNativeStringFromPath(path).c_str());
statement.StepNoResult();
}
2019-10-16 20:51:11 -04:00
void CClient::SetOverview(const fs::path& path, const char* overview)
{
Framework::CSqliteStatement statement(m_db, "UPDATE bootables SET overview = ? WHERE path = ?");
statement.BindText(1, overview, true);
statement.BindText(2, Framework::PathUtils::GetNativeStringFromPath(path).c_str());
statement.StepNoResult();
}
Bootable CClient::ReadBootable(Framework::CSqliteStatement& statement)
{
Bootable bootable;
2018-08-29 13:53:51 -04:00
bootable.path = Framework::PathUtils::GetPathFromNativeString(reinterpret_cast<const char*>(sqlite3_column_text(statement, 0)));
bootable.discId = reinterpret_cast<const char*>(sqlite3_column_text(statement, 1));
bootable.title = reinterpret_cast<const char*>(sqlite3_column_text(statement, 2));
2019-01-06 12:27:31 +00:00
bootable.coverUrl = reinterpret_cast<const char*>(sqlite3_column_text(statement, 3));
bootable.overview = reinterpret_cast<const char*>(sqlite3_column_text(statement, 5));
bootable.lastBootedTime = sqlite3_column_int(statement, 4);
return bootable;
}
void CClient::CheckDbVersion()
{
2018-08-29 13:53:51 -04:00
bool dbExistsAndMatchesVersion =
[&]() {
try
{
auto db = Framework::CSqliteDb(Framework::PathUtils::GetNativeStringFromPath(m_dbPath).c_str(),
SQLITE_OPEN_READONLY);
Framework::CSqliteStatement statement(db, "PRAGMA user_version");
statement.StepWithResult();
int version = sqlite3_column_int(statement, 0);
return (version == DATABASE_VERSION);
}
catch(...)
{
return false;
}
}();
if(!dbExistsAndMatchesVersion)
{
2019-10-16 20:51:11 -04:00
fs::remove(m_dbPath);
}
}