Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
186ca63
Literal holders should be left as is in the node tuple ...
trueqbit Oct 5, 2025
c3efeb2
Hidden virtual table columns and table values when defining a dbstat …
trueqbit Oct 5, 2025
47083c7
Include SQLite3 configuration in funcational/config.h
trueqbit Oct 5, 2025
739ceba
Merge branch 'upstream/dev' into feature/hidden-vtab-columns
trueqbit Oct 5, 2025
0f02d5c
Corrected constructing table value wrapper
trueqbit Oct 5, 2025
cd41de2
Eponymous virtual tables can now be used as table-valued functions
trueqbit Oct 6, 2025
3c1a238
Got rid of table name collector factory function.
trueqbit Oct 12, 2025
6d49fab
appveyor: Updated vcpkg environment to 2025.09.17
trueqbit Oct 12, 2025
9a1c31a
Hidden virtual table columns, table-valued functions, table refs for …
trueqbit Oct 12, 2025
c25a11c
GENERATE_SERIES virtual table support
trueqbit Oct 12, 2025
953463d
Corrected download location of series.c
trueqbit Oct 12, 2025
6885772
Need to qualify call to `random()`
trueqbit Oct 13, 2025
ae7ee4e
Corrected enabling the table-valued function
trueqbit Oct 13, 2025
15c809e
Ignore annoying clang compiler warnings about using future C++ features
trueqbit Oct 13, 2025
dfd0290
Disabled deprecation warnings for unit tests in CMakeLists.txt
trueqbit Oct 13, 2025
f857fcb
Negated clang compiler option to disable deprecation warning for unit…
trueqbit Oct 14, 2025
6b02c63
Copy arguments in `storage_base`'s copy constructor
trueqbit Oct 17, 2025
d698264
Simplified code for virtual tables in respect to C++17
trueqbit Oct 17, 2025
4584e61
Proper argument binding in table-valued function expression
trueqbit Oct 18, 2025
e003824
Explicit From for Get All statements
trueqbit Oct 19, 2025
64c93ec
Hidden FTS5 column named after the table
trueqbit Oct 20, 2025
c337b81
Merge branch 'dev' into feature/hidden-vtab-columns
trueqbit Oct 22, 2025
f806e84
Correct spelling mistake - "exluding" -> "excluding"
trueqbit Oct 22, 2025
10c27a7
Moved function to top of unit test file
trueqbit Oct 22, 2025
d2ed6a0
Merge branch 'dev' into feature/hidden-vtab-columns
trueqbit Oct 22, 2025
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
47 changes: 43 additions & 4 deletions dev/alias_traits.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
#pragma once

#ifndef SQLITE_ORM_IMPORT_STD_MODULE
#include <type_traits> // std::is_base_of, std::is_same
#ifdef SQLITE_ORM_WITH_CPP20_ALIASES
#include <type_traits> // std::is_base_of, std::is_same, std::remove_const
#ifdef SQLITE_ORM_CPP20_CONCEPTS_SUPPORTED
#include <concepts>
#endif
#endif

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

