Skip to content

Commit 9e82466

Browse files
C++ query builder
1 parent 635f9d8 commit 9e82466

31 files changed

Lines changed: 2229 additions & 78 deletions

crates/bindings-cpp/CMakeLists.txt

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -76,30 +76,39 @@ option(BUILD_TESTS "Build the test suite" ${_is_top_level})
7676

7777
if(BUILD_TESTS AND NOT CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
7878
enable_testing()
79-
80-
# Add test executable
79+
80+
# Existing module-library unit-test target
8181
add_executable(test_bsatn tests/main.cpp tests/module_library_unit_tests.cpp)
82-
83-
# Link against the module library
8482
target_link_libraries(test_bsatn PRIVATE spacetimedb_cpp_library)
85-
86-
# Set C++20 standard for tests
8783
target_compile_features(test_bsatn PRIVATE cxx_std_20)
88-
89-
# Add test to CTest
9084
add_test(NAME bsatn_tests COMMAND test_bsatn)
91-
92-
# Add verbose test variant
9385
add_test(NAME bsatn_tests_verbose COMMAND test_bsatn -v)
94-
95-
# Set test properties
96-
set_tests_properties(bsatn_tests PROPERTIES
86+
set_tests_properties(bsatn_tests PROPERTIES
9787
TIMEOUT 30
9888
LABELS "unit"
9989
)
100-
101-
set_tests_properties(bsatn_tests_verbose PROPERTIES
90+
set_tests_properties(bsatn_tests_verbose PROPERTIES
10291
TIMEOUT 30
10392
LABELS "unit;verbose"
10493
)
94+
95+
# Query-builder SQL rendering tests
96+
add_executable(query_builder_sql_tests
97+
tests/query-builder-sql/main.cpp
98+
tests/query-builder-sql/query_builder_sql_tests.cpp)
99+
100+
target_include_directories(query_builder_sql_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
101+
102+
# Set C++20 standard for tests
103+
target_compile_features(query_builder_sql_tests PRIVATE cxx_std_20)
104+
105+
# Add test to CTest
106+
add_test(NAME query_builder_sql_tests COMMAND query_builder_sql_tests)
107+
108+
# Set test properties
109+
set_tests_properties(query_builder_sql_tests PROPERTIES
110+
TIMEOUT 30
111+
LABELS "unit"
112+
)
113+
105114
endif()

crates/bindings-cpp/include/spacetimedb.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@
133133

134134
// View context and macros
135135
#include "spacetimedb/view_macros.h"
136+
#include "spacetimedb/query_builder.h"
136137

137138
// =============================================================================
138139
// CONVENIENCE ALIASES AND COMPATIBILITY

crates/bindings-cpp/include/spacetimedb/client_visibility_filter.h

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#pragma once
22

3+
#include "spacetimedb/query_builder.h"
4+
35
#include <string>
46

57
namespace SpacetimeDB {
@@ -21,21 +23,33 @@ namespace SpacetimeDB {
2123
/// will be reported during `spacetime publish`, not at compile time.
2224
class Filter {
2325
private:
24-
const char* sql_text_;
26+
std::string sql_text_;
2527

2628
public:
2729
/// Create a SQL-based client visibility filter
2830
static Filter Sql(const char* sql) {
2931
return Filter(sql);
3032
}
3133

34+
/// Create a SQL-based client visibility filter from an owned string
35+
static Filter Sql(std::string sql) {
36+
return Filter(std::move(sql));
37+
}
38+
39+
/// Create a SQL-based client visibility filter from a typed query-builder value.
40+
template<query_builder::QueryLike TQuery>
41+
static Filter Sql(const TQuery& query) {
42+
return Filter(query.into_sql());
43+
}
44+
3245
/// Get the SQL text for this filter
33-
const char* sql_text() const {
46+
const std::string& sql_text() const {
3447
return sql_text_;
3548
}
3649

3750
private:
38-
explicit Filter(const char* sql) : sql_text_(sql) {}
51+
explicit Filter(const char* sql) : sql_text_(sql != nullptr ? sql : "") {}
52+
explicit Filter(std::string sql) : sql_text_(std::move(sql)) {}
3953
};
4054

41-
} // namespace SpacetimeDB
55+
} // namespace SpacetimeDB

crates/bindings-cpp/include/spacetimedb/internal/Module.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ class Module {
106106
public:
107107
// Registration support routed through the V10 module-definition builder.
108108
static void RegisterClientVisibilityFilter(const char* sql);
109+
static void RegisterClientVisibilityFilter(const std::string& sql);
109110
static void SetCaseConversionPolicy(CaseConversionPolicy policy);
110111
static void RegisterExplicitTableName(const std::string& source_name, const std::string& canonical_name);
111112
static void RegisterExplicitFunctionName(const std::string& source_name, const std::string& canonical_name);
@@ -143,6 +144,10 @@ class Module {
143144
static void RegisterClientVisibilityFilter(const char* sql) {
144145
Internal::Module::RegisterClientVisibilityFilter(sql);
145146
}
147+
148+
static void RegisterClientVisibilityFilter(const std::string& sql) {
149+
Internal::Module::RegisterClientVisibilityFilter(sql);
150+
}
146151

147152
// Module metadata (future extension)
148153
static void SetMetadata([[maybe_unused]] const char* name, [[maybe_unused]] const char* version) {

crates/bindings-cpp/include/spacetimedb/internal/v10_builder.h

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "autogen/RawRowLevelSecurityDefV9.g.h"
3333
#include "autogen/RawTypeDefV10.g.h"
3434
#include "field_registration.h"
35+
#include "../query_builder.h"
3536
#include "buffer_pool.h"
3637
#include "runtime_registration.h"
3738
#include "template_utils.h"
@@ -462,10 +463,14 @@ class V10Builder {
462463
[func](ViewContext& ctx, BytesSource args_source) -> std::vector<uint8_t> {
463464
(void)args_source;
464465
auto result = func(ctx);
465-
auto result_vec = view_result_to_vec(std::move(result));
466466
IterBuf buf = IterBuf::take();
467-
{
468-
bsatn::Writer writer(buf.get());
467+
bsatn::Writer writer(buf.get());
468+
if constexpr (query_builder::QueryBuilderReturn<ReturnType>) {
469+
writer.write_u8(1);
470+
bsatn::serialize(writer, result.into_sql());
471+
} else {
472+
writer.write_u8(0);
473+
auto result_vec = view_result_to_vec(std::move(result));
469474
bsatn::serialize(writer, result_vec);
470475
}
471476
return buf.release();
@@ -476,10 +481,14 @@ class V10Builder {
476481
[func](AnonymousViewContext& ctx, BytesSource args_source) -> std::vector<uint8_t> {
477482
(void)args_source;
478483
auto result = func(ctx);
479-
auto result_vec = view_result_to_vec(std::move(result));
480484
IterBuf buf = IterBuf::take();
481-
{
482-
bsatn::Writer writer(buf.get());
485+
bsatn::Writer writer(buf.get());
486+
if constexpr (query_builder::QueryBuilderReturn<ReturnType>) {
487+
writer.write_u8(1);
488+
bsatn::serialize(writer, result.into_sql());
489+
} else {
490+
writer.write_u8(0);
491+
auto result_vec = view_result_to_vec(std::move(result));
483492
bsatn::serialize(writer, result_vec);
484493
}
485494
return buf.release();
@@ -488,8 +497,17 @@ class V10Builder {
488497
}
489498

490499
auto& type_reg = getModuleTypeRegistration();
491-
auto bsatn_return = bsatn::bsatn_traits<ReturnType>::algebraic_type();
492-
AlgebraicType return_type = type_reg.registerType(bsatn_return, "", &typeid(ReturnType));
500+
AlgebraicType return_type = [&]() {
501+
if constexpr (query_builder::QueryBuilderReturn<ReturnType>) {
502+
using RowType = query_builder::query_row_type_t<ReturnType>;
503+
auto row_bsatn = bsatn::bsatn_traits<RowType>::algebraic_type();
504+
auto row_type = type_reg.registerType(row_bsatn, "", &typeid(RowType));
505+
return MakeQueryReturnAlgebraicType(std::move(row_type));
506+
} else {
507+
auto bsatn_return = bsatn::bsatn_traits<ReturnType>::algebraic_type();
508+
return type_reg.registerType(bsatn_return, "", &typeid(ReturnType));
509+
}
510+
}();
493511
bool is_anonymous = std::is_same_v<ContextType, AnonymousViewContext>;
494512
uint32_t index = static_cast<uint32_t>(is_anonymous ? (GetAnonymousViewHandlerCount() - 1) : (GetViewHandlerCount() - 1));
495513

@@ -647,6 +665,7 @@ class V10Builder {
647665
uint16_t field_idx) const;
648666
static AlgebraicType MakeUnitAlgebraicType();
649667
static AlgebraicType MakeStringAlgebraicType();
668+
static AlgebraicType MakeQueryReturnAlgebraicType(AlgebraicType row_type);
650669

651670
std::vector<std::pair<std::string, bool>> table_is_event_;
652671
std::optional<CaseConversionPolicy> case_conversion_policy_;

0 commit comments

Comments
 (0)