Lightweight 0.20260617.0
Loading...
Searching...
No Matches
Lightweight::RowArrayCursor Class Reference

A cursor that fetches result rows in bulk (ODBC row-array binding) for fast column reads. More...

#include <SqlStatement.hpp>

Public Types

enum class  BoundType : std::uint8_t {
  Int64 , Double , Char , WChar ,
  Date , Timestamp , Guid
}
 How a result column is bound for bulk fetch (the canonical fixed-stride C representation chosen from the column's SQL type). Public so a transparent prefetch layer can dispatch a generic cell read to the matching Get* accessor. More...
 

Public Member Functions

 RowArrayCursor (RowArrayCursor const &)=delete
 
RowArrayCursoroperator= (RowArrayCursor const &)=delete
 
 RowArrayCursor (RowArrayCursor &&)=delete
 
RowArrayCursoroperator= (RowArrayCursor &&)=delete
 
LIGHTWEIGHT_API RowArrayCursor (SqlStatement &stmt, std::size_t arrayDepth)
 Constructs the cursor on a statement whose query has already been executed. Inspects the result columns via SQLDescribeCol, allocates per-column buffers, and binds them with the row-array statement attributes.
 
LIGHTWEIGHT_API ~RowArrayCursor () noexcept
 Resets the statement's row-array attributes and unbinds the columns so the handle can be safely reused.
 
LIGHTWEIGHT_API std::size_t FetchArray ()
 Fetches the next block of rows into the bound buffers.
 
LIGHTWEIGHT_API std::size_t ColumnCount () const noexcept
 The number of result columns.
 
LIGHTWEIGHT_API std::size_t ArrayDepth () const noexcept
 The effective maximum number of rows per FetchArray() — the requested depth, possibly reduced so the bound buffers fit MemoryBudgetBytes (never below MinArrayDepth unless the caller requested less).
 
LIGHTWEIGHT_API std::optional< std::int64_t > GetI64 (std::size_t rowInBatch, SQLUSMALLINT column) const
 Reads an integer cell from the last fetched block.
 
LIGHTWEIGHT_API std::optional< double > GetF64 (std::size_t rowInBatch, SQLUSMALLINT column) const
 Reads a floating-point cell from the last fetched block.
 
LIGHTWEIGHT_API std::optional< std::string > GetString (std::size_t rowInBatch, SQLUSMALLINT column) const
 Reads a text cell from the last fetched block, however the driver bound it.
 
LIGHTWEIGHT_API std::optional< SqlDateGetDate (std::size_t rowInBatch, SQLUSMALLINT column) const
 Reads a DATE cell from the last fetched block. Valid only for Date-bound columns.
 
LIGHTWEIGHT_API std::optional< SqlDateTimeGetTimestamp (std::size_t rowInBatch, SQLUSMALLINT column) const
 Reads a TIMESTAMP/DATETIME cell from the last fetched block. Valid only for Timestamp-bound columns.
 
LIGHTWEIGHT_API std::optional< SqlGuidGetGuid (std::size_t rowInBatch, SQLUSMALLINT column) const
 Reads a GUID cell from the last fetched block. Valid only for Guid-bound columns (drivers that report SQL_GUID, i.e. MSSQL uniqueidentifier / PostgreSQL uuid).
 
LIGHTWEIGHT_API BoundType ColumnBoundType (SQLUSMALLINT column) const
 The bound representation chosen for a result column.
 
LIGHTWEIGHT_API SQLSMALLINT ColumnSqlType (SQLUSMALLINT column) const
 The raw SQL data type the driver reported for a result column (the SQL_* value from SQLDescribeCol), letting callers gate on the exact source type rather than the coarser BoundType (which collapses e.g. textual TIME/NUMERIC into Char).
 
LIGHTWEIGHT_API bool IsCellNull (std::size_t rowInBatch, SQLUSMALLINT column) const
 Whether a cell in the last fetched block is SQL NULL.
 

Static Public Attributes

static constexpr std::size_t MaxCharColumnBytes = 8192
 
static constexpr std::size_t MemoryBudgetBytes = 4 * 1024 * 1024
 
static constexpr std::size_t MinArrayDepth = 16
 

Detailed Description

A cursor that fetches result rows in bulk (ODBC row-array binding) for fast column reads.

Created via SqlStatement::ExecuteBatchFetch. Instead of issuing one SQLGetData per cell, this cursor binds a contiguous buffer per result column and lets the driver materialize whole blocks of rows per SQLFetchScroll round-trip — eliminating per-cell driver round-trips.

Supported (fixed-stride) column types, decided per column from SQLDescribeCol:

  • integer SQL types (SQL_BIT, SQL_TINYINT, SQL_SMALLINT, SQL_INTEGER, SQL_BIGINT) are bound as SQL_C_SBIGINT (an int64 buffer);
  • floating SQL types (SQL_REAL, SQL_FLOAT, SQL_DOUBLE) are bound as SQL_C_DOUBLE;
  • all other types (char/varchar/decimal/date/time/timestamp/numeric/...) are bound as SQL_C_CHAR with a per-column buffer sized from the reported column size (plus a margin, capped at RowArrayCursor::MaxCharColumnBytes).

LOB / unbounded columns (the driver reports column size 0 or an absurdly large size) are rejected: constructing the cursor throws std::runtime_error. Such columns must use the single-row SQLGetData fallback instead.

The cursor is non-copyable and non-movable: it owns the ODBC statement's array-binding state for its entire lifetime. The constructor binds raw pointers into its own members (SQL_ATTR_ROWS_FETCHED_PTR, SQL_ATTR_ROW_STATUS_PTR) and SQLBindCol into its per-column buffers, so the object must not be relocated after construction — a move would leave the statement handle pointing at the moved-from storage (use-after-free). It is constructed in place via SqlStatement::ExecuteBatchFetch (guaranteed copy elision) and used as a local. The bound buffers must outlive the SQLBindCol binding until fetching completes. Cell indices are 1-based to match SqlResultCursor::GetColumn.

Definition at line 647 of file SqlStatement.hpp.

Member Enumeration Documentation

◆ BoundType

enum class Lightweight::RowArrayCursor::BoundType : std::uint8_t
strong

How a result column is bound for bulk fetch (the canonical fixed-stride C representation chosen from the column's SQL type). Public so a transparent prefetch layer can dispatch a generic cell read to the matching Get* accessor.

Enumerator
Int64 

bound as SQL_C_SBIGINT into an int64 buffer

Double 

bound as SQL_C_DOUBLE into a double buffer

Char 

bound as SQL_C_CHAR into a per-column byte buffer

WChar 

bound as SQL_C_WCHAR (UTF-16) into a per-column byte buffer

Date 

bound as SQL_C_TYPE_DATE into a SQL_DATE_STRUCT buffer

Timestamp 

bound as SQL_C_TYPE_TIMESTAMP into a SQL_TIMESTAMP_STRUCT buffer

Guid 

bound as SQL_C_GUID into a 16-byte GUID buffer

Definition at line 742 of file SqlStatement.hpp.

Constructor & Destructor Documentation

◆ RowArrayCursor()

LIGHTWEIGHT_API Lightweight::RowArrayCursor::RowArrayCursor ( SqlStatement stmt,
std::size_t  arrayDepth 
)

Constructs the cursor on a statement whose query has already been executed. Inspects the result columns via SQLDescribeCol, allocates per-column buffers, and binds them with the row-array statement attributes.

Parameters
stmtThe executed statement (must outlive the cursor).
arrayDepthMaximum number of rows materialized per FetchArray() (must be > 0). The effective depth may be reduced to fit MemoryBudgetBytes (see ArrayDepth()).

Member Function Documentation

◆ FetchArray()

LIGHTWEIGHT_API std::size_t Lightweight::RowArrayCursor::FetchArray ( )

Fetches the next block of rows into the bound buffers.

Returns
The number of rows materialized (0 at end of result set).

◆ GetI64()

LIGHTWEIGHT_API std::optional< std::int64_t > Lightweight::RowArrayCursor::GetI64 ( std::size_t  rowInBatch,
SQLUSMALLINT  column 
) const

Reads an integer cell from the last fetched block.

Parameters
rowInBatch0-based row offset within the block returned by the last FetchArray().
column1-based result column index.
Returns
The value, or std::nullopt if the cell is NULL.

◆ GetF64()

LIGHTWEIGHT_API std::optional< double > Lightweight::RowArrayCursor::GetF64 ( std::size_t  rowInBatch,
SQLUSMALLINT  column 
) const

Reads a floating-point cell from the last fetched block.

Parameters
rowInBatch0-based row offset within the block returned by the last FetchArray().
column1-based result column index.
Returns
The value, or std::nullopt if the cell is NULL.

◆ GetString()

LIGHTWEIGHT_API std::optional< std::string > Lightweight::RowArrayCursor::GetString ( std::size_t  rowInBatch,
SQLUSMALLINT  column 
) const

Reads a text cell from the last fetched block, however the driver bound it.

Narrow-bound cells (SQL_C_CHAR) are returned verbatim — identical bytes to a single-row SQL_C_CHAR read. Wide-bound cells (the driver reported SQL_WCHAR/SQL_WVARCHAR, e.g. MSSQL NVARCHAR, or SQLite which reports all text as wide) are converted UTF-16 -> UTF-8; for valid UTF-8 source data that round-trip is byte-lossless, so the result again matches the single-row read of the same cell.

Parameters
rowInBatch0-based row offset within the block returned by the last FetchArray().
column1-based result column index.
Returns
The UTF-8 value, or std::nullopt if the cell is NULL.

◆ GetDate()

LIGHTWEIGHT_API std::optional< SqlDate > Lightweight::RowArrayCursor::GetDate ( std::size_t  rowInBatch,
SQLUSMALLINT  column 
) const

Reads a DATE cell from the last fetched block. Valid only for Date-bound columns.

Parameters
rowInBatch0-based row offset within the block returned by the last FetchArray().
column1-based result column index.
Returns
The value, or std::nullopt if the cell is NULL.

◆ GetTimestamp()

LIGHTWEIGHT_API std::optional< SqlDateTime > Lightweight::RowArrayCursor::GetTimestamp ( std::size_t  rowInBatch,
SQLUSMALLINT  column 
) const

Reads a TIMESTAMP/DATETIME cell from the last fetched block. Valid only for Timestamp-bound columns.

Parameters
rowInBatch0-based row offset within the block returned by the last FetchArray().
column1-based result column index.
Returns
The value, or std::nullopt if the cell is NULL.

◆ GetGuid()

LIGHTWEIGHT_API std::optional< SqlGuid > Lightweight::RowArrayCursor::GetGuid ( std::size_t  rowInBatch,
SQLUSMALLINT  column 
) const

Reads a GUID cell from the last fetched block. Valid only for Guid-bound columns (drivers that report SQL_GUID, i.e. MSSQL uniqueidentifier / PostgreSQL uuid).

Parameters
rowInBatch0-based row offset within the block returned by the last FetchArray().
column1-based result column index.
Returns
The value, or std::nullopt if the cell is NULL.

◆ ColumnBoundType()

LIGHTWEIGHT_API BoundType Lightweight::RowArrayCursor::ColumnBoundType ( SQLUSMALLINT  column) const

The bound representation chosen for a result column.

Parameters
column1-based result column index.
Returns
The BoundType the column was bound as.

◆ ColumnSqlType()

LIGHTWEIGHT_API SQLSMALLINT Lightweight::RowArrayCursor::ColumnSqlType ( SQLUSMALLINT  column) const

The raw SQL data type the driver reported for a result column (the SQL_* value from SQLDescribeCol), letting callers gate on the exact source type rather than the coarser BoundType (which collapses e.g. textual TIME/NUMERIC into Char).

Parameters
column1-based result column index.
Returns
The reported SQL_* type code.

◆ IsCellNull()

LIGHTWEIGHT_API bool Lightweight::RowArrayCursor::IsCellNull ( std::size_t  rowInBatch,
SQLUSMALLINT  column 
) const

Whether a cell in the last fetched block is SQL NULL.

Parameters
rowInBatch0-based row offset within the block returned by the last FetchArray.
column1-based result column index.
Returns
true if the cell's length indicator is SQL_NULL_DATA.

Member Data Documentation

◆ MaxCharColumnBytes

constexpr std::size_t Lightweight::RowArrayCursor::MaxCharColumnBytes = 8192
staticconstexpr

Maximum byte width allocated for a single bound character column (per row). Columns whose reported size exceeds this are treated as unbounded/LOB and rejected.

Definition at line 652 of file SqlStatement.hpp.

◆ MemoryBudgetBytes

constexpr std::size_t Lightweight::RowArrayCursor::MemoryBudgetBytes = 4 * 1024 * 1024
staticconstexpr

Per-cursor byte budget for the bound column buffers. The effective array depth is clamp(budget / row-byte-width, MinArrayDepth, requested depth), so wide tables (many or large character columns) bind fewer rows per round-trip instead of exhausting memory — the footprint otherwise multiplies across workers x columns x depth on real schemas.

Definition at line 658 of file SqlStatement.hpp.

◆ MinArrayDepth

constexpr std::size_t Lightweight::RowArrayCursor::MinArrayDepth = 16
staticconstexpr

Lower bound for the budget-adapted array depth, so bulk fetch always makes progress even on extremely wide rows (never reduced below this unless the caller requested less).

Definition at line 662 of file SqlStatement.hpp.


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