SQLITE_ORM_EXPORT namespace sqlite_orm {

Expand All @@ -20,6 +19,22 @@ SQLITE_ORM_EXPORT namespace sqlite_orm {

namespace sqlite_orm {
namespace internal {
template<class O>
struct table_reference;

template<class RecordSet>
struct decay_table_ref : std::remove_const<RecordSet> {};
template<class O>
struct decay_table_ref<table_reference<O>> : polyfill::type_identity<O> {};
template<class O>
struct decay_table_ref<const table_reference<O>> : polyfill::type_identity<O> {};

template<class RecordSet>
using decay_table_ref_t = typename decay_table_ref<RecordSet>::type;
#ifdef SQLITE_ORM_WITH_CPP20_ALIASES
template<auto recordset>
using auto_decay_table_ref_t = typename decay_table_ref<decltype(recordset)>::type;
#endif

template<class A>
inline constexpr bool is_alias_v = std::is_base_of<alias_tag, A>::value;
Expand All @@ -36,6 +51,13 @@ namespace sqlite_orm {
template<class A>
struct is_column_alias : is_alias<A> {};

template<class O>
inline constexpr bool is_table_reference_v =
polyfill::is_specialization_of_v<std::remove_const_t<O>, table_reference>;

template<class R>
struct is_table_reference : polyfill::bool_constant<is_table_reference_v<R>> {};

/** @short Alias of any type of record set, see `orm_recordset_alias`.
*/
template<class A>
Expand Down Expand Up @@ -68,11 +90,20 @@ namespace sqlite_orm {

template<class A>
using is_cte_moniker = polyfill::bool_constant<is_cte_moniker_v<A>>;

/** @short Referring to a recordset.
*/
template<class T>
inline constexpr bool is_referring_to_recordset_v =
polyfill::disjunction_v<is_table_reference<T>, is_recordset_alias<T>>;

template<class T>
using is_referring_to_recordset = polyfill::bool_constant<is_referring_to_recordset_v<T>>;
}
}

SQLITE_ORM_EXPORT namespace sqlite_orm {
#ifdef SQLITE_ORM_WITH_CPP20_ALIASES
#ifdef SQLITE_ORM_CPP20_CONCEPTS_SUPPORTED
template<class A>
concept orm_alias = std::derived_from<A, alias_tag>;

Expand All @@ -85,6 +116,14 @@ SQLITE_ORM_EXPORT namespace sqlite_orm {
template<class A>
concept orm_column_alias = (orm_alias<A> && !orm_names_type<A>);

/** @short Specifies that a type is a reference of a concrete table, especially of a derived class.
*
* A concrete table reference has the following traits:
* - specialization of `table_reference`, whose `type` typename references a mapped object.
*/
template<class O>
concept orm_table_reference = polyfill::is_specialization_of_v<std::remove_const_t<O>, internal::table_reference>;

/** @short Specifies that a type is an alias of any type of record set.
*
* A record set alias has the following traits:
Expand Down
48 changes: 37 additions & 11 deletions dev/ast/match.h
Original file line number Diff line number Diff line change
@@ -1,25 +1,51 @@
#pragma once

#ifndef SQLITE_ORM_IMPORT_STD_MODULE
#include <utility>
#include <utility> // std::move
#endif

namespace sqlite_orm {
namespace internal {
#include "../type_traits.h"

template<class T, class X>
struct match_t {
using mapped_type = T;
using argument_type = X;
namespace sqlite_orm::internal {
template<class T, class X>
struct match_with_table_t {
using mapped_type = T;
using argument_type = X;

argument_type argument;
};
}
argument_type argument;
};

/*
* Alternative equality comparison where the left side is always a field.
*/
template<class Field, class X>
struct match_t {
using field_type = Field;
using argument_type = X;

field_type field;
argument_type argument;
};
}

SQLITE_ORM_EXPORT namespace sqlite_orm {
/**
* [Deprecation notice] This expression factory function is deprecated and will be removed in v1.11.
*/
template<class T, class X>
internal::match_t<T, X> match(X argument) {
[[deprecated(
"Use the `match` function accepting the hidden FTS5 'any' field or a field of your FTS table instead")]]
constexpr internal::match_with_table_t<T, X> match(X argument) {
return {std::move(argument)};
}

template<class CP, class X>
constexpr internal::match_t<CP, X> match(CP field, X argument) {
return {std::move(field), std::move(argument)};
}

template<class O, class F, class X>
constexpr internal::match_t<F O::*, X> match(F O::* field, X argument) {
return {field, std::move(argument)};
}
}
4 changes: 4 additions & 0 deletions dev/ast/rank.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ namespace sqlite_orm {
}

SQLITE_ORM_EXPORT namespace sqlite_orm {
/**
* [Deprecation notice] This expression factory function is deprecated and will be removed in v1.11.
*/
[[deprecated("Use the hidden FTS5 rank column instead")]]
inline internal::rank_t rank() {
return {};
}
Expand Down
35 changes: 33 additions & 2 deletions dev/ast_iterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,18 @@ namespace sqlite_orm {
};

template<class T, class X>
struct ast_iterator<match_t<T, X>, void> {
using node_type = match_t<T, X>;
struct ast_iterator<match_with_table_t<T, X>, void> {
using node_type = match_with_table_t<T, X>;

template<class L>
SQLITE_ORM_STATIC_CALLOP void operator()(const node_type& node, L& lambda) SQLITE_ORM_OR_CONST_CALLOP {
iterate_ast(node.argument, lambda);
}
};

template<class Field, class X>
struct ast_iterator<match_t<Field, X>, void> {
using node_type = match_t<Field, X>;

template<class L>
SQLITE_ORM_STATIC_CALLOP void operator()(const node_type& node, L& lambda) SQLITE_ORM_OR_CONST_CALLOP {
Expand Down Expand Up @@ -158,6 +168,27 @@ namespace sqlite_orm {
}
};

template<class T>
struct ast_iterator<T, match_if<is_table_valued_expression, T>> {
using node_type = T;

template<class L>
SQLITE_ORM_STATIC_CALLOP void operator()(const node_type& expression,
L& lambda) SQLITE_ORM_OR_CONST_CALLOP {
iterate_ast(expression.table_values, lambda);
}
};

template<class T>
struct ast_iterator<T, match_if<is_from2, T>> {
using node_type = T;

template<class L>
SQLITE_ORM_STATIC_CALLOP void operator()(const node_type& from, L& lambda) SQLITE_ORM_OR_CONST_CALLOP {
iterate_ast(from.table_expressions, lambda);
}
};

template<class C>
struct ast_iterator<where_t<C>, void> {
using node_type = where_t<C>;
Expand Down
46 changes: 21 additions & 25 deletions dev/column_pointer.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once

#ifndef SQLITE_ORM_IMPORT_STD_MODULE
#include <type_traits> // std::enable_if, std::is_convertible
#include <type_traits> // std::enable_if, std::is_convertible, std::is_base_of
#include <utility> // std::move
#endif

Expand Down Expand Up @@ -53,49 +53,45 @@ SQLITE_ORM_EXPORT namespace sqlite_orm {
*/
template<class O, class Base, class F, internal::satisfies_not<internal::is_recordset_alias, O> = true>
constexpr internal::column_pointer<O, F Base::*> column(F Base::* field) {
static_assert(std::is_convertible<F Base::*, F O::*>::value, "Field must be from derived class");
static_assert(std::is_convertible<F Base::*, F O::*>::value ||
std::is_same<polyfill::detected_t<internal::enclosing_type_of_t, Base, O>, O>::value ||
// trust the `enclosing_type` alias template defined in the virtual table's data struct
polyfill::is_detected_v<internal::enclosing_type_t, Base>,
"Field must be from derived or related class");
return {field};
}

#ifdef SQLITE_ORM_WITH_CPP20_ALIASES
/**
* Explicitly refer to a column.
*/
template<orm_table_reference auto table, class O, class F>
constexpr auto column(F O::* field) {
template<orm_table_reference auto table, class Base, class F>
constexpr auto column(F Base::* field) {
return column<internal::auto_type_t<table>>(field);
}
#endif

// Intentionally place pointer-to-member operator for table references in the internal namespace
// to facilitate ADL (Argument Dependent Lookup)
namespace internal {
#ifdef SQLITE_ORM_WITH_CPP20_ALIASES
/**
* Explicitly refer to a column.
*/
template<orm_table_reference R, class O, class F>
constexpr auto operator->*(const R& /*table*/, F O::* field) {
template<orm_table_reference R, class Base, class F>
constexpr auto operator->*(const R& /*table*/, F Base::* field) {
return column<typename R::type>(field);
}
#else
/**
* Explicitly refer to a column.
*/
template<class R, class Base, class F, std::enable_if_t<internal::is_table_reference_v<R>, bool> = true>
constexpr auto operator->*(const R& /*table*/, F Base::* field) {
return column<typename R::type>(field);
}
}

/**
* Make a table reference.
*/
template<class O>
requires (!orm_recordset_alias<O>)
consteval internal::table_reference<O> column() {
return {};
}

/**
* Make a table reference.
*/
template<class O>
requires (!orm_recordset_alias<O>)
consteval internal::table_reference<O> c() {
return {};
}
#endif
}

#if (SQLITE_VERSION_NUMBER >= 3008003) && defined(SQLITE_ORM_WITH_CTE)
/**
Expand Down
Loading