diff --git a/dev/ast_iterator.h b/dev/ast_iterator.h index f332f0636..41a17e531 100644 --- a/dev/ast_iterator.h +++ b/dev/ast_iterator.h @@ -106,6 +106,18 @@ namespace sqlite_orm { } }; + template + struct ast_iterator, void> { + using node_type = highlight_t; + + template + void operator()(const node_type& expression, L& lambda) const { + iterate_ast(expression.argument0, lambda); + iterate_ast(expression.argument1, lambda); + iterate_ast(expression.argument2, lambda); + } + }; + template struct ast_iterator, void> { using node_type = excluded_t; diff --git a/dev/column_result.h b/dev/column_result.h index b5d2fd745..d3b5f02a5 100644 --- a/dev/column_result.h +++ b/dev/column_result.h @@ -225,6 +225,11 @@ namespace sqlite_orm { using type = typename T::result_type; }; + template + struct column_result_t, void> { + using type = std::string; + }; + /** * Result for the most simple queries like `SELECT 1` */ diff --git a/dev/core_functions.h b/dev/core_functions.h index 6412efd6f..9e813f35b 100644 --- a/dev/core_functions.h +++ b/dev/core_functions.h @@ -612,6 +612,21 @@ namespace sqlite_orm { template using field_type_or_type_t = polyfill::detected_or_t>; + + template + struct highlight_t { + using table_type = T; + using argument0_type = X; + using argument1_type = Y; + using argument2_type = Z; + + argument0_type argument0; + argument1_type argument1; + argument2_type argument2; + + highlight_t(argument0_type argument0, argument1_type argument1, argument2_type argument2) : + argument0(std::move(argument0)), argument1(std::move(argument1)), argument2(std::move(argument2)) {} + }; } /** @@ -2102,4 +2117,9 @@ namespace sqlite_orm { return {get_from_expression(std::forward(l)), get_from_expression(std::forward(r))}; } } + + template + internal::highlight_t highlight(X x, Y y, Z z) { + return {std::move(x), std::move(y), std::move(z)}; + } } diff --git a/dev/node_tuple.h b/dev/node_tuple.h index dc088922c..a277ba325 100644 --- a/dev/node_tuple.h +++ b/dev/node_tuple.h @@ -63,6 +63,14 @@ namespace sqlite_orm { using type = tuple_cat_t...>; }; + template + struct node_tuple, void> { + using x_node_tuple = node_tuple_t; + using y_node_tuple = node_tuple_t; + using z_node_tuple = node_tuple_t; + using type = tuple_cat_t; + }; + template struct node_tuple, void> : node_tuple {}; diff --git a/dev/statement_serializer.h b/dev/statement_serializer.h index c85d96513..dbbf39a29 100644 --- a/dev/statement_serializer.h +++ b/dev/statement_serializer.h @@ -134,6 +134,22 @@ namespace sqlite_orm { } }; + template + struct statement_serializer, void> { + using statement_type = highlight_t; + + template + std::string operator()(const statement_type& statement, const Ctx& context) { + std::stringstream ss; + auto& tableName = lookup_table_name(context.db_objects); + ss << "HIGHLIGHT (" << streaming_identifier(tableName); + ss << ", " << serialize(statement.argument0, context); + ss << ", " << serialize(statement.argument1, context); + ss << ", " << serialize(statement.argument2, context) << ")"; + return ss.str(); + } + }; + /** * Serializer for literal values. */ diff --git a/dev/table_name_collector.h b/dev/table_name_collector.h index 549b8c82f..a85dc51dc 100644 --- a/dev/table_name_collector.h +++ b/dev/table_name_collector.h @@ -85,6 +85,11 @@ namespace sqlite_orm { void operator()(const table__rowid_t&) { this->table_names.emplace(lookup_table_name(this->db_objects), ""); } + + template + void operator()(const highlight_t&) { + this->table_names.emplace(lookup_table_name(this->db_objects), ""); + } }; template = true> diff --git a/include/sqlite_orm/sqlite_orm.h b/include/sqlite_orm/sqlite_orm.h index 5552acdb4..717a5bec6 100644 --- a/include/sqlite_orm/sqlite_orm.h +++ b/include/sqlite_orm/sqlite_orm.h @@ -5169,6 +5169,21 @@ namespace sqlite_orm { template using field_type_or_type_t = polyfill::detected_or_t>; + + template + struct highlight_t { + using table_type = T; + using argument0_type = X; + using argument1_type = Y; + using argument2_type = Z; + + argument0_type argument0; + argument1_type argument1; + argument2_type argument2; + + highlight_t(argument0_type argument0, argument1_type argument1, argument2_type argument2) : + argument0(std::move(argument0)), argument1(std::move(argument1)), argument2(std::move(argument2)) {} + }; } /** @@ -6659,6 +6674,11 @@ namespace sqlite_orm { return {get_from_expression(std::forward(l)), get_from_expression(std::forward(r))}; } } + + template + internal::highlight_t highlight(X x, Y y, Z z) { + return {std::move(x), std::move(y), std::move(z)}; + } } #pragma once @@ -10910,6 +10930,11 @@ namespace sqlite_orm { using type = typename T::result_type; }; + template + struct column_result_t, void> { + using type = std::string; + }; + /** * Result for the most simple queries like `SELECT 1` */ @@ -11481,6 +11506,11 @@ namespace sqlite_orm { void operator()(const table__rowid_t&) { this->table_names.emplace(lookup_table_name(this->db_objects), ""); } + + template + void operator()(const highlight_t&) { + this->table_names.emplace(lookup_table_name(this->db_objects), ""); + } }; template = true> @@ -12477,6 +12507,18 @@ namespace sqlite_orm { } }; + template + struct ast_iterator, void> { + using node_type = highlight_t; + + template + void operator()(const node_type& expression, L& lambda) const { + iterate_ast(expression.argument0, lambda); + iterate_ast(expression.argument1, lambda); + iterate_ast(expression.argument2, lambda); + } + }; + template struct ast_iterator, void> { using node_type = excluded_t; @@ -15550,6 +15592,22 @@ namespace sqlite_orm { } }; + template + struct statement_serializer, void> { + using statement_type = highlight_t; + + template + std::string operator()(const statement_type& statement, const Ctx& context) { + std::stringstream ss; + auto& tableName = lookup_table_name(context.db_objects); + ss << "HIGHLIGHT (" << streaming_identifier(tableName); + ss << ", " << serialize(statement.argument0, context); + ss << ", " << serialize(statement.argument1, context); + ss << ", " << serialize(statement.argument2, context) << ")"; + return ss.str(); + } + }; + /** * Serializer for literal values. */ @@ -18991,6 +19049,14 @@ namespace sqlite_orm { using type = tuple_cat_t...>; }; + template + struct node_tuple, void> { + using x_node_tuple = node_tuple_t; + using y_node_tuple = node_tuple_t; + using z_node_tuple = node_tuple_t; + using type = tuple_cat_t; + }; + template struct node_tuple, void> : node_tuple {}; diff --git a/tests/table_name_collector.cpp b/tests/table_name_collector.cpp index 3a5b813ed..ace2aa2c9 100644 --- a/tests/table_name_collector.cpp +++ b/tests/table_name_collector.cpp @@ -15,10 +15,10 @@ TEST_CASE("table name collector") { auto dbObjects = db_objects_t{table}; internal::table_name_collector_base::table_name_set expected; - SECTION("from table") { - internal::serializer_context context{dbObjects}; - auto collector = internal::make_table_name_collector(context.db_objects); + internal::serializer_context context{dbObjects}; + auto collector = internal::make_table_name_collector(context.db_objects); + SECTION("from table") { SECTION("regular column") { using als = alias_z; auto expression = &User::id; @@ -44,4 +44,16 @@ TEST_CASE("table name collector") { } REQUIRE(collector.table_names == expected); } + SECTION("highlight") { + SECTION("simple") { + auto expression = highlight(0, "", ""); + expected.emplace(table.name, ""); + iterate_ast(expression, collector); + } + SECTION("in columns") { + auto expression = columns(highlight(0, "", "")); + expected.emplace(table.name, ""); + iterate_ast(expression, collector); + } + } }