diff --git a/dev/constraints.h b/dev/constraints.h index e2dd984b..71f6c31c 100644 --- a/dev/constraints.h +++ b/dev/constraints.h @@ -156,6 +156,13 @@ namespace sqlite_orm { value_type value; }; + template + struct content_t { + using value_type = T; + + value_type value; + }; + /** * DEFAULT constraint class. * T is a value type. @@ -563,6 +570,16 @@ namespace sqlite_orm { return {std::move(value)}; } + /** + * content='' table constraint builder function. Used in FTS virtual tables. + * + * https://www.sqlite.org/fts5.html#contentless_tables + */ + template + internal::content_t content(T value) { + return {std::move(value)}; + } + /** * PRIMARY KEY table constraint builder function. */ diff --git a/dev/schema/table.h b/dev/schema/table.h index 70fb7e18..3fec77cf 100644 --- a/dev/schema/table.h +++ b/dev/schema/table.h @@ -36,7 +36,8 @@ namespace sqlite_orm { check_if_is_template, check_if_is_template, check_if_is_template, - check_if_is_template>, + check_if_is_template, + check_if_is_template>, T>; #ifdef SQLITE_ORM_WITH_CTE diff --git a/dev/statement_serializer.h b/dev/statement_serializer.h index 8035a0a4..90d14073 100644 --- a/dev/statement_serializer.h +++ b/dev/statement_serializer.h @@ -1079,6 +1079,18 @@ namespace sqlite_orm { } }; + template + struct statement_serializer, void> { + using statement_type = content_t; + + template + std::string operator()(const statement_type& statement, const Ctx& context) const { + std::stringstream ss; + ss << "content=" << serialize(statement.value, context); + return ss.str(); + } + }; + template<> struct statement_serializer { using statement_type = collate_constraint_t; @@ -1094,8 +1106,8 @@ namespace sqlite_orm { using statement_type = default_t; template - std::string operator()(const statement_type& c, const Ctx& context) const { - return static_cast(c) + " (" + serialize(c.value, context) + ")"; + std::string operator()(const statement_type& statement, const Ctx& context) const { + return static_cast(statement) + " (" + serialize(statement.value, context) + ")"; } }; diff --git a/include/sqlite_orm/sqlite_orm.h b/include/sqlite_orm/sqlite_orm.h index e54d5f3a..1696b00b 100644 --- a/include/sqlite_orm/sqlite_orm.h +++ b/include/sqlite_orm/sqlite_orm.h @@ -1935,6 +1935,13 @@ namespace sqlite_orm { value_type value; }; + template + struct content_t { + using value_type = T; + + value_type value; + }; + /** * DEFAULT constraint class. * T is a value type. @@ -2342,6 +2349,16 @@ namespace sqlite_orm { return {std::move(value)}; } + /** + * content='' table constraint builder function. Used in FTS virtual tables. + * + * https://www.sqlite.org/fts5.html#contentless_tables + */ + template + internal::content_t content(T value) { + return {std::move(value)}; + } + /** * PRIMARY KEY table constraint builder function. */ @@ -11419,7 +11436,8 @@ namespace sqlite_orm { check_if_is_template, check_if_is_template, check_if_is_template, - check_if_is_template>, + check_if_is_template, + check_if_is_template>, T>; #ifdef SQLITE_ORM_WITH_CTE @@ -19617,6 +19635,18 @@ namespace sqlite_orm { } }; + template + struct statement_serializer, void> { + using statement_type = content_t; + + template + std::string operator()(const statement_type& statement, const Ctx& context) const { + std::stringstream ss; + ss << "content=" << serialize(statement.value, context); + return ss.str(); + } + }; + template<> struct statement_serializer { using statement_type = collate_constraint_t; @@ -19632,8 +19662,8 @@ namespace sqlite_orm { using statement_type = default_t; template - std::string operator()(const statement_type& c, const Ctx& context) const { - return static_cast(c) + " (" + serialize(c.value, context) + ")"; + std::string operator()(const statement_type& statement, const Ctx& context) const { + return static_cast(statement) + " (" + serialize(statement.value, context) + ")"; } }; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b13578d9..27dd9f62 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -100,6 +100,7 @@ add_executable(unit_tests statement_serializer_tests/table_constraints/prefix.cpp statement_serializer_tests/table_constraints/foreign_key.cpp statement_serializer_tests/table_constraints/tokenize.cpp + statement_serializer_tests/table_constraints/content.cpp statement_serializer_tests/bindables.cpp statement_serializer_tests/ast/upsert_clause.cpp statement_serializer_tests/ast/excluded.cpp diff --git a/tests/statement_serializer_tests/schema/using_fts5.cpp b/tests/statement_serializer_tests/schema/using_fts5.cpp index 61f3cce2..33103845 100644 --- a/tests/statement_serializer_tests/schema/using_fts5.cpp +++ b/tests/statement_serializer_tests/schema/using_fts5.cpp @@ -43,5 +43,10 @@ TEST_CASE("statement_serializer using_fts5") { expected = R"(USING FTS5("title", "body", tokenize = 'unicode61 remove_diacritics 1'))"; } } + SECTION("content") { + auto node = using_fts5(make_column("title", &Post::title), make_column("body", &Post::body), content("")); + value = serialize(node, context); + expected = R"(USING FTS5("title", "body", content=''))"; + } REQUIRE(value == expected); } diff --git a/tests/statement_serializer_tests/table_constraints/content.cpp b/tests/statement_serializer_tests/table_constraints/content.cpp new file mode 100644 index 00000000..72704b34 --- /dev/null +++ b/tests/statement_serializer_tests/table_constraints/content.cpp @@ -0,0 +1,17 @@ +#include +#include + +using namespace sqlite_orm; + +TEST_CASE("statement_serializer content") { + internal::db_objects_tuple<> storage; + internal::serializer_context> context{storage}; + std::string value; + std::string expected; + SECTION("empty") { + auto node = content(""); + value = serialize(node, context); + expected = "content=''"; + } + REQUIRE(value == expected); +}