Skip to content

Commit 9b5b28c

Browse files
committed
Merge branch 'dev' into experimental/threadsafe_connection
2 parents 14dd6b4 + 92b7959 commit 9b5b28c

File tree

101 files changed

+5912
-2733
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+5912
-2733
lines changed

appveyor.yml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ environment:
2727

2828
- job_name: clang, C++23
2929
appveyor_build_worker_image: Ubuntu2204
30-
CC: clang-18
31-
CXX: clang++-18
30+
CC: clang-20
31+
CXX: clang++-20
3232
SQLITE_ORM_CXX_STANDARD: "-DSQLITE_ORM_ENABLE_CXX_23=ON"
3333
cmake_build_parallel: ""
3434

@@ -108,12 +108,12 @@ for:
108108
install:
109109
- |-
110110
cd C:\Tools\vcpkg
111-
git fetch --tags && git checkout 2025.04.09
111+
git fetch --tags && git checkout 2025.09.17
112112
cd %APPVEYOR_BUILD_FOLDER%
113113
C:\Tools\vcpkg\bootstrap-vcpkg.bat -disableMetrics
114114
C:\Tools\vcpkg\vcpkg integrate install
115115
set VCPKG_DEFAULT_TRIPLET=%platform%-windows
116-
vcpkg install sqlite3[core,dbstat,math,json1,fts5,soundex]
116+
vcpkg install sqlite3[core,dbstat,math,json1,fts5,rtree,soundex]
117117
rem The Visual Studio 2017 build worker image comes with CMake 3.16 only, and sqlite_orm will build the Catch2 dependency from source
118118
if not "%appveyor_build_worker_image%"=="Visual Studio 2017" (vcpkg install catch2)
119119
before_build:
@@ -142,11 +142,11 @@ for:
142142
install:
143143
- |-
144144
pushd $HOME/vcpkg
145-
git fetch --tags && git checkout 2025.04.09
145+
git fetch --tags && git checkout 2025.09.17
146146
popd
147147
$HOME/vcpkg/bootstrap-vcpkg.sh -disableMetrics
148148
$HOME/vcpkg/vcpkg integrate install --overlay-triplets=vcpkg/triplets
149-
vcpkg install sqlite3[core,dbstat,math,json1,fts5,soundex] catch2 --overlay-triplets=vcpkg/triplets
149+
vcpkg install sqlite3[core,dbstat,math,json1,fts5,rtree,soundex] catch2 --overlay-triplets=vcpkg/triplets
150150
before_build:
151151
- |-
152152
mkdir compile
@@ -170,10 +170,10 @@ for:
170170
# using custom vcpkg triplets for building and linking dynamic dependent libraries
171171
install:
172172
- |-
173-
git clone --depth 1 --branch 2025.04.09 https://github.com/microsoft/vcpkg.git $HOME/vcpkg
173+
git clone --depth 1 --branch 2025.09.17 https://github.com/microsoft/vcpkg.git $HOME/vcpkg
174174
$HOME/vcpkg/bootstrap-vcpkg.sh -disableMetrics
175175
$HOME/vcpkg/vcpkg integrate install --overlay-triplets=vcpkg/triplets
176-
vcpkg install sqlite3[core,dbstat,math,json1,fts5,soundex] catch2 --overlay-triplets=vcpkg/triplets
176+
vcpkg install sqlite3[core,dbstat,math,json1,fts5,rtree,soundex] catch2 --overlay-triplets=vcpkg/triplets
177177
before_build:
178178
- |-
179179
mkdir compile

