Skip to content

Commit 1842de0

Browse files
committed
Add documentation for names
Also fix instances of SQLPP_ALIAS_PROVIDER.
1 parent 50921fc commit 1842de0

6 files changed

Lines changed: 117 additions & 28 deletions

File tree

docs/connection_pool.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
# Connection pools
44

5-
sqlpp11 has support for connection pools which are centralized caches of database connections. When you need a database connection, you can fetch one from the connection pool, use the connection to make SQL
5+
sqlpp23 has support for connection pools which are centralized caches of database connections. When you need a database connection, you can fetch one from the connection pool, use the connection to make SQL
66
queries and when you no longer need the connection object, destroy it, usually by letting it go out of scope. When a connection object is destroyed, the actual connection to the database server is not closed,
77
but put in a cache instead and next time when you need a database connection object, you will be handed one that reuses a cached connection. If there are no connections is the cache, then a new connection
88
will be created, wrapped in a connection object and handed to you.

docs/functions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ select(sqlpp::value(
171171
The other use of the `value` function is to wrap a [sub select](/docs/sub_select.md) for use as a selected column.
172172

173173
```c++
174-
SQLPP_ALIAS_PROVIDER(cheese_cake); // Declared outside of function
174+
SQLPP_CREATE_NAME_TAG(cheese_cake); // Declared outside of function
175175
// ...
176176
for (const auto& row :
177177
db(select(all_of(foo),

docs/names.md

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
[**\< Index**](/docs/README.md)
2+
3+
# Names
4+
5+
C++ and SQL use names to refer to entities. sqlpp23 automatically translates
6+
between names in C++ and names in SQL for columns and tables, e.g. when you
7+
select columns from a table, the resulting SQL expression contains the correct
8+
names and the members of result rows also refer to the correct names.
9+
10+
```c++
11+
for (const auto& row : db(select(
12+
foo.id, foo.name, foo.language).from(foo))) {
13+
// use row.id, row.name, row.language
14+
```
15+
16+
This works because tables and their columns are specifically created such that
17+
they "know" their SQL name.
18+
19+
The C++ name of entities does not matter, though.
20+
21+
```c++
22+
constexpr auto foo = TabFoo{}; // represented as tab_foo in SQL
23+
constexpr auto bar = foo; // also represented as tab_foo in SQL
24+
```
25+
26+
Also, other expressions, like function calls or arithmetic operations, for instance, do
27+
not have a name per se.
28+
29+
If you want to give something an SQL name or if you want to change its SQL name,
30+
you can either
31+
32+
- use the name of something that already has a name
33+
- prepare a name tag
34+
35+
and attach that name tag to a table, column, or expression via the `.as()`
36+
function.
37+
38+
## Name tags
39+
40+
Name tags are created using the `SQLPP_CREATE_NAME_TAG` macro. It has to be used
41+
outside of functions (typically in an unnamed namespace), e.g.
42+
43+
```
44+
// Outside of function scope.
45+
SQLPP_CREATE_NAME_TAG(my_fancy_name);
46+
SQLPP_CREATE_NAME_TAG(max_id);
47+
```
48+
49+
sqlpp23 also provides a couple of convenience name tags in the `sqlpp::alias`
50+
namespace. These are
51+
52+
```
53+
sqlpp::alias::a;
54+
// ...
55+
sqlpp::alias::z;
56+
sqlpp::alias::left;
57+
sqlpp::alias::right;
58+
```
59+
60+
## `.as()`
61+
62+
Tables, columns, and expressions in sqlpp23 expose the `.as()` member function.
63+
It takes name tag (see above) or an expression that already has a name as an
64+
argument and renames the in SQL using the `AS` operator.
65+
66+
```c++
67+
auto foo = TabFoo{}; // a table called tab_foo in SQL
68+
auto id = foo.id; // a column called id in SQL
69+
auto x = (foo.id + 17) * 4; // an sqlpp expression with no SQL name
70+
auto seven = 7; // a value with no SQL name
71+
72+
// re-naming a table, e.g. for a self-join
73+
auto left = foo.as(sqlpp::alias::left); // tab_foo AS left
74+
auto right = foo.as(sqlpp::alias::right); // tab_foo AS right
75+
76+
// re-naming a column
77+
id.as(sqlpp::alias::a); // tab_foo.id AS a
78+
left.id.as(my_fancy_name); // left.id AS my_fancy_name
79+
80+
// naming an sqlpp expression
81+
x.as(foo.id); // ((tab_foo.id + 17) * 4) AS id
82+
max(foo.id).as(max_id); // MAX(tab_foo.id) AS max_id
83+
84+
// naming a value
85+
sqlpp::value(seven).as(sqlpp::alias::s); // 7 AS s
86+
```
87+
88+
## C++26 reflection (experimental)
89+
90+
C++26 offers [reflection](https://wg21.link/P2996). One aspect of that is an improved
91+
meta-programming access to names.
92+
93+
When used with C++26 and reflection support, the library offers another overload of the
94+
`.as` function.
95+
96+
```c++
97+
// with reflection, you can use a string literal as template argument to name or
98+
// rename entities.
99+
foo.as<"left">(); // tab_foo AS left
100+
max(left.id).as<"max_id">(); // MAX(left.id) AS max_id
101+
```
102+
103+
**Experimental**
104+
As of this writing (2026-02), this is known to compile with g++-16.0.1 with `-freflection`.
105+
106+
[**\< Index**](/docs/README.md)

docs/select.md

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,7 @@ would be `foo.id`, `foo.name` and `foo.hasFun`.
101101
102102
Other expressions, like function calls or arithmetic operations, for instance, do
103103
not have a name per se. But you can give them a name using the
104-
`as(name_provider)` method. The easiest way is to use a named expression as
105-
`name_provider`, e.g.
104+
`as(name_provider)` method, see [names](/docs/names.md).
106105
107106
```C++
108107
const auto unnamed_expression = (foo.id + 17) * 4;
@@ -114,22 +113,6 @@ for (const auto& row : db(select(
114113
}
115114
```
116115

117-
Another option is to define an alias like this:
118-
119-
```C++
120-
// In namespace scope
121-
SQLPP_ALIAS_PROVIDER(total);
122-
123-
[...]
124-
125-
// In a function
126-
for (const auto& row : db(select(sum(id).as(total)).as(foo.id).from(tab).where(true))
127-
{
128-
std::cout << row.total << std::endl;
129-
}
130-
131-
```
132-
133116
Using aliases also comes in handy when you join tables and have several columns
134117
of the same name, e.g.
135118

@@ -141,7 +124,7 @@ This will result in compile error when accessing `row.id`. One of the columns
141124
needs an alias.
142125
143126
```C++
144-
SQLPP_ALIAS_PROVIDER(barId);
127+
SQLPP_CREATE_NAME_TAG(barId);
145128
146129
[...]
147130
@@ -162,7 +145,7 @@ select(all_of(foo)).from(foo).where(condition);
162145
`select` will not let you mix aggregates (see [`group_by`](#group-by) and
163146
[aggregate functions](/docs/aggregate_functions.md)) and non-aggregates, e.g.
164147
165-
````c++
148+
```c++
166149
// This will fail to compile as it mixes aggregate and non-aggregate values.
167150
db(select(
168151
foo.id, // non-aggregate
@@ -187,7 +170,7 @@ select(
187170
dynamic(maybe1, foo.textN), // dynamically selected, if maybe1 == true
188171
dynamic(maybe2, bar.id.as(barId)) // dynamically selected, if maybe2 == true
189172
).from(foo.cross_join(bar)).where(condition);
190-
````
173+
```
191174
192175
Dynamically selected columns are represented as `std::optional` in the result
193176
row. In case the condition (e.g. `maybe1`) is false:

docs/sub_select.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ As seen above, a sub select statement with single column and a single result row
2323
To use it a sub select as a column, you need to wrap in `sqlpp::value` and give the whole thing a name, e.g.
2424
2525
```c++
26-
SQLPP_ALIAS_PROVIDER(cheese_cake); // Declared outside of function
26+
SQLPP_CREATE_NAME_TAG(cheese_cake); // Declared outside of function
2727
// ...
2828
for (const auto& row :
2929
db(select(all_of(foo),
@@ -56,7 +56,7 @@ A select can be used as a pseudo table in another select. You just have to give
5656
it a name.
5757
5858
```c++
59-
SQLPP_ALIAS_PROVIDER(sub); // Declared outside of functions
59+
SQLPP_CREATE_NAME_TAG(sub); // Declared outside of functions
6060
// [...]
6161
6262
auto sub_select = select(all_of(foo)).from(foo).where(foo.id == 42).as(sub);

docs/tables.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,9 @@ useful for self-joins, for instance.
9191

9292
```C++
9393
// Outside of functions
94-
SQLPP_ALIAS_PROVIDER(left);
95-
SQLPP_ALIAS_PROVIDER(right);
96-
SQLPP_ALIAS_PROVIDER(r_id);
94+
SQLPP_CREATE_NAME_TAG(left);
95+
SQLPP_CREATE_NAME_TAG(right);
96+
SQLPP_CREATE_NAME_TAG(r_id);
9797
[...]
9898

9999
// Inside a function

0 commit comments

Comments
 (0)