Added create_index

This commit is contained in:
Dr. Patrick Urbanke
2025-05-18 18:12:55 +02:00
parent b7598c55a6
commit 9afa1867d7
16 changed files with 432 additions and 8 deletions

View File

@@ -17,6 +17,7 @@
#include "sqlgen/begin_transaction.hpp"
#include "sqlgen/col.hpp"
#include "sqlgen/commit.hpp"
#include "sqlgen/create_index.hpp"
#include "sqlgen/create_table.hpp"
#include "sqlgen/delete_from.hpp"
#include "sqlgen/drop.hpp"

View File

@@ -0,0 +1,76 @@
#ifndef SQLGEN_CREATEINDEX_HPP_
#define SQLGEN_CREATEINDEX_HPP_
#include <rfl.hpp>
#include "Ref.hpp"
#include "Result.hpp"
#include "transpilation/columns_t.hpp"
#include "transpilation/to_create_index.hpp"
namespace sqlgen {
template <class ValueType, class ColumnsType, class WhereType>
Result<Ref<Connection>> create_index_impl(const Ref<Connection>& _conn,
const std::string& _name,
const bool _unique,
const bool _if_not_exists,
const WhereType& _where) {
const auto query =
transpilation::to_create_index<ValueType, ColumnsType, WhereType>(
_name, _unique, _if_not_exists, _where);
return _conn->execute(_conn->to_sql(query)).transform([&](const auto&) {
return _conn;
});
}
template <class ValueType, class ColumnsType, class WhereType>
Result<Ref<Connection>> create_index_impl(const Result<Ref<Connection>>& _res,
const std::string& _name,
const bool _unique,
const bool _if_not_exists,
const WhereType& _where) {
return _res.and_then([&](const auto& _conn) {
return create_index_impl<ValueType, ColumnsType, WhereType>(
_conn, _name, _unique, _if_not_exists, _where);
});
}
template <rfl::internal::StringLiteral _name, class ValueType, class WhereType,
class... ColTypes>
struct CreateIndex {
Result<Ref<Connection>> operator()(const auto& _conn) const noexcept {
try {
return create_index_impl<ValueType,
transpilation::columns_t<ValueType, ColTypes...>,
WhereType>(_conn, _name.str(), unique_,
if_not_exists_, where_);
} catch (std::exception& e) {
return error(e.what());
}
}
bool unique_ = false;
bool if_not_exists_ = false;
WhereType where_;
};
template <rfl::internal::StringLiteral _name, class ValueType,
class... ColTypes>
auto create_index(const ColTypes&...) {
return CreateIndex<_name, ValueType, Nothing, ColTypes...>{
.unique_ = false, .if_not_exists_ = false};
}
template <rfl::internal::StringLiteral _name, class ValueType,
class... ColTypes>
auto create_unique_index(const ColTypes&...) {
return CreateIndex<_name, ValueType, Nothing, ColTypes...>{
.unique_ = true, .if_not_exists_ = false};
}
}; // namespace sqlgen
#endif

View File

@@ -37,8 +37,8 @@ struct CreateTable {
bool if_not_exists_;
};
template <class ContainerType>
const auto create_table = CreateTable<ContainerType>{};
template <class ValueType>
const auto create_table = CreateTable<ValueType>{};
}; // namespace sqlgen

View File

@@ -0,0 +1,26 @@
#ifndef SQLGEN_DYNAMIC_CREATEINDEX_HPP_
#define SQLGEN_DYNAMIC_CREATEINDEX_HPP_
#include <string>
#include <vector>
#include "Column.hpp"
#include "Condition.hpp"
#include "Table.hpp"
namespace sqlgen::dynamic {
struct CreateIndex {
std::string name;
Table table;
std::vector<std::string> columns;
bool unique = false;
bool if_not_exists = true;
std::optional<Condition> where = std::nullopt;
};
} // namespace sqlgen::dynamic
#endif

View File

@@ -13,7 +13,6 @@ struct CreateTable {
Table table;
std::vector<Column> columns;
bool if_not_exists = true;
// TODO: Constraints
};
} // namespace sqlgen::dynamic