dev/alias.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ namespace sqlite_orm {
5858
is_operator_argument_v<T, std::enable_if_t<polyfill::is_specialization_of<T, alias_column_t>::value>> =
5959
true;
6060

61-
struct basic_table;
61+
struct table_identifier;
6262

6363
/*
6464
* Encapsulates extracting the alias identifier of a non-alias.
@@ -77,7 +77,7 @@ namespace sqlite_orm {
7777
return {};
7878
}
7979

80-
template<class X = basic_table>
80+
template<class X = table_identifier>
8181
static const std::string& as_qualifier(const X& table) {
8282
return table.name;
8383
}
@@ -114,7 +114,7 @@ namespace sqlite_orm {
114114

115115
// for regular table aliases -> alias identifier
116116
template<class T = A, satisfies<is_table_alias, T> = true>
117-
static std::string as_qualifier(const basic_table&) {
117+
static std::string as_qualifier(const table_identifier&) {
118118
return alias_extractor::extract();
119119
}
120120
};
@@ -163,7 +163,13 @@ namespace sqlite_orm {
163163
return {};
164164
}
165165

166-
template<auto t>
166+
template<orm_table_reference auto t>
167+
[[nodiscard]] consteval auto for_() const {
168+
using T = auto_decay_table_ref_t<t>;
169+
return recordset_alias<T, A, X...>{};
170+
}
171+
172+
template<orm_recordset_alias auto t>
167173
[[nodiscard]] consteval auto for_() const {
168174
using T = std::remove_const_t<decltype(t)>;
169175
return recordset_alias<T, A, X...>{};

dev/alias_traits.h

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
#pragma once
22

33
#ifndef SQLITE_ORM_IMPORT_STD_MODULE
4-
#include <type_traits> // std::is_base_of, std::is_same
5-
#ifdef SQLITE_ORM_WITH_CPP20_ALIASES
4+
#include <type_traits> // std::is_base_of, std::is_same, std::remove_const
5+
#ifdef SQLITE_ORM_CPP20_CONCEPTS_SUPPORTED
66
#include <concepts>
77
#endif
88
#endif
99

1010
#include "functional/cxx_type_traits_polyfill.h"
1111
#include "type_traits.h"
12-
#include "table_reference.h"
1312

1413
SQLITE_ORM_EXPORT namespace sqlite_orm {
1514

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

2120
namespace sqlite_orm {
2221
namespace internal {
22+
template<class O>
23+
struct table_reference;
24+
25+
template<class RecordSet>
26+
struct decay_table_ref : std::remove_const<RecordSet> {};
27+
template<class O>
28+
struct decay_table_ref<table_reference<O>> : polyfill::type_identity<O> {};
29+
template<class O>
30+
struct decay_table_ref<const table_reference<O>> : polyfill::type_identity<O> {};
31+
32+
template<class RecordSet>
33+
using decay_table_ref_t = typename decay_table_ref<RecordSet>::type;
34+
#ifdef SQLITE_ORM_WITH_CPP20_ALIASES
35+
template<auto recordset>
36+
using auto_decay_table_ref_t = typename decay_table_ref<decltype(recordset)>::type;
37+
#endif
2338

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

54+
template<class O>
55+
inline constexpr bool is_table_reference_v =
56+
polyfill::is_specialization_of_v<std::remove_const_t<O>, table_reference>;
57+
58+
template<class R>
59+
struct is_table_reference : polyfill::bool_constant<is_table_reference_v<R>> {};
60+
3961
/** @short Alias of any type of record set, see `orm_recordset_alias`.
4062
*/
4163
template<class A>
@@ -68,11 +90,20 @@ namespace sqlite_orm {
6890

6991
template<class A>
7092
using is_cte_moniker = polyfill::bool_constant<is_cte_moniker_v<A>>;
93+
94+
/** @short Referring to a recordset.
95+
*/
96+
template<class T>
97+
inline constexpr bool is_referring_to_recordset_v =
98+
polyfill::disjunction_v<is_table_reference<T>, is_recordset_alias<T>>;
99+
100+
template<class T>
101+
using is_referring_to_recordset = polyfill::bool_constant<is_referring_to_recordset_v<T>>;
71102
}
72103
}
73104

