mirror of
https://github.com/getml/sqlgen.git
synced 2026-01-03 16:09:47 -06:00
committed by
GitHub
parent
7b5c849e02
commit
1424d29c5d
@@ -6,6 +6,7 @@ Welcome to the sqlgen documentation. This guide provides detailed information ab
|
||||
|
||||
- [Defining Tables](defining_tables.md) - How to define tables using C++ structs
|
||||
- [sqlgen::col](col.md) - How to represent columns in queries
|
||||
- [sqlgen::literals](literals.md) - How to use column and table alias literals in queries
|
||||
- [sqlgen::Flatten](flatten.md) - How to "inherit" fields from other structs
|
||||
- [sqlgen::PrimaryKey](primary_key.md) - How to define primary keys in sqlgen
|
||||
- [sqlgen::Result](result.md) - How sqlgen handles errors and results
|
||||
@@ -24,8 +25,8 @@ Welcome to the sqlgen documentation. This guide provides detailed information ab
|
||||
- [sqlgen::drop](drop.md) - How to drop a table
|
||||
- [sqlgen::exec](exec.md) - How to execute raw SQL statements
|
||||
- [sqlgen::group_by and Aggregations](group_by_and_aggregations.md) - How generate GROUP BY queries and aggregate data
|
||||
- [sqlgen::inner_join, sqlgen::left_join, sqlgen::right_join, sqlgen::full_join](joins.md) - How to join different tables
|
||||
- [sqlgen::insert](insert.md) - How to insert data within transactions
|
||||
- [Joins](joins.md) - How to join different tables
|
||||
- [sqlgen::update](update.md) - How to update data in a table
|
||||
|
||||
## Other Operations
|
||||
|
||||
@@ -10,6 +10,7 @@ Reference a column using the string literal operator:
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
// Using string literal operator
|
||||
const auto age_col = "age"_c;
|
||||
@@ -26,6 +27,7 @@ Compare columns with values or other columns:
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
// Compare with value
|
||||
const auto query1 = read<std::vector<Person>> | where("age"_c > 18);
|
||||
@@ -55,6 +57,7 @@ Check for NULL or NOT NULL values:
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
// Find records where age is NULL
|
||||
const auto query1 = read<std::vector<Person>> |
|
||||
@@ -85,6 +88,7 @@ Use LIKE and NOT LIKE for pattern matching:
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
// Find names starting with 'H'
|
||||
const auto query1 = read<std::vector<Person>> |
|
||||
@@ -115,6 +119,7 @@ Specify column ordering in queries:
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
// Order by age ascending
|
||||
const auto query1 = read<std::vector<Person>> |
|
||||
@@ -154,6 +159,7 @@ Set column values in UPDATE statements:
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
// Update a single column
|
||||
const auto query1 = update<Person>("age"_c.set(46));
|
||||
@@ -192,4 +198,4 @@ WHERE "first_name" = 'Hugo';
|
||||
- All operations are composable and can be chained together
|
||||
- The class supports both value and column-to-column comparisons
|
||||
- String literals are automatically converted to the appropriate SQL type
|
||||
- The class is thread-safe and has no mutable state
|
||||
- The class is thread-safe and has no mutable state
|
||||
|
||||
@@ -105,6 +105,7 @@ Example of thread-safe usage with monadic style:
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
// Create pool
|
||||
const auto pool = make_connection_pool<postgres::Connection>(config, credentials);
|
||||
@@ -133,6 +134,7 @@ Sessions are managed through RAII (Resource Acquisition Is Initialization) and s
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
// Using monadic style for session management with exec
|
||||
session(pool)
|
||||
|
||||
@@ -37,6 +37,7 @@ Create an index only if it doesn't already exist:
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
const auto query = create_index<"person_ix", Person>("first_name"_c, "last_name"_c) | if_not_exists;
|
||||
|
||||
@@ -53,6 +54,7 @@ You can also use monadic error handling here:
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
const auto query = create_index<"person_ix", Person>("first_name"_c, "last_name"_c) | if_not_exists;
|
||||
|
||||
@@ -66,6 +68,7 @@ Create a unique index to enforce uniqueness constraints:
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
const auto query = create_unique_index<"person_ix", Person>("first_name"_c, "last_name"_c);
|
||||
|
||||
@@ -84,6 +87,7 @@ Create a partial index by adding a WHERE clause to filter which rows are include
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
const auto query = create_index<"test_table_ix", TestTable>("field1"_c, "field2"_c) |
|
||||
if_not_exists |
|
||||
@@ -104,6 +108,7 @@ The WHERE clause can be combined with other modifiers like `if_not_exists` and w
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
const auto query = create_index<"person_ix", Person>("first_name"_c, "last_name"_c) | if_not_exists;
|
||||
|
||||
@@ -120,7 +125,7 @@ This generates the following SQL:
|
||||
CREATE INDEX IF NOT EXISTS "person_ix" ON "Person" ("first_name", "last_name");
|
||||
```
|
||||
|
||||
It is strongly recommended that you use `using namespace sqlgen`. However,
|
||||
It is strongly recommended that you use `using namespace sqlgen` and `using namespace sqlgen::literals`. However,
|
||||
if you do not want to do that, you can rewrite the example above as follows:
|
||||
|
||||
```cpp
|
||||
@@ -134,7 +139,7 @@ const auto result = query(conn);
|
||||
|
||||
- The `if_not_exists` clause is optional - if omitted, the query will fail if the index already exists
|
||||
- The `Result<Ref<Connection>>` type provides error handling; use `.value()` to extract the result (will throw an exception if there's an error) or handle errors as needed or refer to the documentation on `sqlgen::Result<...>` for other forms of error handling.
|
||||
- `"..."_c` refers to the name of the column. If such a field does not exist on the struct (e.g., `Person`), the code will fail to compile.
|
||||
- `"..."_c` refers to the name of the column. If such a field does not exist on the struct (e.g., `Person`), the code will fail to compile. It is defined in the namespace `sqlgen::literals`.
|
||||
- Index names must be unique within a database
|
||||
- You can create indexes on multiple columns by providing multiple column names
|
||||
- Use `create_unique_index` when you need to enforce uniqueness constraints on the indexed columns
|
||||
|
||||
@@ -37,6 +37,7 @@ Delete specific records using a `where` clause:
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
const auto query = delete_from<Person> |
|
||||
where("first_name"_c == "Hugo");
|
||||
@@ -52,12 +53,14 @@ WHERE "first_name" = 'Hugo';
|
||||
```
|
||||
|
||||
Note that `"..."_c` refers to the name of the column. If such a field does not
|
||||
exist on the struct `Person`, the code will fail to compile.
|
||||
exist on the struct `Person`, the code will fail to compile. `"..."_c` is
|
||||
defined in the namespace `sqlgen::literals`.
|
||||
|
||||
You can also use monadic error handling here:
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
const auto query = delete_from<Person> |
|
||||
where("first_name"_c == "Hugo");
|
||||
@@ -70,6 +73,7 @@ const auto result = sqlite::connect("database.db").and_then(query);
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
const auto query = delete_from<Person> |
|
||||
where("age"_c >= 18 and "last_name"_c == "Simpson");
|
||||
@@ -88,7 +92,7 @@ DELETE FROM "Person"
|
||||
WHERE ("age" >= 18) AND ("last_name" = 'Simpson');
|
||||
```
|
||||
|
||||
It is strongly recommended that you use `using namespace sqlgen`. However,
|
||||
It is strongly recommended that you use `using namespace sqlgen` and `using namespace sqlgen::literals`. However,
|
||||
if you do not want to do that, you can rewrite the example above as follows:
|
||||
|
||||
```cpp
|
||||
|
||||
@@ -10,6 +10,7 @@ Perform aggregations without grouping:
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
struct Children {
|
||||
int num_children;
|
||||
@@ -54,6 +55,7 @@ Group data and perform aggregations:
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
struct Children {
|
||||
std::string last_name;
|
||||
|
||||
@@ -19,6 +19,7 @@ Each join type can be used with either a table or a subquery, and can be aliased
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
struct Person {
|
||||
sqlgen::PrimaryKey<uint32_t> id;
|
||||
@@ -128,7 +129,9 @@ Where:
|
||||
|
||||
## Aliasing and Column References
|
||||
|
||||
When joining tables or subqueries, you must use aliases to disambiguate columns. Use the `_t1`, `_t2`, etc. suffixes to refer to columns from different tables or subqueries:
|
||||
When joining tables or subqueries, you must use aliases to disambiguate columns. Use the `_t1`, `_t2`, etc.
|
||||
suffixes to refer to columns from different tables or subqueries, which are defined in the
|
||||
namespace `sqlgen::literals`:
|
||||
|
||||
```cpp
|
||||
"id"_t1, "first_name"_t2, "age"_t3
|
||||
|
||||
127
docs/literals.md
Normal file
127
docs/literals.md
Normal file
@@ -0,0 +1,127 @@
|
||||
# `sqlgen::literals`
|
||||
|
||||
The `sqlgen::literals` namespace provides user-defined literal operators for referencing columns and table aliases in a type-safe, expressive, and concise way when building SQL queries with sqlgen. These literals are essential for writing readable and maintainable query expressions, especially when working with complex queries involving joins and table aliases.
|
||||
|
||||
## Usage
|
||||
|
||||
### Column Literals: `_c`
|
||||
|
||||
Reference a column by name using the `_c` literal:
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
// Reference the "age" column
|
||||
const auto age_col = "age"_c;
|
||||
|
||||
// Use in a query
|
||||
const auto query = sqlgen::read<std::vector<Person>> | where("age"_c < 18);
|
||||
```
|
||||
|
||||
This generates SQL like:
|
||||
|
||||
```sql
|
||||
SELECT "id", "first_name", "last_name", "age"
|
||||
FROM "Person"
|
||||
WHERE "age" < 18;
|
||||
```
|
||||
|
||||
If the column name does not exist in the struct, the code will fail to compile, ensuring type safety.
|
||||
|
||||
### Table Alias Literals: `_t1`, `_t2`, ..., `_t99`
|
||||
|
||||
When working with joins or subqueries, you often need to disambiguate columns by table alias. The `sqlgen::literals` namespace provides `_tN` suffixes for this purpose, where `N` ranges from 1 to 99:
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
// Reference the "id" column from table alias t1
|
||||
const auto id_t1 = "id"_t1;
|
||||
|
||||
// Reference the "first_name" column from table alias t2
|
||||
const auto first_name_t2 = "first_name"_t2;
|
||||
```
|
||||
|
||||
#### Example: Joins with Aliases
|
||||
|
||||
```cpp
|
||||
const auto get_people =
|
||||
select_from<Person, "t1">(
|
||||
"last_name"_t1 | as<"last_name">,
|
||||
"first_name"_t1 | as<"first_name_parent">,
|
||||
"first_name"_t3 | as<"first_name_child">,
|
||||
("age"_t1 - "age"_t3) | as<"parent_age_at_birth">
|
||||
)
|
||||
| inner_join<Relationship, "t2">("id"_t1 == "parent_id"_t2)
|
||||
| left_join<Person, "t3">("id"_t3 == "child_id"_t2)
|
||||
| order_by("id"_t1, "id"_t3)
|
||||
| to<std::vector<ParentAndChild>>;
|
||||
```
|
||||
|
||||
This produces SQL like:
|
||||
|
||||
```sql
|
||||
SELECT t1."last_name" AS "last_name", t1."first_name" AS "first_name_parent", t3."first_name" AS "first_name_child", (t1."age") - (t3."age") AS "parent_age_at_birth"
|
||||
FROM "Person" t1
|
||||
INNER JOIN "Relationship" t2 ON t1."id" = t2."parent_id"
|
||||
LEFT JOIN "Person" t3 ON t3."id" = t2."child_id"
|
||||
ORDER BY t1."id", t3."id"
|
||||
```
|
||||
|
||||
### Supported Suffixes
|
||||
|
||||
- `_c` — Reference a column by name (e.g., `"age"_c`)
|
||||
- `_t1`, `_t2`, ..., `_t99` — Reference a column by name and table alias (e.g., `"id"_t2`)
|
||||
|
||||
All these literals are defined in the `sqlgen::literals` namespace. It is strongly recommended to use:
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen::literals;
|
||||
```
|
||||
|
||||
in your query files for convenience.
|
||||
|
||||
## Type Safety
|
||||
|
||||
- Column names are checked at compile time against the struct definition.
|
||||
- Table aliases are enforced by the literal suffix, preventing ambiguous references in joins.
|
||||
- If you use a column or alias that does not exist, the code will fail to compile.
|
||||
|
||||
## Advanced: Custom Aliases
|
||||
|
||||
If you need an alias outside the provided `_tN` range, you can use the `col` template directly:
|
||||
|
||||
```cpp
|
||||
const auto custom_col = col<"id", "custom_alias">;
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- The `_c` and `_tN` literals return `Col` objects, which support all standard SQL operations (comparison, ordering, etc.).
|
||||
- These literals are composable with all sqlgen query builder functions, such as `where`, `order_by`, `group_by`, and join conditions.
|
||||
- The use of these literals is required for type-safe, readable, and maintainable query construction in sqlgen.
|
||||
- All operations are thread-safe and have no mutable state.
|
||||
|
||||
## Example: Full Query Composition
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
const auto query = sqlgen::read<std::vector<Person>>
|
||||
| where("age"_c >= 18 and "last_name"_c == "Simpson")
|
||||
| order_by("first_name"_c.desc())
|
||||
| limit(10);
|
||||
```
|
||||
|
||||
This generates:
|
||||
|
||||
```sql
|
||||
SELECT "id", "first_name", "last_name", "age"
|
||||
FROM "Person"
|
||||
WHERE ("age" >= 18) AND ("last_name" = 'Simpson')
|
||||
ORDER BY "first_name" DESC
|
||||
LIMIT 10;
|
||||
```
|
||||
@@ -109,6 +109,7 @@ struct Person {
|
||||
std::vector<Person> get_people(const auto& conn,
|
||||
const sqlgen::AlphaNumeric& first_name) {
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
const auto query = sqlgen::read<std::vector<Person>> |
|
||||
where("first_name"_c == first_name);
|
||||
return query(conn).value();
|
||||
|
||||
@@ -33,6 +33,7 @@ if (!conn) {
|
||||
}
|
||||
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
const auto query = sqlgen::read<std::vector<Person>> |
|
||||
where("age"_c < 18 and "first_name"_c != "Hugo");
|
||||
|
||||
@@ -38,6 +38,7 @@ Filter results using a `where` clause:
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
const auto query = sqlgen::read<std::vector<Person>> |
|
||||
where("age"_c < 18 and "first_name"_c != "Hugo");
|
||||
@@ -56,12 +57,14 @@ WHERE
|
||||
```
|
||||
|
||||
Note that `"..."_c` refers to the name of the column. If such a field does not
|
||||
exists on the struct `Person`, the code will fail to compile.
|
||||
exists on the struct `Person`, the code will fail to compile. It is defined in
|
||||
the namespace `sqlgen::literals`.
|
||||
|
||||
You can also use monadic error handling here:
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
const auto query = sqlgen::read<std::vector<Person>> |
|
||||
where("age"_c < 18 and "first_name"_c != "Hugo");
|
||||
@@ -76,6 +79,7 @@ Sort and limit results:
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
const auto query = sqlgen::read<std::vector<Person>> |
|
||||
order_by("age"_c) |
|
||||
@@ -125,6 +129,7 @@ const auto adults = people_range | filter([](const sqlgen::Result<Person>& r) {
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
const auto query = sqlgen::read<std::vector<Person>> |
|
||||
where("age"_c >= 18) |
|
||||
@@ -147,7 +152,7 @@ ORDER BY
|
||||
LIMIT 10;
|
||||
```
|
||||
|
||||
It is strongly recommended that you use `using namespace sqlgen`. However,
|
||||
It is strongly recommended that you use `using namespace sqlgen` and `using namespace sqlgen::literals;`. However,
|
||||
if you do not want to do that, you can rewrite the example above as follows:
|
||||
|
||||
```cpp
|
||||
@@ -164,4 +169,4 @@ const auto adults = query(conn).value();
|
||||
- All query clauses (`where`, `order_by`, `limit`) are optional.
|
||||
- The `Result<ContainerType>` type provides error handling; use `.value()` to extract the result (will throw a exception if the results) or handle errors as needed. Refer to the
|
||||
- The `sqlgen::Range<T>` type allows for lazy iteration over results.
|
||||
- `"..."_c` refers to the name of the column.
|
||||
- `"..."_c` refers to the name of the column.
|
||||
|
||||
@@ -27,6 +27,7 @@ if (!conn) {
|
||||
}
|
||||
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
const auto query = sqlgen::read<std::vector<Person>> |
|
||||
where("age"_c < 18 and "first_name"_c != "Hugo");
|
||||
|
||||
@@ -10,6 +10,7 @@ Transpile any SQL operation to a dialect-specific SQL string:
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
// Define a query
|
||||
const auto query = sqlgen::read<std::vector<Person>> |
|
||||
@@ -44,6 +45,7 @@ const auto sqlite_sql = sqlite::to_sql(query);
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
// Basic select
|
||||
const auto select_query = sqlgen::read<std::vector<Person>>;
|
||||
@@ -81,6 +83,7 @@ before actually inserting the data.
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
// Define a table structure
|
||||
struct TestTable {
|
||||
@@ -111,6 +114,7 @@ CREATE TABLE IF NOT EXISTS "TestTable" (
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
const auto insert_query = Insert<TestTable>{};
|
||||
const auto sql = postgres::to_sql(insert_query);
|
||||
@@ -134,6 +138,7 @@ VALUES (?, ?, ?, ?);
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
const auto delete_query = delete_from<TestTable> |
|
||||
where("field2"_c > 0);
|
||||
|
||||
@@ -14,6 +14,7 @@ Here's a basic example of how to use transactions:
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
// Start a transaction and chain operations
|
||||
// Note that all of these operations return
|
||||
@@ -37,6 +38,7 @@ Example with error handling:
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
auto conn = sqlite::connect("database.db")
|
||||
.and_then(begin_transaction)
|
||||
|
||||
@@ -12,6 +12,7 @@ Update specific columns in a table:
|
||||
const auto conn = sqlgen::sqlite::connect("database.db");
|
||||
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
const auto query = update<Person>("age"_c.set(100), "first_name"_c.set("New Name"));
|
||||
|
||||
@@ -42,6 +43,7 @@ Update specific records using a `where` clause:
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
const auto query = update<Person>("age"_c.set(100)) |
|
||||
where("first_name"_c == "Hugo");
|
||||
@@ -58,12 +60,14 @@ WHERE "first_name" = 'Hugo';
|
||||
```
|
||||
|
||||
Note that `"..."_c` refers to the name of the column. If such a field does not
|
||||
exist on the struct `Person`, the code will fail to compile.
|
||||
exist on the struct `Person`, the code will fail to compile. It is defined
|
||||
in the namespace `sqlgen::literals`.
|
||||
|
||||
You can also use monadic error handling here:
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
const auto query = update<Person>("age"_c.set(100)) |
|
||||
where("first_name"_c == "Hugo");
|
||||
@@ -78,6 +82,7 @@ You can set a column's value to another column's value:
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
const auto query = update<Person>("first_name"_c.set("last_name"_c)) |
|
||||
where("age"_c > 18);
|
||||
@@ -97,6 +102,7 @@ WHERE "age" > 18;
|
||||
|
||||
```cpp
|
||||
using namespace sqlgen;
|
||||
using namespace sqlgen::literals;
|
||||
|
||||
const auto query = update<Person>(
|
||||
"first_name"_c.set("last_name"_c),
|
||||
@@ -120,7 +126,8 @@ SET
|
||||
WHERE "age" > 0;
|
||||
```
|
||||
|
||||
It is strongly recommended that you use `using namespace sqlgen`. However,
|
||||
It is strongly recommended that you use `using namespace sqlgen`
|
||||
and `using namespace sqlgen::literals`. However,
|
||||
if you do not want to do that, you can rewrite the example above as follows:
|
||||
|
||||
```cpp
|
||||
@@ -137,7 +144,7 @@ const auto result = query(conn);
|
||||
- You must specify at least one column to update
|
||||
- The `where` clause is optional - if omitted, all records will be updated
|
||||
- The `Result<Ref<Connection>>` type provides error handling; use `.value()` to extract the result (will throw an exception if there's an error) or handle errors as needed or refer to the documentation on `sqlgen::Result<...>` for other forms of error handling
|
||||
- `"..."_c` refers to the name of the column
|
||||
- `"..."_c` refers to the name of the column. It is defined in the namespace `sqlgen::literals`.
|
||||
- You can set columns to either literal values or other column values
|
||||
- The update operation is atomic - either all specified columns are updated or none are
|
||||
|
||||
|
||||
Reference in New Issue
Block a user