Add extracted tools: CitrineOS, OpenOCPP, ShapeShifter
- CitrineOS core extracted (CSMS OCPP 2.0.1) - OpenOCPP extracted (firmware OCPP 1.6J/2.0.1) - ShapeShifter library installed (pip install -e) - ShapeShifter specification extracted - EVerest extracted TODO updated with progress
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <exception>
|
||||
#include <string>
|
||||
|
||||
namespace everest::db {
|
||||
|
||||
/// \brief Base class for database-related exceptions
|
||||
class Exception : public std::exception {
|
||||
public:
|
||||
explicit Exception(const std::string& message) : msg(message) {
|
||||
}
|
||||
~Exception() noexcept override = default;
|
||||
|
||||
[[nodiscard]] const char* what() const noexcept override {
|
||||
return msg.c_str();
|
||||
}
|
||||
|
||||
protected:
|
||||
std::string msg;
|
||||
};
|
||||
|
||||
/// \brief Exception for database connection errors
|
||||
class ConnectionException : public Exception {
|
||||
public:
|
||||
explicit ConnectionException(const std::string& message) : Exception(message) {
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Exception that is used if expected table entries are not found
|
||||
class RequiredEntryNotFoundException : public Exception {
|
||||
public:
|
||||
explicit RequiredEntryNotFoundException(const std::string& message) : Exception(message) {
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Exception for errors during database migration
|
||||
class MigrationException : public Exception {
|
||||
public:
|
||||
explicit MigrationException(const std::string& message) : Exception(message) {
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Exception for errors during query execution
|
||||
class QueryExecutionException : public Exception {
|
||||
public:
|
||||
explicit QueryExecutionException(const std::string& message) : Exception(message) {
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace everest::db
|
||||
@@ -0,0 +1,109 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#ifndef EVEREST_SQLITE_USE_BOOST_FILESYSTEM
|
||||
#include <filesystem>
|
||||
#else
|
||||
#include <boost/filesystem.hpp>
|
||||
#endif
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <sqlite3.h>
|
||||
|
||||
#include <everest/database/sqlite/statement.hpp>
|
||||
|
||||
#ifndef EVEREST_SQLITE_USE_BOOST_FILESYSTEM
|
||||
namespace fs = std::filesystem;
|
||||
#else
|
||||
namespace fs = boost::filesystem;
|
||||
#endif
|
||||
|
||||
namespace everest::db::sqlite {
|
||||
|
||||
/// \brief Helper class for transactions. Will lock the database interface from new transaction until commit() or
|
||||
/// rollback() is called or the object destroyed
|
||||
class TransactionInterface {
|
||||
public:
|
||||
/// \brief Destructor of transaction: Will by default rollback unless commit() is called
|
||||
virtual ~TransactionInterface() = default;
|
||||
|
||||
/// \brief Commits the transaction and release the lock on the database interface
|
||||
virtual void commit() = 0;
|
||||
|
||||
/// \brief Aborts the transaction and release the lock on the database interface
|
||||
virtual void rollback() = 0;
|
||||
};
|
||||
|
||||
class ConnectionInterface {
|
||||
public:
|
||||
virtual ~ConnectionInterface() = default;
|
||||
|
||||
/// \brief Opens the database connection. Returns true if succeeded.
|
||||
virtual bool open_connection() = 0;
|
||||
|
||||
/// \brief Closes the database connection. Returns true if succeeded.
|
||||
virtual bool close_connection() = 0;
|
||||
|
||||
/// \brief Start a transaction on the database. Returns an object holding the transaction.
|
||||
/// \note This function can block until the previous transaction is finished.
|
||||
[[nodiscard]] virtual std::unique_ptr<TransactionInterface> begin_transaction() = 0;
|
||||
|
||||
/// \brief Immediately executes \p statement. Returns true if succeeded.
|
||||
virtual bool execute_statement(const std::string& statement) = 0;
|
||||
|
||||
/// \brief Returns a new StatementInterface to be used to perform more advanced sql statements.
|
||||
/// \note Will throw an std::runtime_error if the statement can't be prepared
|
||||
virtual std::unique_ptr<StatementInterface> new_statement(const std::string& sql) = 0;
|
||||
|
||||
/// \brief Returns the latest error message from sqlite3.
|
||||
virtual const char* get_error_message() = 0;
|
||||
|
||||
/// \brief Clears the table with name \p table. Returns true if succeeded.
|
||||
virtual bool clear_table(const std::string& table) = 0;
|
||||
|
||||
/// \brief Gets the last inserted rowid.
|
||||
virtual int64_t get_last_inserted_rowid() = 0;
|
||||
|
||||
/// \brief Helper function to set the user version of the database to \p version
|
||||
virtual void set_user_version(uint32_t version) = 0;
|
||||
|
||||
/// \brief Helper function to get the user version of the database.
|
||||
virtual uint32_t get_user_version() = 0;
|
||||
};
|
||||
|
||||
class Connection : public ConnectionInterface {
|
||||
private:
|
||||
sqlite3* db;
|
||||
const fs::path database_file_path;
|
||||
std::atomic_uint32_t open_count;
|
||||
std::timed_mutex transaction_mutex;
|
||||
|
||||
bool close_connection_internal(bool force_close);
|
||||
|
||||
public:
|
||||
explicit Connection(const fs::path& database_file_path) noexcept;
|
||||
|
||||
~Connection() override;
|
||||
|
||||
bool open_connection() override;
|
||||
bool close_connection() override;
|
||||
|
||||
[[nodiscard]] std::unique_ptr<TransactionInterface> begin_transaction() override;
|
||||
|
||||
bool execute_statement(const std::string& statement) override;
|
||||
std::unique_ptr<StatementInterface> new_statement(const std::string& sql) override;
|
||||
|
||||
const char* get_error_message() override;
|
||||
|
||||
bool clear_table(const std::string& table) override;
|
||||
|
||||
int64_t get_last_inserted_rowid() override;
|
||||
|
||||
uint32_t get_user_version() override;
|
||||
void set_user_version(uint32_t version) override;
|
||||
};
|
||||
|
||||
} // namespace everest::db::sqlite
|
||||
@@ -0,0 +1,12 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace everest::db::sqlite {
|
||||
template <typename T, typename U> T constexpr clamp_to(U len) {
|
||||
return (len <= std::numeric_limits<T>::max()) ? static_cast<T>(len) : std::numeric_limits<T>::max();
|
||||
}
|
||||
} // namespace everest::db::sqlite
|
||||
@@ -0,0 +1,27 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <everest/database/sqlite/connection.hpp>
|
||||
|
||||
namespace everest::db::sqlite {
|
||||
|
||||
class SchemaUpdater {
|
||||
private:
|
||||
ConnectionInterface* database;
|
||||
|
||||
public:
|
||||
/// \brief Class that can apply migration files to a database to update the schema
|
||||
/// \param database Interface for the database connection
|
||||
explicit SchemaUpdater(ConnectionInterface* database) noexcept;
|
||||
|
||||
/// \brief Apply migration files to a database to update the schema
|
||||
/// \param sql_migration_files_path Filesystem path to migration file folder
|
||||
/// \param target_schema_version The target schema version of the database
|
||||
/// \return True if migrations applied successfully, false otherwise. Database is not modified when the migration
|
||||
/// fails.
|
||||
bool apply_migration_files(const fs::path& migration_file_directory, uint32_t target_schema_version);
|
||||
};
|
||||
|
||||
} // namespace everest::db::sqlite
|
||||
@@ -0,0 +1,92 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
namespace everest::db::sqlite {
|
||||
|
||||
/// @brief Type used to indicate if SQLite should make a internal copy of a string
|
||||
enum class SQLiteString {
|
||||
Static, /// Indicates string will be valid for the whole statement
|
||||
Transient /// Indicates string might change during statement, SQLite should make a copy
|
||||
};
|
||||
|
||||
/// @bried Variant type for possible return value based on name getter
|
||||
using SqliteVariant = std::variant<std::monostate, int, double, int64_t, std::string>;
|
||||
|
||||
/// \brief Interface for Statement wrapper class that handles finalization, step, binding and column access of
|
||||
/// sqlite3_stmt
|
||||
class StatementInterface {
|
||||
public:
|
||||
virtual ~StatementInterface() = default;
|
||||
|
||||
virtual int step() = 0;
|
||||
virtual int reset() = 0;
|
||||
virtual int changes() = 0;
|
||||
|
||||
virtual int bind_text(const int idx, const std::string& val, SQLiteString lifetime = SQLiteString::Static) = 0;
|
||||
virtual int bind_text(const std::string& param, const std::string& val,
|
||||
SQLiteString lifetime = SQLiteString::Static) = 0;
|
||||
virtual int bind_int(const int idx, const int val) = 0;
|
||||
virtual int bind_int(const std::string& param, const int val) = 0;
|
||||
virtual int bind_int64(const int idx, const int64_t val) = 0;
|
||||
virtual int bind_int64(const std::string& param, const int64_t val) = 0;
|
||||
virtual int bind_double(const int idx, const double val) = 0;
|
||||
virtual int bind_double(const std::string& param, const double val) = 0;
|
||||
virtual int bind_null(const int idx) = 0;
|
||||
virtual int bind_null(const std::string& param) = 0;
|
||||
|
||||
virtual int get_number_of_rows() = 0;
|
||||
virtual int column_type(const int idx) = 0;
|
||||
virtual SqliteVariant column_variant(const std::string& name) = 0;
|
||||
virtual std::string column_text(const int idx) = 0;
|
||||
virtual std::optional<std::string> column_text_nullable(const int idx) = 0;
|
||||
virtual int column_int(const int idx) = 0;
|
||||
virtual int64_t column_int64(const int idx) = 0;
|
||||
virtual double column_double(const int idx) = 0;
|
||||
};
|
||||
|
||||
/// \brief RAII wrapper class that handles finalization, step, binding and column access of sqlite3_stmt
|
||||
class Statement : public StatementInterface {
|
||||
private:
|
||||
sqlite3_stmt* stmt;
|
||||
sqlite3* db;
|
||||
|
||||
public:
|
||||
Statement(sqlite3* db, const std::string& query);
|
||||
~Statement() override;
|
||||
|
||||
int step() override;
|
||||
int reset() override;
|
||||
int changes() override;
|
||||
|
||||
int bind_text(const int idx, const std::string& val, SQLiteString lifetime = SQLiteString::Static) override;
|
||||
int bind_text(const std::string& param, const std::string& val,
|
||||
SQLiteString lifetime = SQLiteString::Static) override;
|
||||
int bind_int(const int idx, const int val) override;
|
||||
int bind_int(const std::string& param, const int val) override;
|
||||
int bind_double(const int idx, const double val) override;
|
||||
int bind_double(const std::string& param, const double val) override;
|
||||
int bind_int64(const int idx, const int64_t val) override;
|
||||
int bind_int64(const std::string& param, const int64_t val) override;
|
||||
int bind_null(const int idx) override;
|
||||
int bind_null(const std::string& param) override;
|
||||
|
||||
int get_number_of_rows() override;
|
||||
int column_type(const int idx) override;
|
||||
SqliteVariant column_variant(const std::string& name) override;
|
||||
std::string column_text(const int idx) override;
|
||||
std::optional<std::string> column_text_nullable(const int idx) override;
|
||||
int column_int(const int idx) override;
|
||||
int64_t column_int64(const int idx) override;
|
||||
double column_double(const int idx) override;
|
||||
};
|
||||
|
||||
} // namespace everest::db::sqlite
|
||||
Reference in New Issue
Block a user