Skip to content

Commit 17bebfc

Browse files
Pierre-Luc GagnéCopilot
andcommitted
refactor: replace env vars in example with hardcoded constants
basic_query.cpp now uses named constants (k_host, k_port, k_database, k_user, k_password) at the top of the file instead of reading five environment variables at runtime. The config_from_env() helper and its early-exit error path are removed. Users adjust the constants directly before building. Also commit the in-progress sql.hpp change (on_duplicate_key_update now returns insert_into_upsert_builder<T> with build_sql() instead of a raw std::string) and update the corresponding unit test to call .build_sql(), keeping it consistent with the rest of the builder API. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent c3b24a8 commit 17bebfc

3 files changed

Lines changed: 45 additions & 56 deletions

File tree

examples/basic_query.cpp

Lines changed: 21 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,26 @@
1212
// cmake --preset release && cmake --build build -j$(nproc)
1313
// ./build/bin/examples/example_basic_query
1414
//
15-
// Set these environment variables to point at a real MySQL instance:
16-
// DS_MYSQL_TEST_HOST (e.g. 127.0.0.1)
17-
// DS_MYSQL_TEST_PORT (e.g. 3307)
18-
// DS_MYSQL_TEST_DATABASE (e.g. ds_mysql_example)
19-
// DS_MYSQL_TEST_USER
20-
// DS_MYSQL_TEST_PASSWORD
21-
22-
#include <cstdlib>
23-
#include <iostream>
15+
// Edit the connection constants below to match your MySQL instance.
16+
2417
#include <optional>
2518
#include <print>
2619
#include <string>
2720

2821
#include "ds_mysql.hpp"
2922

23+
// ===================================================================
24+
// Connection configuration — adjust to match your MySQL instance.
25+
// ===================================================================
26+
27+
namespace {
28+
constexpr auto k_host = "127.0.0.1";
29+
constexpr auto k_database = "ds_mysql_example";
30+
constexpr auto k_user = "root";
31+
constexpr auto k_password = "";
32+
constexpr unsigned int k_port = 3306;
33+
}
34+
3035
// ===================================================================
3136
// Define a typed table struct.
3237
//
@@ -62,60 +67,24 @@ struct product {
6267
created_at created_at_;
6368
};
6469

65-
// ===================================================================
66-
// Read connection config from environment variables.
67-
// ===================================================================
68-
69-
[[nodiscard]] std::optional<ds_mysql::mysql_config> config_from_env() {
70-
auto get = [](char const* name, char const* fallback = "") -> std::string {
71-
char const* v = std::getenv(name);
72-
return v ? v : fallback;
73-
};
74-
75-
const std::string host = get("DS_MYSQL_TEST_HOST");
76-
const std::string database = get("DS_MYSQL_TEST_DATABASE", "ds_mysql_example");
77-
const std::string user = get("DS_MYSQL_TEST_USER");
78-
const std::string password = get("DS_MYSQL_TEST_PASSWORD");
79-
80-
if (host.empty() || user.empty()) {
81-
return std::nullopt;
82-
}
83-
84-
const unsigned int port = [&] {
85-
char const* p = std::getenv("DS_MYSQL_TEST_PORT");
86-
return p ? static_cast<unsigned int>(std::stoul(p))
87-
: ds_mysql::default_mysql_port.to_unsigned_int();
88-
}();
89-
90-
return ds_mysql::mysql_config{
91-
ds_mysql::host_name{host},
92-
ds_mysql::database_name{database},
93-
ds_mysql::auth_credentials{ds_mysql::user_name{user}, ds_mysql::user_password{password}},
94-
ds_mysql::port_number{port},
95-
};
96-
}
97-
9870
// ===================================================================
9971
// Main
10072
// ===================================================================
10173

