diff --git a/docs/README.md b/docs/README.md index 1cb25e6..5cc1278 100644 --- a/docs/README.md +++ b/docs/README.md @@ -18,6 +18,7 @@ Welcome to the sqlgen documentation. This guide provides detailed information ab - [sqlgen::update](update.md) - How to update data in a table - [sqlgen::delete_from](delete_from.md) - How to delete data from a table - [sqlgen::drop](drop.md) - How to drop a table +- [sqlgen::create_index](create_index.md) - How to create an index on a table - [Transactions](transactions.md) - How to use transactions for atomic operations ## Data Types and Validation diff --git a/include/sqlgen/where.hpp b/include/sqlgen/where.hpp index 1c64a67..d186855 100644 --- a/include/sqlgen/where.hpp +++ b/include/sqlgen/where.hpp @@ -4,6 +4,7 @@ #include #include "Result.hpp" +#include "create_index.hpp" #include "delete_from.hpp" #include "read.hpp" #include "transpilation/Limit.hpp" @@ -17,6 +18,19 @@ struct Where { ConditionType condition; }; +template +auto operator|(const CreateIndex<_name, ValueType, WhereType, ColTypes...>& _c, + const Where& _where) { + static_assert(std::is_same_v, + "You cannot call where(...) twice (but you can apply more " + "than one condition by combining them with && or ||)."); + return CreateIndex<_name, ValueType, ConditionType, ColTypes...>{ + .unique_ = _c.unique_, + .if_not_exists_ = _c.if_not_exists_, + .where_ = _where.condition}; +} + template auto operator|(const DeleteFrom& _d, const Where& _where) { diff --git a/tests/postgres/test_create_index_where.cpp b/tests/postgres/test_create_index_where.cpp new file mode 100644 index 0000000..b2860a3 --- /dev/null +++ b/tests/postgres/test_create_index_where.cpp @@ -0,0 +1,45 @@ +#ifndef SQLGEN_BUILD_DRY_TESTS_ONLY + +#include + +#include +#include +#include +#include +#include + +namespace test_create_index_where { + +struct Person { + sqlgen::PrimaryKey id; + std::string first_name; + std::string last_name; + int age; +}; + +TEST(postgres, test_create_index_where) { + const auto credentials = sqlgen::postgres::Credentials{.user = "postgres", + .password = "password", + .host = "localhost", + .dbname = "postgres"}; + + using namespace sqlgen; + + const auto people = + sqlgen::postgres::connect(credentials) + .and_then(drop | if_exists) + .and_then(create_table | if_not_exists) + .and_then(create_index<"test_table_ix", Person>( + "first_name"_c, "last_name"_c, "age"_c) | + if_not_exists | where("age"_c > 0)) + .and_then(sqlgen::read>) + .value(); + + const std::string expected = R"([])"; + + EXPECT_EQ(rfl::json::write(people), expected); +} + +} // namespace test_create_index_where + +#endif diff --git a/tests/postgres/test_create_index_where_dry.cpp b/tests/postgres/test_create_index_where_dry.cpp new file mode 100644 index 0000000..4f1e148 --- /dev/null +++ b/tests/postgres/test_create_index_where_dry.cpp @@ -0,0 +1,27 @@ +#include + +#include +#include + +namespace test_create_index_where_dry { + +struct TestTable { + std::string field1; + int32_t field2; + sqlgen::PrimaryKey id; + std::optional nullable; +}; + +TEST(postgres, test_create_index_where_dry) { + using namespace sqlgen; + + const auto query = + create_index<"test_table_ix", TestTable>("field1"_c, "field2"_c) | + if_not_exists | where("field2"_c > 0); + + const auto expected = + R"(CREATE INDEX IF NOT EXISTS "test_table_ix" ON "TestTable"("field1", "field2") WHERE "field2" > 0;)"; + + EXPECT_EQ(sqlgen::postgres::to_sql(query), expected); +} +} // namespace test_create_index_where_dry