|
| 1 | +∂# `sqlgen::duckdb` |
| 2 | + |
| 3 | +The `sqlgen::duckdb` module provides a type-safe and efficient interface for interacting with DuckDB databases. It implements the core database operations through a connection-based API with support for prepared statements, transactions, and efficient data iteration. |
| 4 | + |
| 5 | +## Usage |
| 6 | + |
| 7 | +### Basic Connection |
| 8 | + |
| 9 | +Create a connection to a DuckDB database: |
| 10 | + |
| 11 | +```cpp |
| 12 | +// Connect to an in-memory database |
| 13 | +const auto conn = sqlgen::duckdb::connect(); |
| 14 | + |
| 15 | +// Connect to a file-based database |
| 16 | +const auto conn = sqlgen::duckdb::connect("database.db"); |
| 17 | +``` |
| 18 | + |
| 19 | +The type of `conn` is `sqlgen::Result<sqlgen::Ref<sqlgen::duckdb::Connection>>`, which is useful for error handling: |
| 20 | + |
| 21 | +```cpp |
| 22 | +// Handle connection errors |
| 23 | +const auto conn = sqlgen::duckdb::connect("database.db"); |
| 24 | +if (!conn) { |
| 25 | + // Handle error... |
| 26 | + return; |
| 27 | +} |
| 28 | + |
| 29 | +using namespace sqlgen; |
| 30 | +using namespace sqlgen::literals; |
| 31 | + |
| 32 | +const auto query = sqlgen::read<std::vector<Person>> | |
| 33 | + where("age"_c < 18 and "first_name"_c != "Hugo"); |
| 34 | + |
| 35 | +// Use the connection |
| 36 | +const auto minors = query(conn); |
| 37 | +``` |
| 38 | +
|
| 39 | +### Basic Operations |
| 40 | +
|
| 41 | +Write data to the database: |
| 42 | +
|
| 43 | +```cpp |
| 44 | +struct Person { |
| 45 | + sqlgen::PrimaryKey<uint32_t> id; |
| 46 | + std::string first_name; |
| 47 | + std::string last_name; |
| 48 | + int age; |
| 49 | +}; |
| 50 | +
|
| 51 | +const auto people = std::vector<Person>{ |
| 52 | + Person{.id = 0, .first_name = "Homer", .last_name = "Simpson", .age = 45}, |
| 53 | + Person{.id = 1, .first_name = "Bart", .last_name = "Simpson", .age = 10}, |
| 54 | + Person{.id = 2, .first_name = "Lisa", .last_name = "Simpson", .age = 8} |
| 55 | +}; |
| 56 | +
|
| 57 | +// Write data to database |
| 58 | +const auto result = sqlgen::write(conn, people); |
| 59 | +``` |
| 60 | + |
| 61 | +Read data with filtering and ordering: |
| 62 | + |
| 63 | +```cpp |
| 64 | +using namespace sqlgen; |
| 65 | +using namespace sqlgen::literals; |
| 66 | + |
| 67 | +// Read all people ordered by age |
| 68 | +const auto all_people = sqlgen::read<std::vector<Person>> | |
| 69 | + order_by("age"_c); |
| 70 | + |
| 71 | +// Read minors only |
| 72 | +const auto minors = sqlgen::read<std::vector<Person>> | |
| 73 | + where("age"_c < 18) | |
| 74 | + order_by("age"_c); |
| 75 | + |
| 76 | +// Use the queries |
| 77 | +const auto result1 = all_people(conn); |
| 78 | +const auto result2 = minors(conn); |
| 79 | +``` |
| 80 | +
|
| 81 | +### Transactions |
| 82 | +
|
| 83 | +Perform operations within transactions: |
| 84 | +
|
| 85 | +```cpp |
| 86 | +using namespace sqlgen; |
| 87 | +using namespace sqlgen::literals; |
| 88 | +
|
| 89 | +// Delete a person and update another in a transaction |
| 90 | +const auto delete_hugo = delete_from<Person> | |
| 91 | + where("first_name"_c == "Hugo"); |
| 92 | +
|
| 93 | +const auto update_homer = update<Person>("age"_c.set(46)) | |
| 94 | + where("first_name"_c == "Homer"); |
| 95 | +
|
| 96 | +const auto result = begin_transaction(conn) |
| 97 | + .and_then(delete_hugo) |
| 98 | + .and_then(update_homer) |
| 99 | + .and_then(commit) |
| 100 | + .value(); |
| 101 | +``` |
| 102 | + |
| 103 | +### Update Operations |
| 104 | + |
| 105 | +Update data in a table: |
| 106 | + |
| 107 | +```cpp |
| 108 | +using namespace sqlgen; |
| 109 | +using namespace sqlgen::literals; |
| 110 | + |
| 111 | +// Update multiple columns |
| 112 | +const auto query = update<Person>("first_name"_c.set("last_name"_c), "age"_c.set(100)) | |
| 113 | + where("first_name"_c == "Hugo"); |
| 114 | + |
| 115 | +query(conn).value(); |
| 116 | +``` |
| 117 | +
|
| 118 | +## Notes |
| 119 | +
|
| 120 | +- The module provides a type-safe interface for DuckDB operations |
| 121 | +- All operations return `sqlgen::Result<T>` for error handling |
| 122 | +- Prepared statements are used for efficient query execution |
| 123 | +- The iterator interface supports batch processing of results |
| 124 | +- SQL generation adapts to DuckDB's dialect |
| 125 | +- The module supports: |
| 126 | + - In-memory and file-based databases |
| 127 | + - Transactions (begin, commit, rollback) |
| 128 | + - Efficient batch operations |
| 129 | + - Type-safe SQL generation |
| 130 | + - Error handling through `Result<T>` |
| 131 | + - Resource management through `Ref<T>` |
| 132 | + - Auto-incrementing primary keys |
| 133 | + - Various data types including VARCHAR, TIMESTAMP, DATE |
| 134 | + - Complex queries with WHERE clauses, ORDER BY, LIMIT, JOINs |
| 135 | + - LIKE and pattern matching operations |
| 136 | + - Mathematical operations and string functions |
| 137 | + - JSON data types |
| 138 | + - Foreign keys and referential integrity |
| 139 | + - Unique constraints |
| 140 | + - Views and materialized views |
| 141 | + - Indexes |
| 142 | +``` |
0 commit comments