View File

@@ -3,6 +3,7 @@
#include <rfl.hpp>
#include "CreateIndex.hpp"
#include "CreateTable.hpp"
#include "DeleteFrom.hpp"
#include "Drop.hpp"
@@ -12,8 +13,8 @@
namespace sqlgen::dynamic {
using Statement = rfl::TaggedUnion<"stmt", CreateTable, DeleteFrom, Drop,
Insert, SelectFrom, Update>;
using Statement = rfl::TaggedUnion<"stmt", CreateIndex, CreateTable, DeleteFrom,
Drop, Insert, SelectFrom, Update>;
} // namespace sqlgen::dynamic

View File

@@ -0,0 +1,34 @@
#ifndef SQLGEN_TRANSPILATION_COLUMNST_HPP_
#define SQLGEN_TRANSPILATION_COLUMNST_HPP_
#include <rfl.hpp>
#include <type_traits>
#include <vector>
#include "../col.hpp"
#include "Desc.hpp"
#include "all_columns_exist.hpp"
namespace sqlgen::transpilation {
template <class... _ColTypes>
struct Columns {
rfl::Tuple<_ColTypes...> values;
static std::vector<std::string> to_vec() {
return std::vector<std::string>({_ColTypes().name()...});
}
};
template <class T, class... ColTypes>
auto make_columns() {
static_assert(all_columns_exist<T, ColTypes...>(), "All columns must exist.");
return Columns<ColTypes...>{};
}
template <class T, class... ColTypes>
using columns_t = std::invoke_result_t<decltype(make_columns<T, ColTypes...>)>;
} // namespace sqlgen::transpilation
#endif

View File

@@ -0,0 +1,37 @@
#ifndef SQLGEN_TRANSPILATION_TO_CREATE_INDEX_HPP_
#define SQLGEN_TRANSPILATION_TO_CREATE_INDEX_HPP_
#include <rfl.hpp>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
#include "../dynamic/CreateIndex.hpp"
#include "../dynamic/Table.hpp"
#include "get_schema.hpp"
#include "get_tablename.hpp"
#include "to_condition.hpp"
namespace sqlgen::transpilation {
template <class T, class ColumnsType, class WhereType>
requires std::is_class_v<std::remove_cvref_t<T>> &&
std::is_aggregate_v<std::remove_cvref_t<T>>
dynamic::CreateIndex to_create_index(const std::string& _name,
const bool _unique,
const bool _if_not_exists,
const WhereType& _where) {
return dynamic::CreateIndex{
.name = _name,
.table =
dynamic::Table{.name = get_tablename<T>(), .schema = get_schema<T>()},
.columns = ColumnsType::to_vec(),
.unique = _unique,
.if_not_exists = _if_not_exists,
.where = to_condition<std::remove_cvref_t<T>>(_where)};
}
} // namespace sqlgen::transpilation
#endif

View File

@@ -4,12 +4,15 @@
#include <vector>
#include "../Insert.hpp"
#include "../create_index.hpp"
#include "../create_table.hpp"
#include "../delete_from.hpp"
#include "../drop.hpp"
#include "../dynamic/Statement.hpp"
#include "../read.hpp"
#include "../update.hpp"
#include "columns_t.hpp"
#include "to_create_index.hpp"
#include "to_create_table.hpp"
#include "to_delete_from.hpp"
#include "to_drop.hpp"
@@ -23,6 +26,17 @@ namespace sqlgen::transpilation {
template <class T>
struct ToSQL;
template <rfl::internal::StringLiteral _name, class ValueType, class WhereType,
class... ColTypes>
struct ToSQL<CreateIndex<_name, ValueType, WhereType, ColTypes...>> {
dynamic::Statement operator()(const auto& _create_index) const {
return transpilation::to_create_index<
ValueType, columns_t<ValueType, ColTypes...>, WhereType>(
_name.str(), _create_index.unique_, _create_index.if_not_exists_,
_create_index.where_);
}
};
template <class T>
struct ToSQL<CreateTable<T>> {
dynamic::Statement operator()(const auto&) const {