10274
int main() {
103-
const auto config = config_from_env();
104-
if (!config) {
105-
std::println(stderr,
106-
"Set DS_MYSQL_TEST_HOST, DS_MYSQL_TEST_USER, DS_MYSQL_TEST_PASSWORD "
107-
"to run this example.");
108-
return 1;
109-
}
110-
11175
// --- Connect ---
112-
auto db_result = ds_mysql::mysql_database::connect(*config);
76+
auto db_result = ds_mysql::mysql_database::connect(ds_mysql::mysql_config{
77+
ds_mysql::host_name{k_host},
78+
ds_mysql::database_name{k_database},
79+
ds_mysql::auth_credentials{ds_mysql::user_name{k_user}, ds_mysql::user_password{k_password}},
80+
ds_mysql::port_number{k_port},
81+
});
11382
if (!db_result) {
11483
std::println(stderr, "Connection failed: {}", db_result.error());
11584
return 1;
11685
}
11786
auto& db = *db_result;
118-
std::println("Connected to {}:{}", config->host().to_string(), config->port().to_unsigned_int());
87+
std::println("Connected to {}:{}", k_host, k_port);
11988

12089
// --- Create table ---
12190
if (auto r = db.execute(ds_mysql::create_table<product>().if_not_exists()); !r) {

lib/include/ds_mysql/sql.hpp

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1817,6 +1817,27 @@ class describe_builder {
18171817
// ---------------------------------------------------------------
18181818
// insert_into_values_builder / insert_into_builder
18191819
// ---------------------------------------------------------------
1820+
template <typename T>
1821+
class insert_into_upsert_builder {
1822+
public:
1823+
insert_into_upsert_builder(std::string insert_sql, std::string update_clause)
1824+
: insert_sql_(std::move(insert_sql)), update_clause_(std::move(update_clause)) {
1825+
}
1826+
1827+
[[nodiscard]] std::string build_sql() const {
1828+
std::string sql;
1829+
sql.reserve(insert_sql_.size() + 26 + update_clause_.size());
1830+
sql += insert_sql_;
1831+
sql += " ON DUPLICATE KEY UPDATE ";
1832+
sql += update_clause_;
1833+
return sql;
1834+
}
1835+
1836+
private:
1837+
std::string insert_sql_;
1838+
std::string update_clause_;
1839+
};
1840+
18201841
template <typename T>
18211842
class insert_into_values_builder {
18221843
public:
@@ -1828,9 +1849,8 @@ class insert_into_values_builder {
18281849
// Each argument must be a FieldOf<T> column_field instance carrying the new value.
18291850
template <FieldOf<T>... Cols>
18301851
requires(sizeof...(Cols) > 0)
1831-
[[nodiscard]] std::string on_duplicate_key_update(Cols const&... assignments) const {
1852+
[[nodiscard]] insert_into_upsert_builder<T> on_duplicate_key_update(Cols const&... assignments) const {
18321853
std::ostringstream ss;
1833-
ss << build_sql() << " ON DUPLICATE KEY UPDATE ";
18341854
bool first = true;
18351855
(
18361856
[&](auto const& field) {
@@ -1842,7 +1862,7 @@ class insert_into_values_builder {
18421862
first = false;
18431863
}(assignments),
18441864
...);
1845-
return ss.str();
1865+
return insert_into_upsert_builder<T>{build_sql(), ss.str()};
18461866
}
18471867

18481868
[[nodiscard]] std::string build_sql() const {

tests/unit/test_dml.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ suite<"DML"> dml_suite = [] {
322322
row.ticker_ = "AAPL";
323323
row.instrument_ = "Stock";
324324
auto const sql =
325-
insert_into<asset>().values(row).on_duplicate_key_update(asset::ticker{"AAPL"}, asset::instrument{"Stock"});
325+
insert_into<asset>().values(row).on_duplicate_key_update(asset::ticker{"AAPL"}, asset::instrument{"Stock"}).build_sql();
326326
expect(sql ==
327327
"INSERT INTO asset (id, exchange_id, ticker, instrument, name, sector, currency, created_date, "
328328
"last_updated_date) "

0 commit comments

Comments
 (0)