Compare commits
2 Commits
e78d648178
...
3a890069de
| Author | SHA1 | Date | |
|---|---|---|---|
| 3a890069de | |||
| 1775e864b4 |
275
Bigfoot/Sources/Engine/BigFile/BigFile.cpp
Normal file
275
Bigfoot/Sources/Engine/BigFile/BigFile.cpp
Normal file
@@ -0,0 +1,275 @@
|
|||||||
|
/*********************************************************************
|
||||||
|
* \file BigFile.cpp
|
||||||
|
*
|
||||||
|
* \author Romain BOULLARD
|
||||||
|
* \date October 2025
|
||||||
|
*********************************************************************/
|
||||||
|
#include <Engine/BigFile/BigFile.hpp>
|
||||||
|
|
||||||
|
#include <Engine/EngineAssertHandler.hpp>
|
||||||
|
|
||||||
|
namespace Bigfoot
|
||||||
|
{
|
||||||
|
BigFile::BigFile(const File& p_file)
|
||||||
|
{
|
||||||
|
[[maybe_unused]]
|
||||||
|
const int result = sqlite3_open_v2(p_file.Absolute().Path().data(), &m_db, SQLITE_OPEN_READWRITE, nullptr);
|
||||||
|
CRITICAL_ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to open BigFile DB: {}", sqlite3_errmsg(m_db));
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
void BigFile::BeginTransaction()
|
||||||
|
{
|
||||||
|
[[maybe_unused]]
|
||||||
|
const int result = sqlite3_exec(m_db, "BEGIN TRANSACTION;", nullptr, nullptr, nullptr);
|
||||||
|
ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to begin transaction: {}", sqlite3_errmsg(m_db));
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
void BigFile::CommitTransaction()
|
||||||
|
{
|
||||||
|
[[maybe_unused]]
|
||||||
|
const int result = sqlite3_exec(m_db, "COMMIT TRANSACTION;", nullptr, nullptr, nullptr);
|
||||||
|
ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to commit: {}", sqlite3_errmsg(m_db));
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
void BigFile::RollbackTransaction()
|
||||||
|
{
|
||||||
|
[[maybe_unused]]
|
||||||
|
const int result = sqlite3_exec(m_db, "ROLLBACK TRANSACTION;", nullptr, nullptr, nullptr);
|
||||||
|
ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to rollback: {}", sqlite3_errmsg(m_db));
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
BigFile::~BigFile()
|
||||||
|
{
|
||||||
|
[[maybe_unused]]
|
||||||
|
const int result = sqlite3_close_v2(m_db);
|
||||||
|
CRITICAL_ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to close BigFile DB: {}", sqlite3_errmsg(m_db));
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
BigFile::Request::Request(const BigFile& p_bigFile, const eastl::string_view p_request):
|
||||||
|
m_db(p_bigFile.m_db)
|
||||||
|
{
|
||||||
|
[[maybe_unused]]
|
||||||
|
const int result = sqlite3_prepare_v2(m_db,
|
||||||
|
p_request.data(),
|
||||||
|
static_cast<std::uint32_t>(p_request.size()),
|
||||||
|
&m_statement,
|
||||||
|
nullptr);
|
||||||
|
CRITICAL_ASSERT(EngineAssertHandler,
|
||||||
|
result == SQLITE_OK,
|
||||||
|
"Failed to create statement from BigFile DB: {}",
|
||||||
|
sqlite3_errmsg(m_db));
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
void BigFile::Request::Bind(const std::uint32_t p_index, const std::int32_t p_value)
|
||||||
|
{
|
||||||
|
ASSERT(EngineAssertHandler,
|
||||||
|
(p_index >= 1) && (p_index <= static_cast<std::uint32_t>(sqlite3_bind_parameter_count(m_statement))),
|
||||||
|
"Invalid index for statement");
|
||||||
|
|
||||||
|
[[maybe_unused]]
|
||||||
|
const int result = sqlite3_bind_int(m_statement, p_index, p_value);
|
||||||
|
ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to bind value for statement: {}", sqlite3_errmsg(m_db));
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
void BigFile::Request::Bind(const std::uint32_t p_index, const std::uint32_t p_value)
|
||||||
|
{
|
||||||
|
ASSERT(EngineAssertHandler,
|
||||||
|
(p_index >= 1) && (p_index <= static_cast<std::uint32_t>(sqlite3_bind_parameter_count(m_statement))),
|
||||||
|
"Invalid index for statement");
|
||||||
|
|
||||||
|
[[maybe_unused]]
|
||||||
|
const int result = sqlite3_bind_int(m_statement, p_index, p_value);
|
||||||
|
ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to bind value for statement: {}", sqlite3_errmsg(m_db));
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
void BigFile::Request::Bind(const std::uint32_t p_index, const std::int64_t p_value)
|
||||||
|
{
|
||||||
|
ASSERT(EngineAssertHandler,
|
||||||
|
(p_index >= 1) && (p_index <= static_cast<std::uint32_t>(sqlite3_bind_parameter_count(m_statement))),
|
||||||
|
"Invalid index for statement");
|
||||||
|
|
||||||
|
[[maybe_unused]]
|
||||||
|
const int result = sqlite3_bind_int64(m_statement, p_index, p_value);
|
||||||
|
ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to bind value for statement: {}", sqlite3_errmsg(m_db));
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
void BigFile::Request::Bind(const std::uint32_t p_index, const float p_value)
|
||||||
|
{
|
||||||
|
ASSERT(EngineAssertHandler,
|
||||||
|
(p_index >= 1) && (p_index <= static_cast<std::uint32_t>(sqlite3_bind_parameter_count(m_statement))),
|
||||||
|
"Invalid index for statement");
|
||||||
|
|
||||||
|
[[maybe_unused]]
|
||||||
|
const int result = sqlite3_bind_double(m_statement, p_index, p_value);
|
||||||
|
ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to bind value for statement: {}", sqlite3_errmsg(m_db));
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
void BigFile::Request::Bind(const std::uint32_t p_index, const double p_value)
|
||||||
|
{
|
||||||
|
ASSERT(EngineAssertHandler,
|
||||||
|
(p_index >= 1) && (p_index <= static_cast<std::uint32_t>(sqlite3_bind_parameter_count(m_statement))),
|
||||||
|
"Invalid index for statement");
|
||||||
|
|
||||||
|
[[maybe_unused]]
|
||||||
|
const int result = sqlite3_bind_double(m_statement, p_index, p_value);
|
||||||
|
ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to bind value for statement: {}", sqlite3_errmsg(m_db));
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
void BigFile::Request::Bind(const std::uint32_t p_index, const eastl::string_view p_value, const CopyValue p_copy)
|
||||||
|
{
|
||||||
|
ASSERT(EngineAssertHandler,
|
||||||
|
(p_index >= 1) && (p_index <= static_cast<std::uint32_t>(sqlite3_bind_parameter_count(m_statement))),
|
||||||
|
"Invalid index for statement");
|
||||||
|
|
||||||
|
[[maybe_unused]]
|
||||||
|
const int result = sqlite3_bind_text(m_statement,
|
||||||
|
p_index,
|
||||||
|
p_value.data(),
|
||||||
|
static_cast<std::uint32_t>(p_value.size()),
|
||||||
|
p_copy ? SQLITE_TRANSIENT : SQLITE_STATIC);
|
||||||
|
ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to bind value for statement: {}", sqlite3_errmsg(m_db));
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
void BigFile::Request::Bind(const std::uint32_t p_index,
|
||||||
|
const eastl::span<const std::byte> p_value,
|
||||||
|
const CopyValue p_copy)
|
||||||
|
{
|
||||||
|
ASSERT(EngineAssertHandler,
|
||||||
|
(p_index >= 1) && (p_index <= static_cast<std::uint32_t>(sqlite3_bind_parameter_count(m_statement))),
|
||||||
|
"Invalid index for statement");
|
||||||
|
|
||||||
|
[[maybe_unused]]
|
||||||
|
const int result = sqlite3_bind_blob(m_statement,
|
||||||
|
p_index,
|
||||||
|
p_value.data(),
|
||||||
|
static_cast<std::uint32_t>(p_value.size()),
|
||||||
|
p_copy ? SQLITE_TRANSIENT : SQLITE_STATIC);
|
||||||
|
ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to bind value for statement: {}", sqlite3_errmsg(m_db));
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
bool BigFile::Request::Step()
|
||||||
|
{
|
||||||
|
const int result = sqlite3_step(m_statement);
|
||||||
|
ASSERT(EngineAssertHandler,
|
||||||
|
(result == SQLITE_DONE) || (result == SQLITE_ROW),
|
||||||
|
"Failed to step through the statement: {}",
|
||||||
|
sqlite3_errmsg(m_db));
|
||||||
|
|
||||||
|
return result == SQLITE_ROW;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
std::uint32_t BigFile::Request::Execute()
|
||||||
|
{
|
||||||
|
[[maybe_unused]]
|
||||||
|
const int result = sqlite3_step(m_statement);
|
||||||
|
ASSERT(EngineAssertHandler, (result == SQLITE_DONE), "Failed to execute the statement: {}", sqlite3_errmsg(m_db));
|
||||||
|
|
||||||
|
return sqlite3_changes(m_db);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
BigFile::Request::Column::Column(const Request& p_request, const std::uint32_t p_index):
|
||||||
|
m_statement(p_request.m_statement),
|
||||||
|
m_index(p_index)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
BigFile::Request::Column::operator std::int32_t() const
|
||||||
|
{
|
||||||
|
return sqlite3_column_int(m_statement, m_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
BigFile::Request::Column::operator std::uint32_t() const
|
||||||
|
{
|
||||||
|
return sqlite3_column_int(m_statement, m_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
BigFile::Request::Column::operator std::int64_t() const
|
||||||
|
{
|
||||||
|
return sqlite3_column_int64(m_statement, m_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
BigFile::Request::Column::operator float() const
|
||||||
|
{
|
||||||
|
return static_cast<float>(sqlite3_column_double(m_statement, m_index));
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
BigFile::Request::Column::operator double() const
|
||||||
|
{
|
||||||
|
return sqlite3_column_double(m_statement, m_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
BigFile::Request::Column::operator eastl::string_view() const
|
||||||
|
{
|
||||||
|
return eastl::string_view {reinterpret_cast<const char*>(sqlite3_column_text(m_statement, m_index)),
|
||||||
|
static_cast<std::size_t>(sqlite3_column_bytes(m_statement, m_index))};
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
BigFile::Request::Column::operator eastl::span<const std::byte>() const
|
||||||
|
{
|
||||||
|
return eastl::span<const std::byte> {static_cast<const std::byte*>(sqlite3_column_blob(m_statement, m_index)),
|
||||||
|
static_cast<std::size_t>(sqlite3_column_bytes(m_statement, m_index))};
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
BigFile::Request::Column BigFile::Request::Get(const std::uint32_t p_index) const
|
||||||
|
{
|
||||||
|
ASSERT(EngineAssertHandler,
|
||||||
|
p_index < static_cast<std::uint32_t>(sqlite3_column_count(m_statement)),
|
||||||
|
"Invalid index for column!");
|
||||||
|
return {*this, p_index};
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
BigFile::Request::~Request()
|
||||||
|
{
|
||||||
|
[[maybe_unused]]
|
||||||
|
const int result = sqlite3_finalize(m_statement);
|
||||||
|
CRITICAL_ASSERT(EngineAssertHandler, result == SQLITE_OK, "Failed to finalize statement: {}", sqlite3_errmsg(m_db));
|
||||||
|
}
|
||||||
|
} // namespace Bigfoot
|
||||||
262
Bigfoot/Sources/Engine/Include/Engine/BigFile/BigFile.hpp
Normal file
262
Bigfoot/Sources/Engine/Include/Engine/BigFile/BigFile.hpp
Normal file
@@ -0,0 +1,262 @@
|
|||||||
|
/*********************************************************************
|
||||||
|
* \file BigFile.hpp
|
||||||
|
*
|
||||||
|
* \author Romain BOULLARD
|
||||||
|
* \date October 2025
|
||||||
|
*********************************************************************/
|
||||||
|
#ifndef BIGFOOT_ENGINE_BIGFILE_HPP
|
||||||
|
#define BIGFOOT_ENGINE_BIGFILE_HPP
|
||||||
|
#include <System/File.hpp>
|
||||||
|
|
||||||
|
#include <Utils/TaggedType.hpp>
|
||||||
|
|
||||||
|
#include <EASTL/span.h>
|
||||||
|
|
||||||
|
#include <sqlite3.h>
|
||||||
|
|
||||||
|
namespace Bigfoot
|
||||||
|
{
|
||||||
|
class BigFile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* \param p_file The file targetting the BigFile DB
|
||||||
|
*/
|
||||||
|
BigFile(const File& p_file);
|
||||||
|
|
||||||
|
BigFile(const BigFile& p_bigFile) = default;
|
||||||
|
BigFile(BigFile&& p_bigFile) = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begin a transaction
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void BeginTransaction();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Commit a transaction
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void CommitTransaction();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rollback a transaction
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void RollbackTransaction();
|
||||||
|
|
||||||
|
~BigFile();
|
||||||
|
|
||||||
|
BigFile& operator=(const BigFile& p_bigFile) = default;
|
||||||
|
BigFile& operator=(BigFile&& p_bigFile) = default;
|
||||||
|
|
||||||
|
class Request
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* \param p_bigFile The bigfile
|
||||||
|
* \param p_request The SQL request
|
||||||
|
*/
|
||||||
|
Request(const BigFile& p_bigFile, const eastl::string_view p_request);
|
||||||
|
|
||||||
|
Request(const Request& p_request) = default;
|
||||||
|
Request(Request&& p_request) = default;
|
||||||
|
|
||||||
|
using CopyValue = TaggedType<bool>;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bind a int32 value to the Request at index
|
||||||
|
*
|
||||||
|
* \param p_index The index to bind to
|
||||||
|
* \param p_value The value
|
||||||
|
*/
|
||||||
|
void Bind(const std::uint32_t p_index, const std::int32_t p_value);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bind a uint32 value to the Request at index
|
||||||
|
*
|
||||||
|
* \param p_index The index to bind to
|
||||||
|
* \param p_value The value
|
||||||
|
*/
|
||||||
|
void Bind(const std::uint32_t p_index, const std::uint32_t p_value);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bind a int64 value to the Request at index
|
||||||
|
*
|
||||||
|
* \param p_index The index to bind to
|
||||||
|
* \param p_value The value
|
||||||
|
*/
|
||||||
|
void Bind(const std::uint32_t p_index, const std::int64_t p_value);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bind a float value to the Request at index
|
||||||
|
*
|
||||||
|
* \param p_index The index to bind to
|
||||||
|
* \param p_value The value
|
||||||
|
*/
|
||||||
|
void Bind(const std::uint32_t p_index, const float p_value);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bind a double value to the Request at index
|
||||||
|
*
|
||||||
|
* \param p_index The index to bind to
|
||||||
|
* \param p_value The value
|
||||||
|
*/
|
||||||
|
void Bind(const std::uint32_t p_index, const double p_value);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bind a string value to the Request at index
|
||||||
|
*
|
||||||
|
* \param p_index The index to bind to
|
||||||
|
* \param p_value The value
|
||||||
|
* \param p_copy Should the memory be copied so that caller does not have to retain it
|
||||||
|
*/
|
||||||
|
void Bind(const std::uint32_t p_index,
|
||||||
|
const eastl::string_view p_value,
|
||||||
|
const CopyValue p_copy = CopyValue {false});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bind a blob value to the Request at index
|
||||||
|
*
|
||||||
|
* \param p_index The index to bind to
|
||||||
|
* \param p_value The value
|
||||||
|
* \param p_copy Should the memory be copied so that caller does not have to retain it
|
||||||
|
*/
|
||||||
|
void Bind(const std::uint32_t p_index,
|
||||||
|
const eastl::span<const std::byte> p_value,
|
||||||
|
const CopyValue p_copy = CopyValue {false});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Step through the request
|
||||||
|
*
|
||||||
|
* \return True if the request can continue (get next row), false otherwise
|
||||||
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
|
bool Step();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Execute the request once
|
||||||
|
*
|
||||||
|
* The number of modified rows
|
||||||
|
*/
|
||||||
|
[[maybe_unused]]
|
||||||
|
std::uint32_t Execute();
|
||||||
|
|
||||||
|
class Column
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* \param p_request The request to get the column of
|
||||||
|
* \param p_index Column index
|
||||||
|
*/
|
||||||
|
Column(const Request& p_request, const std::uint32_t p_index);
|
||||||
|
|
||||||
|
Column(const Column& p_column) = default;
|
||||||
|
Column(Column&& p_column) = default;
|
||||||
|
|
||||||
|
~Column() = default;
|
||||||
|
|
||||||
|
Column& operator=(const Column& p_column) = default;
|
||||||
|
Column& operator=(Column&& p_column) = default;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get value as a int32
|
||||||
|
*
|
||||||
|
* \return The value
|
||||||
|
*/
|
||||||
|
operator std::int32_t() const;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get value as a uint32
|
||||||
|
*
|
||||||
|
* \return The value
|
||||||
|
*/
|
||||||
|
operator std::uint32_t() const;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get value as a int64
|
||||||
|
*
|
||||||
|
* \return The value
|
||||||
|
*/
|
||||||
|
operator std::int64_t() const;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get value as a float
|
||||||
|
*
|
||||||
|
* \return The value
|
||||||
|
*/
|
||||||
|
operator float() const;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get value as a double
|
||||||
|
*
|
||||||
|
* \return The value
|
||||||
|
*/
|
||||||
|
operator double() const;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get value as a string
|
||||||
|
*
|
||||||
|
* \return The value
|
||||||
|
*/
|
||||||
|
operator eastl::string_view() const;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get value as a blob
|
||||||
|
*
|
||||||
|
* \return The value
|
||||||
|
*/
|
||||||
|
operator eastl::span<const std::byte>() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*
|
||||||
|
* The statement
|
||||||
|
*/
|
||||||
|
sqlite3_stmt* m_statement;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The column index
|
||||||
|
*/
|
||||||
|
std::uint32_t m_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get a column
|
||||||
|
*
|
||||||
|
* \param p_index Column index
|
||||||
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
|
Column Get(const std::uint32_t p_index) const;
|
||||||
|
|
||||||
|
~Request();
|
||||||
|
|
||||||
|
Request& operator=(const Request& p_request) = default;
|
||||||
|
Request& operator=(Request&& p_request) = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*
|
||||||
|
* The database
|
||||||
|
*/
|
||||||
|
sqlite3* m_db;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The statement
|
||||||
|
*/
|
||||||
|
sqlite3_stmt* m_statement;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The BigFile DB
|
||||||
|
*/
|
||||||
|
sqlite3* m_db;
|
||||||
|
};
|
||||||
|
} // namespace Bigfoot
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1 +0,0 @@
|
|||||||
// to delete when an actual source is in Engine
|
|
||||||
@@ -68,6 +68,12 @@ class Log
|
|||||||
*/
|
*/
|
||||||
void ChangeLoggerLogLevel(LoggerInfo& p_loggerInfo, const Flat::LogLevel p_level);
|
void ChangeLoggerLogLevel(LoggerInfo& p_loggerInfo, const Flat::LogLevel p_level);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flush all the loggers
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void Flush();
|
||||||
|
|
||||||
~Log();
|
~Log();
|
||||||
|
|
||||||
Log& operator=(const Log& p_logger) = delete;
|
Log& operator=(const Log& p_logger) = delete;
|
||||||
|
|||||||
@@ -79,6 +79,16 @@ void Log::SetLoggerLevel(const LoggerInfo& p_loggerInfo)
|
|||||||
|
|
||||||
/****************************************************************************************/
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
void Log::Flush()
|
||||||
|
{
|
||||||
|
for (quill::Logger* logger: quill::Frontend::get_all_loggers())
|
||||||
|
{
|
||||||
|
logger->flush_log();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
Log::~Log()
|
Log::~Log()
|
||||||
{
|
{
|
||||||
for (quill::Logger* logger: quill::Frontend::get_all_loggers())
|
for (quill::Logger* logger: quill::Frontend::get_all_loggers())
|
||||||
|
|||||||
@@ -4,8 +4,9 @@
|
|||||||
* \author Romain BOULLARD
|
* \author Romain BOULLARD
|
||||||
* \date October 2025
|
* \date October 2025
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
#ifndef BIGFOOT_UTILS_ASSERT_HPP
|
#ifndef BIGFOOT_SYSTEM_ASSERT_HPP
|
||||||
#define BIGFOOT_UTILS_ASSERT_HPP
|
#define BIGFOOT_SYSTEM_ASSERT_HPP
|
||||||
|
#include <System/Log/Log.hpp>
|
||||||
|
|
||||||
#if defined BIGFOOT_NOT_OPTIMIZED
|
#if defined BIGFOOT_NOT_OPTIMIZED
|
||||||
|
|
||||||
@@ -79,6 +80,10 @@
|
|||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
HANDLER::Handle(location, stacktrace(), p_message __VA_OPT__(, ) __VA_ARGS__); \
|
HANDLER::Handle(location, stacktrace(), p_message __VA_OPT__(, ) __VA_ARGS__); \
|
||||||
|
if (Bigfoot::Singleton<Bigfoot::Log>::HasInstance()) \
|
||||||
|
{ \
|
||||||
|
Bigfoot::Singleton<Bigfoot::Log>::Instance().Flush(); \
|
||||||
|
} \
|
||||||
BREAK; \
|
BREAK; \
|
||||||
std::abort(); \
|
std::abort(); \
|
||||||
} \
|
} \
|
||||||
|
|||||||
@@ -35,6 +35,16 @@ class Singleton
|
|||||||
return *eastl::bit_cast<TYPE*>(ms_instance.data());
|
return *eastl::bit_cast<TYPE*>(ms_instance.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the instance initialized
|
||||||
|
*
|
||||||
|
* \return True if initialized, false otherwise
|
||||||
|
*/
|
||||||
|
static constexpr bool HasInstance()
|
||||||
|
{
|
||||||
|
return ms_initialized;
|
||||||
|
}
|
||||||
|
|
||||||
class Lifetime
|
class Lifetime
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
158
Bigfoot/Tests/Engine/BigFile/BigFile.cpp
Normal file
158
Bigfoot/Tests/Engine/BigFile/BigFile.cpp
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
/*********************************************************************
|
||||||
|
* \file BigFile.cpp
|
||||||
|
*
|
||||||
|
* \author Romain BOULLARD
|
||||||
|
* \date December 2025
|
||||||
|
*********************************************************************/
|
||||||
|
#include <Engine/BigFile/BigFile.hpp>
|
||||||
|
|
||||||
|
#include <System/Log/Log.hpp>
|
||||||
|
#include <System/Time.hpp>
|
||||||
|
#include <System/UUID/UUID.hpp>
|
||||||
|
|
||||||
|
#include <Utils/Singleton.hpp>
|
||||||
|
#include <Utils/TargetMacros.h>
|
||||||
|
|
||||||
|
#include <EngineTests/BigFileInfo_generated.hpp>
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
namespace Bigfoot
|
||||||
|
{
|
||||||
|
class BigFileFixture: public ::testing::Test
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
void SetUp() override
|
||||||
|
{
|
||||||
|
BigFile::Request deleteHeader {m_bigFile, "DELETE FROM AssetHeader"};
|
||||||
|
BigFile::Request deleteAsset {m_bigFile, "DELETE FROM AssetHeader"};
|
||||||
|
|
||||||
|
m_bigFile.BeginTransaction();
|
||||||
|
deleteHeader.Execute();
|
||||||
|
deleteAsset.Execute();
|
||||||
|
m_bigFile.CommitTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
BIGFOOT_NOT_OPTIMIZED_ONLY(Singleton<Log>::Lifetime m_loggerLifetime;)
|
||||||
|
|
||||||
|
BigFile m_bigFile {File {BIGFILE_ENGINETESTS_LOCATION}};
|
||||||
|
};
|
||||||
|
|
||||||
|
/****************************************************************************************/
|
||||||
|
|
||||||
|
TEST_F(BigFileFixture, Lol)
|
||||||
|
{
|
||||||
|
UUID uuid;
|
||||||
|
UUID uuid2;
|
||||||
|
|
||||||
|
eastl::array<std::byte, 4> blob {std::byte {1}, std::byte {2}, std::byte {3}, std::byte {4}};
|
||||||
|
eastl::array<std::byte, 4> blob2 {std::byte {1}, std::byte {2}, std::byte {3}, std::byte {5}};
|
||||||
|
eastl::array<std::byte, 4> blob3 {std::byte {1}, std::byte {2}, std::byte {3}, std::byte {6}};
|
||||||
|
|
||||||
|
{
|
||||||
|
BigFile::Request assetHeaderRequest {
|
||||||
|
m_bigFile,
|
||||||
|
"INSERT INTO AssetHeader (UUID, Name, TypeID, TypeName) VALUES(?, ?, ?, ?)"};
|
||||||
|
assetHeaderRequest.Bind(1, static_cast<std::span<const std::byte, UUID::UUID_BYTE_SIZE>>(uuid));
|
||||||
|
assetHeaderRequest.Bind(2, "Test");
|
||||||
|
assetHeaderRequest.Bind(3, 42);
|
||||||
|
assetHeaderRequest.Bind(4, "TypeTest");
|
||||||
|
|
||||||
|
BigFile::Request assetRequest {m_bigFile, "INSERT INTO Asset (UUID, Asset) VALUES(?, ?)"};
|
||||||
|
assetRequest.Bind(1, static_cast<std::span<const std::byte, UUID::UUID_BYTE_SIZE>>(uuid));
|
||||||
|
assetRequest.Bind(2, blob);
|
||||||
|
|
||||||
|
BigFile::Request assetHeaderRequest2 {
|
||||||
|
m_bigFile,
|
||||||
|
"INSERT INTO AssetHeader (UUID, Name, TypeID, TypeName) VALUES(?, ?, ?, ?)"};
|
||||||
|
assetHeaderRequest2.Bind(1, static_cast<std::span<const std::byte, UUID::UUID_BYTE_SIZE>>(uuid2));
|
||||||
|
assetHeaderRequest2.Bind(2, "Test2");
|
||||||
|
assetHeaderRequest2.Bind(3, 42);
|
||||||
|
assetHeaderRequest2.Bind(4, "TypeTest");
|
||||||
|
|
||||||
|
BigFile::Request assetRequest2 {m_bigFile, "INSERT INTO Asset (UUID, Asset) VALUES(?, ?)"};
|
||||||
|
assetRequest2.Bind(1, static_cast<std::span<const std::byte, UUID::UUID_BYTE_SIZE>>(uuid2));
|
||||||
|
assetRequest2.Bind(2, blob3);
|
||||||
|
|
||||||
|
m_bigFile.BeginTransaction();
|
||||||
|
[[maybe_unused]]
|
||||||
|
std::uint32_t assetHeaderChangedCount = assetHeaderRequest.Execute();
|
||||||
|
[[maybe_unused]]
|
||||||
|
std::uint32_t assetChangedCount = assetRequest.Execute();
|
||||||
|
|
||||||
|
[[maybe_unused]]
|
||||||
|
std::uint32_t assetHeaderChangedCount2 = assetHeaderRequest2.Execute();
|
||||||
|
[[maybe_unused]]
|
||||||
|
std::uint32_t assetChangedCount2 = assetRequest2.Execute();
|
||||||
|
|
||||||
|
m_bigFile.CommitTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
BigFile::Request updateAsset {m_bigFile, "UPDATE Asset SET Asset = ? WHERE UUID = ?"};
|
||||||
|
updateAsset.Bind(1, blob2);
|
||||||
|
updateAsset.Bind(2, static_cast<std::span<const std::byte, UUID::UUID_BYTE_SIZE>>(uuid));
|
||||||
|
|
||||||
|
m_bigFile.BeginTransaction();
|
||||||
|
[[maybe_unused]]
|
||||||
|
std::uint32_t updateAssetChangedCount = updateAsset.Execute();
|
||||||
|
m_bigFile.CommitTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
BigFile::Request request {
|
||||||
|
m_bigFile,
|
||||||
|
"SELECT Name, TypeID, TypeName, CreateTime, ModificationTime FROM AssetHeader WHERE UUID = ?"};
|
||||||
|
request.Bind(1, static_cast<std::span<const std::byte, UUID::UUID_BYTE_SIZE>>(uuid));
|
||||||
|
|
||||||
|
[[maybe_unused]]
|
||||||
|
const bool get = request.Step();
|
||||||
|
|
||||||
|
[[maybe_unused]]
|
||||||
|
const eastl::string name {static_cast<eastl::string_view>(request.Get(0))};
|
||||||
|
[[maybe_unused]]
|
||||||
|
const std::uint32_t typeId = request.Get(1);
|
||||||
|
[[maybe_unused]]
|
||||||
|
const eastl::string typeName {static_cast<eastl::string_view>(request.Get(2))};
|
||||||
|
[[maybe_unused]]
|
||||||
|
const Time createTime = static_cast<std::int64_t>(request.Get(3));
|
||||||
|
[[maybe_unused]]
|
||||||
|
const Time modificationTime = static_cast<std::int64_t>(request.Get(4));
|
||||||
|
|
||||||
|
{
|
||||||
|
[[maybe_unused]]
|
||||||
|
const std::uint32_t year = createTime.Year();
|
||||||
|
[[maybe_unused]]
|
||||||
|
const std::uint32_t month = createTime.Month();
|
||||||
|
[[maybe_unused]]
|
||||||
|
const std::uint32_t day = createTime.Day();
|
||||||
|
[[maybe_unused]]
|
||||||
|
const std::uint32_t hour = createTime.Hour();
|
||||||
|
[[maybe_unused]]
|
||||||
|
const std::uint32_t minute = createTime.Minute();
|
||||||
|
[[maybe_unused]]
|
||||||
|
const std::uint32_t second = createTime.Second();
|
||||||
|
[[maybe_unused]]
|
||||||
|
const std::uint32_t microsecond = createTime.Microsecond();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
[[maybe_unused]]
|
||||||
|
const std::uint32_t year = modificationTime.Year();
|
||||||
|
[[maybe_unused]]
|
||||||
|
const std::uint32_t month = modificationTime.Month();
|
||||||
|
[[maybe_unused]]
|
||||||
|
const std::uint32_t day = modificationTime.Day();
|
||||||
|
[[maybe_unused]]
|
||||||
|
const std::uint32_t hour = modificationTime.Hour();
|
||||||
|
[[maybe_unused]]
|
||||||
|
const std::uint32_t minute = modificationTime.Minute();
|
||||||
|
[[maybe_unused]]
|
||||||
|
const std::uint32_t second = modificationTime.Second();
|
||||||
|
[[maybe_unused]]
|
||||||
|
const std::uint32_t microsecond = modificationTime.Microsecond();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Bigfoot
|
||||||
@@ -1 +0,0 @@
|
|||||||
// to delete when an actual test is in EngineTests
|
|
||||||
Reference in New Issue
Block a user