VoltMod
C++23 framework for CS2 server plugins
Loading...
Searching...
No Matches
Connection.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <concepts>
4#include <cstdint>
5#include <string>
6#include <string_view>
7// On Windows the MariaDB connector pulls in winsock2.h, so this header must be seen before any
8// windows.h an SDK header reaches (see the PCH order in cmake/VoltModPlugin.cmake).
9#include <sqlpp23/mysql/mysql.h>
10#include <sqlpp23/postgresql/postgresql.h>
11#include <sqlpp23/sqlite3/sqlite3.h>
12#include <sqlpp23/sqlpp23.h>
13#include <type_traits>
14#include <variant>
15
16namespace VoltMod
17{
18
19using PostgresConnection = sqlpp::postgresql::connection;
20using MariaDbConnection = sqlpp::mysql::connection;
21using SqliteConnection = sqlpp::sqlite3::connection;
22
23/** A connection of whichever driver is configured; monostate while closed. */
24using AnyConnection = std::variant<std::monostate, PostgresConnection, MariaDbConnection, SqliteConnection>;
25
26/** Dialect tests for the `if constexpr` branches of a job body run against `auto& conn`. */
27template <class Conn>
28inline constexpr bool IsPostgres = std::same_as<std::remove_cvref_t<Conn>, PostgresConnection>;
29
30template <class Conn>
31inline constexpr bool IsMariaDb = std::same_as<std::remove_cvref_t<Conn>, MariaDbConnection>;
32
33template <class Conn>
34inline constexpr bool IsSqlite = std::same_as<std::remove_cvref_t<Conn>, SqliteConnection>;
35
36/** Insert one row and return its generated id. Postgres reads the `<table>_<key>_seq` sequence
37 * of a SERIAL column; the other drivers report it on the insert result. */
38template <class Conn, class Statement>
39int64_t Insert(Conn& conn, const Statement& insert, std::string_view table, std::string_view key = "id")
40{
41 if constexpr (IsPostgres<Conn>)
42 {
43 conn(insert);
44 return static_cast<int64_t>(conn.last_insert_id(std::string(table), std::string(key)));
45 }
46 else
47 {
48 return static_cast<int64_t>(conn(insert).last_insert_id);
49 }
50}
51
52/**
53 * Update by a natural key, inserting only when nothing matched: the portable upsert, since the
54 * three drivers disagree on `ON CONFLICT` / `ON DUPLICATE KEY`.
55 *
56 * Not atomic, so the key needs a UNIQUE constraint to turn a race between two servers into one
57 * failed job rather than a duplicate row. Relies on `Database` setting CLIENT_FOUND_ROWS, which
58 * makes MariaDB count matched rows instead of changed ones.
59 */
60template <class Conn, class Update, class Statement>
62{
63 if (conn(update).affected_rows == 0)
64 {
65 conn(insert);
66 }
67}
68
69} // namespace VoltMod
static std::string ReadFile(const std::filesystem::path &path)
Definition Loader.cpp:56
sqlpp::postgresql::connection PostgresConnection
int64_t Insert(Conn &conn, const Statement &insert, std::string_view table, std::string_view key="id")
void Upsert(Conn &conn, const Update &update, const Statement &insert)
constexpr bool IsPostgres
sqlpp::sqlite3::connection SqliteConnection
constexpr bool IsSqlite
std::variant< std::monostate, PostgresConnection, MariaDbConnection, SqliteConnection > AnyConnection
sqlpp::mysql::connection MariaDbConnection
constexpr bool IsMariaDb