relx 0.1.0
A Modern C++23 Type-Safe SQL Query Builder
Loading...
Searching...
No Matches
index.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "../utils/error_handling.hpp"
4#include "column.hpp"
5#include "meta.hpp"
6#include "table.hpp"
7
8#include <string_view>
9#include <type_traits>
10#include <vector>
11
12namespace relx::schema {
13
15// Keep the names lowercase to match the lowercase table api
16// NOLINTNEXTLINE(readability-identifier-naming)
17enum class index_type : uint8_t { normal, unique, fulltext, spatial };
18
22constexpr std::string_view index_type_to_string(index_type type) {
23 switch (type) {
25 return "UNIQUE ";
27 return "FULLTEXT ";
29 return "SPATIAL ";
30 case index_type::normal: // Fall through
31 default:
32 return "";
33 }
34}
35
38template <auto ColumnPtr>
39class index {
40public:
42 index() : type_(index_type::normal) {}
43
46 explicit index(index_type type) : type_(type) {}
47
50 std::string create_index_sql() const {
51 // Extract the column name from the pointer
52 using table_type = typename member_pointer_class<decltype(ColumnPtr)>::type;
53 using column_type = typename member_pointer_type<decltype(ColumnPtr)>::type;
54
55 // Get the table name directly
56 std::string table_name = std::string(table_type::table_name);
57 std::string column_name = std::string(column_type::name);
58
59 const std::string index_name = table_name + "_" + column_name + "_idx";
60
61 std::string result = "CREATE ";
62 result += std::string(index_type_to_string(type_));
63 result += "INDEX " + index_name + " ON ";
64 result += table_name + " (" + column_name + ")";
65
66 return result;
67 }
68
69private:
70 index_type type_;
71};
72
75template <auto... ColumnPtrs>
77public:
80
83 explicit composite_index(index_type type) : type_(type) {}
84
87 std::string create_index_sql() const {
88 // Get the table name (assuming all columns are from the same table)
89 std::string table_name = get_table_name<0>();
90
91 // Build the column list and collect all column names
92 std::string column_list;
93 std::vector<std::string> column_names;
94
95 // Process all column pointers to build column list and names
96 (append_column_info<ColumnPtrs>(column_list, column_names, column_list.empty() ? "" : ", "),
97 ...);
98
99 // Generate index name from table name and column names
100 std::string index_name = table_name + "_";
101 for (size_t i = 0; i < column_names.size(); ++i) {
102 index_name += column_names[i];
103 if (i < column_names.size() - 1) {
104 index_name += "_";
105 }
106 }
107 index_name += "_idx";
108
109 // Build the CREATE INDEX statement
110 std::string result = "CREATE ";
111 result += std::string(index_type_to_string(type_));
112 result += "INDEX " + index_name + " ON ";
113 result += table_name + " (" + column_list + ")";
114
115 return result;
116 }
117
118private:
119 index_type type_;
120
121 // Helper to get the table name using the first column in the parameter pack
122 template <size_t I>
123 std::string get_table_name() const {
124 if constexpr (I < sizeof...(ColumnPtrs)) {
125 using first_col_ptr_t = std::tuple_element_t<I, std::tuple<decltype(ColumnPtrs)...>>;
126 using table_t =
127 typename std::remove_reference_t<typename table_for_column<first_col_ptr_t>::type>;
128 return std::string(table_t::table_name);
129 }
130 // Make static assert if template parameters are incorrect
131 static_assert(I < sizeof...(ColumnPtrs),
132 "Invalid index template parameters: no columns provided");
133 return ""; // This line will never be reached due to static_assert
134 }
135
136 // Helper type to extract the table type from a column pointer
137 template <typename T>
138 struct table_for_column;
139
140 template <typename C, typename T>
141 struct table_for_column<T C::*> {
142 using type = C;
143 };
144
145 // Helper to append column info to the column list and index name
146 template <auto ColumnPtr>
147 void append_column_info(std::string& column_list, std::vector<std::string>& column_names,
148 const std::string& separator) const {
149 using col_type = decltype(ColumnPtr);
150 using column_type = typename std::remove_reference_t<typename column_type_for<col_type>::type>;
151 std::string column_name = std::string(column_type::name);
152
153 // Add to column list with separator if needed
154 column_list += separator + column_name;
155
156 // Add to column names vector
157 column_names.push_back(column_name);
158 }
159
160 // Helper to extract the column type from a column pointer
161 template <typename T>
162 struct column_type_for;
163
164 template <typename C, typename T>
165 struct column_type_for<T C::*> {
166 using type = T;
167 };
168};
169
170} // namespace relx::schema
Represents a composite index on multiple columns.
Definition index.hpp:76
composite_index()
Default constructor - creates a normal index.
Definition index.hpp:79
std::string create_index_sql() const
Get SQL statement for creating the composite index.
Definition index.hpp:87
composite_index(index_type type)
Constructor with specific index type.
Definition index.hpp:83
Represents an index on a table.
Definition index.hpp:39
index(index_type type)
Constructor with specific index type.
Definition index.hpp:46
index()
Default constructor - creates a normal index.
Definition index.hpp:42
std::string create_index_sql() const
Get SQL statement for creating the index.
Definition index.hpp:50
index_type
Index types.
Definition index.hpp:17
constexpr std::string_view index_type_to_string(index_type type)
Convert index type to SQL string.
Definition index.hpp:22
Helper to extract the class type from a member pointer.
Definition meta.hpp:10
Helper to extract the member type from a member pointer.
Definition meta.hpp:28
UNIQUE constraint.
Definition column.hpp:14