Skip to content

Connections & Pools

The database module manages MySQL connection pools through framework::database::manager. Connection pooling reuses database connections to reduce the overhead of establishing new connections.

Creating a Pool

A pool is a named group of persistent MySQL connections. Create one for each logical database your service uses.

cpp
auto& db = app.get_state()->of_database();

db.create_pool(
    "primary",              // Pool name
    "127.0.0.1",            // MySQL host
    3306,                   // MySQL port
    "${MYSQL_USER}",        // Username
    "${MYSQL_PASSWORD}",    // Password
    "my_database",          // Database name
    4,                      // Initial connections opened at startup
    32                      // Maximum connections the pool can grow to
);

Parameters:

ParameterDescription
nameLogical name to identify this pool (e.g., "primary", "analytics").
hostMySQL server hostname or IP.
portMySQL server port (default: 3306).
userAuthentication username.
passwordAuthentication password.
databaseDefault database to use.
initial_sizeNumber of connections to open immediately.
max_sizeMaximum number of connections. The pool grows on demand up to this limit.

Running Queries

run(cb, query) — Simple query

Retrieves a connection from the pool, executes the query, and returns the result.

cpp
auto* pool = db.get_pool("primary");

pool->run([](auto ec, const boost::mysql::results& results) {
    if (ec) {
        fmt::println("Query failed: {}", ec.what());
        return;
    }
    // Iterate over rows
    for (auto& row : results.rows()) {
        fmt::println("Column 0: {}", row.at(0));
    }
}, "SELECT * FROM users");

run(cb, query, params) — Parameterized query

Uses ? placeholders to safely bind values. This prevents SQL injection.

cpp
pool->run([](auto ec, auto results) {
    if (ec) return;
    // Process results
}, "SELECT * FROM users WHERE id = ?", {42});

Parameters:

ParameterDescription
cbCallback with (error_code, results). Called on the io_context thread.
querySQL query string with optional ? placeholders.
paramsstd::vector<boost::mysql::field> of values for placeholders.

Transactions

begin_transaction(cb) — Start a transaction

Gets a connection from the pool and begins a MySQL transaction.

cpp
pool->begin_transaction([](auto ec, auto tx) {
    if (ec) return;
    tx->run([](auto ec, auto results) { }, "INSERT INTO ...");
    tx->commit([](auto ec) { });
});

See Transactions for the full API.


Query Logging

The pool can log every executed query with its duration. Useful for debugging and performance analysis. Query logging is a static (global) feature — enabling it affects all pools. Warning: In production, logged queries accumulate without bound — use flush_query_log() periodically or disable logging after debugging.

cpp
using namespace framework;
using namespace framework::database;

// Enable logging globally for all pools
pool::enable_query_log();

// Run queries...
pool->run(/* ... */);

// Read the global log
auto& log = pool::get_query_log();
for (auto& entry : log) {
    fmt::println("Query: {} ({} ms)", entry.query, entry.elapsed_ms);
}

// Disable when done
pool::disable_query_log();

// Clear the log to free memory
pool::flush_query_log();

Each log entry contains:

FieldDescription
queryThe SQL query string.
paramsThe bound parameters.
elapsed_msExecution time in milliseconds.

Pool Management

pool_names() — List pools

cpp
auto names = db.pool_names();
// Returns: {"primary", "analytics", ...}

resize(new_max_size) — Change capacity

Dynamically adjusts the maximum number of connections.

cpp
pool->resize(64);  // Allow up to 64 connections

initial_size() / max_size() — Inspect pool config

cpp
auto init = pool->initial_size();  // Initial connection count
auto max = pool->max_size();       // Maximum connection capacity

is_stopped() — Check if pool is shut down

cpp
if (pool->is_stopped()) {
    // Pool has been shut down
}

stop() — Shut down

Closes all connections in the pool. Called automatically during app shutdown.

cpp
pool->stop();