74105
SQLITE_ORM_EXPORT namespace sqlite_orm {
75-
#ifdef SQLITE_ORM_WITH_CPP20_ALIASES
106+
#ifdef SQLITE_ORM_CPP20_CONCEPTS_SUPPORTED
76107
template<class A>
77108
concept orm_alias = std::derived_from<A, alias_tag>;
78109

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

119+
/** @short Specifies that a type is a reference of a concrete table, especially of a derived class.
120+
*
121+
* A concrete table reference has the following traits:
122+
* - specialization of `table_reference`, whose `type` typename references a mapped object.
123+
*/
124+
template<class O>
125+
concept orm_table_reference = polyfill::is_specialization_of_v<std::remove_const_t<O>, internal::table_reference>;
126+
88127
/** @short Specifies that a type is an alias of any type of record set.
89128
*
90129
* A record set alias has the following traits:

dev/ast/cross_join.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#include "../functional/cxx_type_traits_polyfill.h"
2+
3+
namespace sqlite_orm {
4+
namespace internal {
5+
6+
/**
7+
* CROSS JOIN holder.
8+
* T is joined type which represents any mapped table.
9+
*/
10+
template<class T>
11+
struct cross_join_t {
12+
using type = T;
13+
};
14+
}
15+
}
16+
17+
SQLITE_ORM_EXPORT namespace sqlite_orm {
18+
19+
/**
20+
* CROSS JOIN function. Usage:
21+
* `cross_join<User>();`
22+
*/
23+
template<class T>
24+
internal::cross_join_t<T> cross_join() {
25+
return {};
26+
}
27+
}

dev/ast/into.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
#include "../functional/cxx_type_traits_polyfill.h"
4+
#include "../table_reference.h"
45

