Lightweight 0.20260921.0
Loading...
Searching...
No Matches
Lightweight::SqlPreparedStatementCache Class Referencefinal

A bounded LRU pool of already-prepared ODBC statement handles, owned by a SqlConnection. More...

#include <SqlPreparedStatementCache.hpp>

Classes

struct  PreparedHandle
 A pooled statement handle together with the parameter count the driver reported for it. More...
 
struct  Statistics
 Cumulative counters, primarily for tests and diagnostics. More...
 

Public Member Functions

LIGHTWEIGHT_API SqlPreparedStatementCache (std::size_t capacity=0) noexcept
 Constructs a cache with the given capacity.
 
LIGHTWEIGHT_API ~SqlPreparedStatementCache () noexcept
 Frees every pooled statement handle.
 
 SqlPreparedStatementCache (SqlPreparedStatementCache const &)=delete
 
SqlPreparedStatementCache & operator= (SqlPreparedStatementCache const &)=delete
 
 SqlPreparedStatementCache (SqlPreparedStatementCache &&)=delete
 
SqlPreparedStatementCache & operator= (SqlPreparedStatementCache &&)=delete
 
std::size_t Capacity () const noexcept
 
LIGHTWEIGHT_API void SetCapacity (std::size_t capacity) noexcept
 Sets the capacity, evicting the least recently released handles when shrinking.
 
bool IsEnabled () const noexcept
 
std::size_t Size () const noexcept
 
Statistics const & Stats () const noexcept
 
LIGHTWEIGHT_API void ResetStatistics () noexcept
 Resets the cumulative counters to zero, leaving the pooled handles untouched.
 
void RecordDirectReuse () noexcept
 
LIGHTWEIGHT_API std::optional< PreparedHandle > Acquire (std::string_view query) noexcept
 Takes an idle handle prepared for query out of the pool.
 
LIGHTWEIGHT_API void Release (std::string_view query, PreparedHandle handle) noexcept
 Hands a prepared handle back to the pool as the most recently used entry.
 
LIGHTWEIGHT_API void Clear () noexcept
 Frees every pooled handle, e.g. after DDL invalidated the cached query plans.
 

Detailed Description

A bounded LRU pool of already-prepared ODBC statement handles, owned by a SqlConnection.

Preparing a statement costs a server-side parse on MS SQL Server and PostgreSQL. Neither driver pays it inside SQLPrepare, which sends nothing: it rides along with the first execute of the freshly prepared handle, and a matching deallocate follows when the handle is freed. This cache keeps the SQLHSTMT handles of recently prepared queries alive, so a repeat of the same SQL text on the same connection re-executes a prepared handle instead. Measured behind a 50 ms link, that is worth about three round-trips per query on psqlODBC and one on the Microsoft driver.

A handle is checked out while a statement uses it: Acquire removes it from the pool and Release puts it back. Two statements preparing the same query at the same time therefore each get their own handle, and both are pooled afterwards (subject to the capacity bound). Eviction is least-recently-released first, which matters because several backends cap the number of live prepared statements per session.

Note
Not thread-safe, mirroring SqlConnection: one connection is used by one thread at a time.
A pooled handle holds a query plan derived from the schema as it was at preparation time. A connection that runs DDL must drop those plans via SqlConnection::ClearPreparedStatementCache — Lightweight's own migration paths do it for you.

Definition at line 59 of file SqlPreparedStatementCache.hpp.

Constructor & Destructor Documentation

◆ SqlPreparedStatementCache()

LIGHTWEIGHT_API Lightweight::SqlPreparedStatementCache::SqlPreparedStatementCache ( std::size_t  capacity = 0)
explicitnoexcept

Constructs a cache with the given capacity.

Parameters
capacityMaximum number of idle prepared handles to keep; 0 disables the cache.

Member Function Documentation

◆ Capacity()

std::size_t Lightweight::SqlPreparedStatementCache::Capacity ( ) const
inlinenoexcept
Returns
The maximum number of idle prepared handles kept (0 when disabled).

Definition at line 103 of file SqlPreparedStatementCache.hpp.

◆ SetCapacity()

LIGHTWEIGHT_API void Lightweight::SqlPreparedStatementCache::SetCapacity ( std::size_t  capacity)
noexcept

Sets the capacity, evicting the least recently released handles when shrinking.

Parameters
capacityMaximum number of idle prepared handles to keep; 0 disables and clears.

◆ IsEnabled()

bool Lightweight::SqlPreparedStatementCache::IsEnabled ( ) const
inlinenoexcept
Returns
Whether the cache is enabled, i.e. whether its capacity is non-zero.

Definition at line 113 of file SqlPreparedStatementCache.hpp.

◆ Size()

std::size_t Lightweight::SqlPreparedStatementCache::Size ( ) const
inlinenoexcept
Returns
The number of idle prepared handles currently pooled.

Definition at line 119 of file SqlPreparedStatementCache.hpp.

◆ Stats()

Statistics const & Lightweight::SqlPreparedStatementCache::Stats ( ) const
inlinenoexcept
Returns
The cumulative hit/miss/eviction counters.

Definition at line 125 of file SqlPreparedStatementCache.hpp.

◆ RecordDirectReuse()

void Lightweight::SqlPreparedStatementCache::RecordDirectReuse ( )
inlinenoexcept

Counts a prepare that reused the statement's own handle instead of the pool.

See also
Statistics::directReuses

Definition at line 135 of file SqlPreparedStatementCache.hpp.

References Lightweight::SqlPreparedStatementCache::Statistics::directReuses.

◆ Acquire()

LIGHTWEIGHT_API std::optional< PreparedHandle > Lightweight::SqlPreparedStatementCache::Acquire ( std::string_view  query)
noexcept

Takes an idle handle prepared for query out of the pool.

The caller owns the returned handle until it hands it back via Release (or frees it).

Parameters
queryThe exact SQL text the handle must have been prepared with.
Returns
The pooled handle, or std::nullopt when no idle handle matches.

◆ Release()

LIGHTWEIGHT_API void Lightweight::SqlPreparedStatementCache::Release ( std::string_view  query,
PreparedHandle  handle 
)
noexcept

Hands a prepared handle back to the pool as the most recently used entry.

The caller must have closed the handle's cursor and unbound its columns beforehand. Ownership of handle transfers to the cache; when the capacity bound is exceeded — or the cache is disabled — the surplus handle is freed right away.

Parameters
queryThe SQL text handle is prepared for.
handleThe prepared handle to pool.

The documentation for this class was generated from the following file: