Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
ee3abe3
Started implementing SQL views
trueqbit Jun 7, 2024
ea10616
Merged upstream/dev into experimental/sql-view
trueqbit Sep 24, 2025
89b4805
Renamed `storage_t<>::sync_table()` -> `storage_t<>::sync_dbo()`
trueqbit Sep 24, 2025
8fc8506
Used `c_str()` instead of `data()` for executing SQL string
trueqbit Sep 24, 2025
3627014
Added SQL view to the schema
trueqbit Sep 24, 2025
759aa24
Guarded availability of the SQL view feature
trueqbit Sep 24, 2025
5f9b0c7
Alias template that filters columns of a table
trueqbit Sep 25, 2025
8b3902a
Made sql views working with CTEs
trueqbit Sep 25, 2025
733e1b7
Used the new facility to access the main select to reduce lines of code
trueqbit Sep 25, 2025
add9aeb
Generalized preparing and executing 'raw' DML statements
trueqbit Sep 25, 2025
5b23b3c
Streamlined executing and logging SQL statements
trueqbit Sep 26, 2025
996c34e
Generalized serializer context
trueqbit Sep 26, 2025
aebf0cf
Restructured classes representing table database objects
trueqbit Sep 26, 2025
1c363c1
Pull in Boost PFR if available
trueqbit Sep 26, 2025
d450e3d
Merge branch 'upstream/feature/rtree-vtab' into experimental/sql-view
trueqbit Oct 3, 2025
af22d4a
Include SQLite3 configuration in funcational/config.h
trueqbit Oct 3, 2025
5ee55eb
Automatically include boost-pfr if available
trueqbit Oct 3, 2025
e3c08e1
Merge branch 'upstream/dev' into experimental/sql-view
trueqbit Oct 3, 2025
0fcfe6a
Direct database operations for
trueqbit Oct 3, 2025
1579107
Renamed `view_t` -> `query_view`
trueqbit Oct 3, 2025
63dbea9
Disable boost-pfr when testing the sqlite_orm C++ module
trueqbit Oct 3, 2025
f7cf5d6
Used a custom implementation of `offsetof`
trueqbit Oct 4, 2025
a0bdb6c
Merge branch 'dev' into experimental/sql-view
trueqbit Oct 23, 2025
302119f
Merge branch 'dev' into experimental/sql-view
trueqbit Nov 1, 2025
415b462
Removed duplicate C++ feature test
trueqbit Nov 23, 2025
c880626
Used `std::size_t` for PFR related function
trueqbit Nov 23, 2025
139bda0
Creation of `query_view` with C++26 reflection syntax
trueqbit Nov 23, 2025
b81e4d1
Merge remote-tracking branch 'origin/dev' into experimental/sql-view
trueqbit Nov 23, 2025
bbfec0b
`stream_identifier()` with an index sequence needs to be available
trueqbit Nov 23, 2025
b3373e4
Used the single-argument version of `static_assert`
trueqbit Nov 23, 2025
273bab0
Accommodated for Clang on Windows, which cannot use constexpr DLL exp…
trueqbit Nov 23, 2025
af5a8c3
Merge branch 'clang-related' into experimental/sql-view
trueqbit Nov 24, 2025
d62d21f
Merge branch 'dev' into experimental/sql-view
trueqbit Dec 9, 2025
8de3fac
Added an example for SQL views
trueqbit Dec 9, 2025
c0890d9
Merge branch 'c++17-code-quality' into experimental/sql-view
trueqbit Dec 9, 2025
ea1dcee
Merge branch 'dev' into experimental/sql-view
trueqbit Dec 9, 2025
e8d30b0
Compile with `gcc-16 -std=c++26 -freflection`
trueqbit Apr 25, 2026
1bfd411
Merge remote-tracking branch 'origin/dev' into experimental/sql-view
trueqbit Apr 25, 2026
98709d0
`rank()` should only be used as a window function
trueqbit Apr 25, 2026
2b9a462
Sync query views with schema
trueqbit Apr 25, 2026
98bdf43
Corrected compile options target for examples
trueqbit Apr 26, 2026
30cbcab
Updated .clang-format-ignore with paths that the github linter action…
trueqbit Apr 26, 2026
663fa8b
Corrected superfluous space before comments
trueqbit Apr 26, 2026
f84a9d9
Updated TODO.md
trueqbit Apr 26, 2026
87b8913
Removed fallback to Boost.PFR for query views
trueqbit Apr 28, 2026
7ce965a
Removed code used in local test environment
trueqbit Apr 28, 2026
2c1121f
Address a few things popping up when compiling with GCC
trueqbit May 1, 2026
f80f0de
Supply query view name via C++ annotation
trueqbit May 1, 2026
4027035
Adjust testing enabled query view
trueqbit May 1, 2026
5c7e8ec
Corrected no-warning option
trueqbit May 1, 2026
5398c1d
Corrected a few mixed up things again
trueqbit May 1, 2026
68382d8
Capture only the variables that are needed
trueqbit May 1, 2026
fcbfb11
Considered base members for reflected views/tables
trueqbit May 2, 2026
c3b847b
github actions: try C++26/gcc-16 tests
trueqbit May 2, 2026
1ced217
Addressed points raised in review
trueqbit May 2, 2026
234e5f9
Use github action lukka/run-vcpkg with only the major version 11 again
trueqbit May 2, 2026
d8d39ed
Renamed `dbo_name_t` -> `dbo_name_literal`
trueqbit May 2, 2026
eb8f233
Merge remote-tracking branch 'origin/dev' into experimental/sql-view
trueqbit May 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ StatementMacros:
- _Pragma
- Q_UNUSED
- QT_REQUIRE_VERSION
WhitespaceSensitiveMacros: [SQLITE_ORM_HAS_INCLUDE]
TabWidth: 4
UseTab: Never
LineEnding: LF
Expand Down
2 changes: 2 additions & 0 deletions .clang-format-ignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# exclude until clang-format understands C++ reflection syntax
./dev/functional/meta_util.h
12 changes: 12 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,15 @@ jobs:
compiler_package: g++-11
experimental: true

- name: "gcc-16, C++26"
os: ubuntu-24.04
cc: gcc-16
cxx: g++-16
cxx_standard: "-DSQLITE_ORM_ENABLE_CXX_26=ON"
install_compiler: true
compiler_package: g++-16
compiler_ppa: ppa:ubuntu-toolchain-r/test

name: Linux - ${{ matrix.name }}

env:
Expand All @@ -143,6 +152,9 @@ jobs:
- name: Install compiler
if: matrix.install_compiler
run: |
if [ -n "${{ matrix.compiler_ppa }}" ]; then
sudo add-apt-repository -y ${{ matrix.compiler_ppa }}
fi
sudo apt-get update
sudo apt-get install -y ${{ matrix.compiler_package }}

Expand Down
1 change: 0 additions & 1 deletion TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
* rest of core functions(https://sqlite.org/lang_corefunc.html)
* `ATTACH`
* blob incremental I/O https://sqlite.org/c3ref/blob_open.html
* CREATE VIEW and other view operations https://sqlite.org/lang_createview.html
* query static check for correct order (e.g. `GROUP BY` after `WHERE`)
* `SAVEPOINT` https://www.sqlite.org/lang_savepoint.html
* add `static_assert` in crud `get*` functions in case user passes `where_t` instead of id to make compilation error more clear (example https://github.com/fnc12/sqlite_orm/issues/485)
Expand Down
2 changes: 1 addition & 1 deletion dev/ast/rank.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace sqlite_orm::internal {

SQLITE_ORM_EXPORT namespace sqlite_orm {
/**
* RANK() window function / FTS5 rank keyword.
* RANK() window function
* https://sqlite.org/windowfunctions.html#built-in_window_functions
*/
inline internal::rank_t rank() {
Expand Down
9 changes: 9 additions & 0 deletions dev/conditions.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "type_printer.h"
#include "literal.h"
#include "ast/cross_join.h"
#include "ast/rank.h"

namespace sqlite_orm::internal {
/**
Expand Down Expand Up @@ -1016,6 +1017,14 @@ SQLITE_ORM_EXPORT namespace sqlite_orm {
return {std::move(o)};
}

/**
* [Deprecation notice] This expression factory function is deprecated and will be removed in v1.11.
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to deprecate it cause it is also used in window funcs and it is not going to be deprecated there. So I'd remove [Deprecation notice]

Copy link
Copy Markdown
Collaborator Author

@trueqbit trueqbit May 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

order_by(rank()) can only be used with FTS not with Window functions, that's why I added it here (actually moved from the rank() factory).

*/
[[deprecated("Use the hidden FTS5 rank column instead")]]
inline internal::order_by_t<internal::rank_t> order_by(internal::rank_t o) {
return {std::move(o)};
}

/**
* ORDER BY positional ordinal
*
Expand Down
2 changes: 1 addition & 1 deletion dev/cte_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ namespace sqlite_orm::internal {
auto make_cte_column(std::string name, const ColRef& finalColRef) {
using column_type = column_t<ColRef, empty_setter>;

return column_type{std::move(name), finalColRef, empty_setter{}};
return column_type{std::move(name), finalColRef, empty_setter{}, std::tuple<>{}};
}

#ifdef SQLITE_ORM_STRUCTURED_BINDING_PACK_SUPPORTED
Expand Down
4 changes: 4 additions & 0 deletions dev/functional/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@

#define SQLITE_ORM_WITH_CTE

#if defined(SQLITE_ORM_REFLECTION_SUPPORTED)
#define SQLITE_ORM_WITH_VIEW
#endif

// define the inline namespace "literals" so that it is available even if it was not introduced by a feature
namespace sqlite_orm {
inline namespace literals {}
Expand Down
8 changes: 4 additions & 4 deletions dev/functional/cxx_core_features.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,6 @@
#define SQLITE_ORM_CLASSTYPE_TEMPLATE_ARGS_SUPPORTED
#endif

#if __cpp_nontype_template_args >= 201911L
#define SQLITE_ORM_CLASSTYPE_TEMPLATE_ARGS_SUPPORTED
#endif

#if __cpp_explicit_this_parameter >= 202110L
#define SQLITE_ORM_DEDUCING_THIS_SUPPORTED
#endif
Expand All @@ -67,6 +63,10 @@
#define SQLITE_ORM_CONTRACTS_SUPPORTED
#endif

#if __cpp_impl_reflection >= 202506L
#define SQLITE_ORM_REFLECTION_SUPPORTED
#endif

#if __cplusplus >= 202002L
#define SQLITE_ORM_DEFAULT_COMPARISONS_SUPPORTED
#define SQLITE_ORM_INITSTMT_RANGE_BASED_FOR_SUPPORTED
Expand Down
87 changes: 87 additions & 0 deletions dev/functional/meta_util.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#pragma once

#ifndef SQLITE_ORM_IMPORT_STD_MODULE
#ifdef SQLITE_ORM_REFLECTION_SUPPORTED
#include <array> // std::array
#include <meta> // std::define_static_array, std::meta::access_context, std::meta::nonstatic_data_members_of, std::meta::identifier_of, std::meta::annotations_of
#include <tuple> // std::tuple
#include <utility> // std::index_sequence, std::make_index_sequence
#endif
#endif

#ifdef SQLITE_ORM_REFLECTION_SUPPORTED
namespace sqlite_orm::internal {
/**
* Reflects the non-static data members of `T` and its base classes
* and returns them as a fixed-size span of `std::meta::info` reflections.
*/
template<class T>
consteval auto extract_members() {
constexpr auto ctx = std::meta::access_context::current();

constexpr auto collect = []<class U>(this const auto& self) -> std::vector<std::meta::info> {
std::vector<std::meta::info> result;

// Recurse into direct base classes first (preserves layout order)
template for (constexpr std::meta::info base : std::define_static_array(bases_of(^^U, ctx))) {
using base_type = typename[:type_of(base):];
result.append_range(self.template operator()<base_type>());
}

// Then this class's own non-static data members
result.append_range(nonstatic_data_members_of(^^U, ctx));

return result;
};

return std::define_static_array(collect.template operator()<T>());
}

/**
* Returns the identifier of `T`.
*/
template<class T>
consteval auto extract_type_identifier() {
return std::meta::identifier_of(^^T);
}

/**
* Splices a non-static data member reflection into a member-pointer expression.
* Encapsulated here so the splice operator does not leak into consumer headers.
*/
template<std::meta::info member>
consteval auto splice_member_pointer() {
return &[:member:];
}

/**
* Splices a reflection's annotations into a tuple of values. The reflection may be
* a type or a non-static data member.
* Encapsulated here so the splice operator does not leak into consumer headers.
*
* Two P3394 details inform this implementation:
* - Annotation reflections returned by `annotations_of` are not directly spliceable;
* they must first be routed through `std::meta::constant_of`, which returns a
* splice-able constant reflection.
* - `std::meta::annotations_of` returns a `std::vector<std::meta::info>`, whose heap
* allocation is transient under C++20 constexpr rules and cannot be bound to a
* `constexpr` variable. The size and per-index lookups therefore re-call
* `annotations_of` inline so each transient vector dies within its own constant
* expression.
*/
template<std::meta::info refl>
consteval auto splice_annotations() {
return []<size_t... I>(std::index_sequence<I...>) consteval {
return std::tuple{[:std::meta::constant_of(std::meta::annotations_of(refl)[I]):]...};
}(std::make_index_sequence<std::meta::annotations_of(refl).size()>{});
}

/**
* Returns the class-scope annotations of `T` as a tuple.
*/
template<class T>
consteval auto extract_type_annotations() {
return splice_annotations<^^T>();
}
}
#endif
6 changes: 6 additions & 0 deletions dev/functional/mpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,12 @@ namespace sqlite_orm::internal {
template<template<typename...> class Op>
using check_if_lacks = mpl::not_<check_if_names<Op>>;

/*
* Quoted metafunction that finds the index of the element having the specified trait in a tuple.
*/
template<template<class...> class TraitFn>
using finds_if_has = mpl::finds<check_if<TraitFn>>;

/*
* Quoted metafunction that finds the index of the given type in a tuple.
*/
Expand Down
1 change: 0 additions & 1 deletion dev/mapped_type_proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

#include "functional/cxx_type_traits_polyfill.h"
#include "type_traits.h"
#include "table_reference.h"
#include "alias_traits.h"

namespace sqlite_orm::internal {
Expand Down
3 changes: 2 additions & 1 deletion dev/object_from_column_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "functional/gsl.h"
#include "member_traits/member_traits.h"
#include "type_traits.h"
#include "table_reference.h"
#include "row_extractor.h"
#include "schema/column.h"
Expand Down Expand Up @@ -46,7 +47,7 @@ namespace sqlite_orm::internal {
/**
* Specialization for a table reference.
*
* This plays together with `column_result_of_t`, which returns `object_t<O>` as `table_referenece<O>`
* This plays together with `column_result_of_t`, which returns `object_t<O>` as `table_reference<O>`
*/
template<class O, class DBOs>
struct struct_extractor<table_reference<O>, DBOs> {
Expand Down
84 changes: 84 additions & 0 deletions dev/schema/dbo_name.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#pragma once

#ifndef SQLITE_ORM_IMPORT_STD_MODULE
#ifdef SQLITE_ORM_REFLECTION_SUPPORTED
#include <string_view> // std::string_view
#include <tuple> // std::tuple
#include <type_traits> // std::bool_constant
#include <utility> // std::forward
#endif
#endif

#include "../functional/cstring_literal.h"
#include "../functional/meta_util.h"
#include "../functional/mpl.h"
#include "../tuple_helper/tuple_filter.h"
#include "../tuple_helper/tuple_traits.h"

#ifdef SQLITE_ORM_REFLECTION_SUPPORTED
namespace sqlite_orm::internal {
/**
* Class-scope annotation that overrides the database object name (table or view).
* When absent, the name falls back to `std::meta::identifier_of(^^T)`.
*
* The string is embedded in the type's bytes via `cstring_literal<N>` rather than
* carried by pointer + size: pointers to string literals are not accepted as
* annotation values by current reflection implementations (the underlying object
* has no linkage), so a self-contained fixed-size byte array is required.
*/
template<size_t N>
struct dbo_name_literal : cstring_literal<N> {
constexpr dbo_name_literal(const char (&cstr)[N]) : cstring_literal<N>{cstr} {}

constexpr auto name() const noexcept {
return this->cstr;
}
};

template<class T>
constexpr bool is_dbo_name_v = false;

template<size_t N>
constexpr bool is_dbo_name_v<dbo_name_literal<N>> = true;

template<class T>
using is_dbo_name = std::bool_constant<is_dbo_name_v<T>>;

/**
* Returns the database object name carried by the `dbo_name_literal<…>` element of `annotations`,
* or the type's reflected identifier when no such element is present.
*/
template<class T, class Tuple>
constexpr std::string_view resolve_dbo_name(const Tuple& annotations) {
using name_index = find_tuple_element<Tuple, is_dbo_name>;

if constexpr (name_index::value < std::tuple_size_v<Tuple>) {
return std::get<name_index::value>(annotations).name();
} else {
return extract_type_identifier<T>();
}
}

/**
* Returns a copy of `tuple` with all `dbo_name_literal<…>` elements removed.
*/
template<class Tuple>
constexpr auto filter_out_dbo_name(Tuple&& tuple) {
using constraints_index_sequence = filter_tuple_sequence_t<Tuple, check_if_not<is_dbo_name>::template fn>;
return create_from_tuple<std::tuple>(std::forward<Tuple>(tuple), constraints_index_sequence{});
}
}

SQLITE_ORM_EXPORT namespace sqlite_orm {
/**
* Database object name annotation factory.
* Use as a class-scope annotation: `struct [[=dbo_name("users")]] User { ... };`.
* Both `make_table<T>()` and `make_view<T>()` consume this annotation; when absent
* the name falls back to `T`'s reflected identifier.
*/
template<size_t N>
constexpr internal::dbo_name_literal<N> dbo_name(const char (&dboName)[N]) {
return {dboName};
}
}
#endif
2 changes: 1 addition & 1 deletion dev/schema/table_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ namespace sqlite_orm::internal {
}

/**
* Mixin for a base table, providing methods used to access a mapped object's members.
* Mixin for a base table, providing methods used to access a mapped object's member variables for insertion.
*
* Implementation note: it is provided as a mixin to reduce the number of involved template parameters,
* which is possible in C++23 mode for 'getters'.
Expand Down
Loading
Loading