56
namespace sqlite_orm {
67
namespace internal {
@@ -20,4 +21,11 @@ SQLITE_ORM_EXPORT namespace sqlite_orm {
2021
internal::into_t<T> into() {
2122
return {};
2223
}
24+
25+
#ifdef SQLITE_ORM_WITH_CPP20_ALIASES
26+
template<orm_table_reference auto table>
27+
auto into() {
28+
return into<internal::auto_decay_table_ref_t<table>>();
29+
}
30+
#endif
2331
}

dev/ast/match.h

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,51 @@
11
#pragma once
22

33
#ifndef SQLITE_ORM_IMPORT_STD_MODULE
4-
#include <utility>
4+
#include <utility> // std::move
55
#endif
66

7-
namespace sqlite_orm {
8-
namespace internal {
7+
#include "../type_traits.h"
98

10-
template<class T, class X>
11-
struct match_t {
12-
using mapped_type = T;
13-
using argument_type = X;
9+
namespace sqlite_orm::internal {
10+
template<class T, class X>
11+
struct match_with_table_t {
12+
using mapped_type = T;
13+
using argument_type = X;
1414

15-
argument_type argument;
16-
};
17-
}
15+
argument_type argument;
16+
};
17+
18+
/*
19+
* Alternative equality comparison where the left side is always a field.
20+
*/
21+
template<class Field, class X>
22+
struct match_t {
23+
using field_type = Field;
24+
using argument_type = X;
25+
26+
field_type field;
27+
argument_type argument;
28+
};
1829
}
1930

2031
SQLITE_ORM_EXPORT namespace sqlite_orm {
32+
/**
33+
* [Deprecation notice] This expression factory function is deprecated and will be removed in v1.11.
34+
*/
2135
template<class T, class X>
22-
internal::match_t<T, X> match(X argument) {
36+
[[deprecated(
37+
"Use the `match` function accepting the hidden FTS5 'any' field or a field of your FTS table instead")]]
38+
constexpr internal::match_with_table_t<T, X> match(X argument) {
2339
return {std::move(argument)};
2440
}
41+
42+
template<class CP, class X>
43+
constexpr internal::match_t<CP, X> match(CP field, X argument) {
44+
return {std::move(field), std::move(argument)};
45+
}
46+
47+
template<class O, class F, class X>
48+
constexpr internal::match_t<F O::*, X> match(F O::* field, X argument) {
49+
return {field, std::move(argument)};
50+
}
2551
}

dev/ast/rank.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ namespace sqlite_orm {
77
}
88

99
SQLITE_ORM_EXPORT namespace sqlite_orm {
10+
/**
11+
* [Deprecation notice] This expression factory function is deprecated and will be removed in v1.11.
12+
*/
13+
[[deprecated("Use the hidden FTS5 rank column instead")]]
1014
inline internal::rank_t rank() {
1115
return {};
1216
}

dev/ast/set.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ namespace sqlite_orm {
5151
template<class L, class R>
5252
void push_back(assign_t<L, R> assign) {
5353
auto newContext = this->context;
54-
newContext.skip_table_name = true;
54+
newContext.omit_table_name = true;
5555
// note: we are only interested in the table name on the left-hand side of the assignment operator expression
5656
iterate_ast(assign.lhs, this->collector);
5757
std::stringstream ss;
@@ -108,7 +108,6 @@ SQLITE_ORM_EXPORT namespace sqlite_orm {
108108
*/
109109
template<class S>
110110
internal::dynamic_set_t<internal::serializer_context<typename S::db_objects_type>> dynamic_set(const S& storage) {
111-
internal::serializer_context_builder<S> builder(storage);
112-
return builder();
111+
return {obtain_db_objects(storage)};
113112
}
114113
}

dev/ast_iterator.h

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ namespace sqlite_orm {
7272
ast_iterator<T> iterator;
7373

7474
// possibly invoke lambda with node itself
75-
if constexpr (polyfill::is_invocable<L, polyfill::bool_constant<true>, const T&>::value) {
76-
lambda(polyfill::bool_constant<true>{}, t);
75+
if constexpr (polyfill::is_invocable<L, std::true_type, const T&>::value) {
76+
lambda(std::true_type{}, t);
7777
}
7878

7979
iterator(t, lambda);
@@ -103,8 +103,18 @@ namespace sqlite_orm {
103103
};
104104

105105
template<class T, class X>
106-
struct ast_iterator<match_t<T, X>, void> {
107-
using node_type = match_t<T, X>;
106+
struct ast_iterator<match_with_table_t<T, X>, void> {
107+
using node_type = match_with_table_t<T, X>;
108+
109+
template<class L>
110+
SQLITE_ORM_STATIC_CALLOP void operator()(const node_type& node, L& lambda) SQLITE_ORM_OR_CONST_CALLOP {
111+
iterate_ast(node.argument, lambda);
112+
}
113+
};
114+
115+
template<class Field, class X>
116+
struct ast_iterator<match_t<Field, X>, void> {
117+
using node_type = match_t<Field, X>;
108118

109119
template<class L>
110120
SQLITE_ORM_STATIC_CALLOP void operator()(const node_type& node, L& lambda) SQLITE_ORM_OR_CONST_CALLOP {
@@ -158,6 +168,27 @@ namespace sqlite_orm {
158168
}
159169
};
160170

171+
template<class T>
172+
struct ast_iterator<T, match_if<is_table_valued_expression, T>> {
173+
using node_type = T;
174+
175+
template<class L>
176+
SQLITE_ORM_STATIC_CALLOP void operator()(const node_type& expression,
177+
L& lambda) SQLITE_ORM_OR_CONST_CALLOP {
178+
iterate_ast(expression.table_values, lambda);
179+
}
180+
};
181+
182+
template<class T>
183+
struct ast_iterator<T, match_if<is_from2, T>> {
184+
using node_type = T;
185+
186+
template<class L>
187+
SQLITE_ORM_STATIC_CALLOP void operator()(const node_type& from, L& lambda) SQLITE_ORM_OR_CONST_CALLOP {
188+
iterate_ast(from.table_expressions, lambda);
189+
}
190+
};
191+
161192
template<class C>
162193
struct ast_iterator<where_t<C>, void> {
163194
using node_type = where_t<C>;

0 commit comments

Comments
 (0)