mirror of
https://github.com/getml/sqlgen.git
synced 2026-01-06 01:19:58 -06:00
Implement insert_or_replace (#45)
Co-authored-by: Dr. Patrick Urbanke <patrick@getml.com>
This commit is contained in:
@@ -68,6 +68,58 @@ sqlgen::sqlite::connect("database.db")
|
||||
.value();
|
||||
```
|
||||
|
||||
### With Replacement
|
||||
|
||||
Replace existing rows:
|
||||
|
||||
```cpp
|
||||
const auto people1 = std::vector<Person>({
|
||||
Person{.id = 0, .first_name = "Homer", .last_name = "Simpson", .age = 45},
|
||||
Person{.id = 1, .first_name = "Bart", .last_name = "Simpson", .age = 10}
|
||||
});
|
||||
|
||||
const auto people2 = std::vector<Person>({
|
||||
Person{.id = 1, .first_name = "Bartholomew", .last_name = "Simpson", .age = 10}
|
||||
});
|
||||
|
||||
using namespace sqlgen;
|
||||
|
||||
const auto result = sqlite::connect()
|
||||
.and_then(create_table<Person> | if_not_exists)
|
||||
.and_then(insert(std::ref(people1)))
|
||||
.and_then(insert_or_replace(std::ref(people2)))
|
||||
.value();
|
||||
```
|
||||
|
||||
This generates the following SQL:
|
||||
|
||||
```sql
|
||||
CREATE TABLE IF NOT EXISTS "Person" (
|
||||
"id" INTEGER PRIMARY KEY,
|
||||
"first_name" TEXT NOT NULL,
|
||||
"last_name" TEXT NOT NULL,
|
||||
"age" INTEGER NOT NULL
|
||||
);
|
||||
INSERT INTO "Person" ("id", "first_name", "last_name", "age") VALUES (?, ?, ?, ?);
|
||||
INSERT INTO "Person" ("id", "first_name", "last_name", "age") VALUES (?, ?, ?, ?)
|
||||
ON CONFLICT (id) DO UPDATE SET
|
||||
id=excluded.id,
|
||||
first_name=excluded.first_name,
|
||||
last_name=excluded.last_name,
|
||||
age=excluded.age;
|
||||
```
|
||||
|
||||
The SQL generated by the PostgreSQL backend for `insert_or_replace(...)` is similar. The MySQL backend generates `ON DUPLICATE KEY UPDATE` instead:
|
||||
```sql
|
||||
...
|
||||
INSERT INTO `Person` (`id`, `first_name`, `last_name`, `age`) VALUES (?, ?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
id=VALUES(id),
|
||||
first_name=VALUES(first_name),
|
||||
last_name=VALUES(last_name),
|
||||
age=VALUES(age);
|
||||
```
|
||||
|
||||
## Example: Full Transaction Usage
|
||||
|
||||
Here's a complete example showing how to use `insert` within a transaction:
|
||||
@@ -195,5 +247,4 @@ While both `insert` and `write` can be used to add data to a database, they serv
|
||||
4. Takes a connection and a reference wrapper to a container
|
||||
- Unlike `write`, `insert` does not create tables automatically - you must create tables separately using `create_table`
|
||||
- The insert operation is atomic within a transaction
|
||||
- When using reference wrappers (`std::ref`), the data is not copied, which can be more efficient for large datasets
|
||||
|
||||
- When using reference wrappers (`std::ref`), the data is not copied, which can be more efficient for large datasets
|
||||
Reference in New Issue
Block a user