Showing preview only (627K chars total). Download the full file or copy to clipboard to get everything.
Repository: taocpp/taopq
Branch: main
Commit: 0f28919fd7aa
Files: 146
Total size: 586.6 KB
Directory structure:
gitextract_iares_uf/
├── .clang-format
├── .clang-tidy
├── .github/
│ ├── conan/
│ │ ├── conanfile.py
│ │ └── profiles/
│ │ ├── clangcl
│ │ └── msvc
│ └── workflows/
│ ├── clang-analyze.yml
│ ├── clang-format.yml
│ ├── clang-tidy.yml
│ ├── code-coverage.yml
│ ├── linux.yml
│ ├── macos.yml
│ ├── sanitizer.yml
│ └── windows.yml
├── .gitignore
├── CMakeLists.txt
├── CMakePresets.json
├── LICENSE_1_0.txt
├── Makefile
├── README.md
├── doc/
│ ├── Aggregate-Support.md
│ ├── Binary-Data.md
│ ├── Bulk-Transfer.md
│ ├── Connection-Pool.md
│ ├── Connection.md
│ ├── Error-Handling.md
│ ├── Getting-Started.md
│ ├── Installation.md
│ ├── Large-Object.md
│ ├── Parameter-Type-Conversion.md
│ ├── Performance.md
│ ├── Requirements.md
│ ├── Result-Type-Conversion.md
│ ├── Result.md
│ ├── Statement.md
│ ├── TOC.md
│ └── Transaction.md
├── example/
│ ├── CMakeLists.txt
│ └── get_version/
│ ├── CMakeLists.txt
│ └── main.cpp
├── include/
│ └── tao/
│ ├── pq/
│ │ ├── access_mode.hpp
│ │ ├── binary.hpp
│ │ ├── bind.hpp
│ │ ├── connection.hpp
│ │ ├── connection_pool.hpp
│ │ ├── connection_status.hpp
│ │ ├── exception.hpp
│ │ ├── field.hpp
│ │ ├── internal/
│ │ │ ├── aggregate.hpp
│ │ │ ├── demangle.hpp
│ │ │ ├── exclusive_scan.hpp
│ │ │ ├── format_as.hpp
│ │ │ ├── from_chars.hpp
│ │ │ ├── gen.hpp
│ │ │ ├── parameter_traits_helper.hpp
│ │ │ ├── poll.hpp
│ │ │ ├── pool.hpp
│ │ │ ├── resize_uninitialized.hpp
│ │ │ ├── strtox.hpp
│ │ │ ├── unreachable.hpp
│ │ │ └── zsv.hpp
│ │ ├── is_aggregate.hpp
│ │ ├── is_array.hpp
│ │ ├── isolation_level.hpp
│ │ ├── large_object.hpp
│ │ ├── log.hpp
│ │ ├── notification.hpp
│ │ ├── null.hpp
│ │ ├── oid.hpp
│ │ ├── parameter.hpp
│ │ ├── parameter_traits.hpp
│ │ ├── parameter_traits_aggregate.hpp
│ │ ├── parameter_traits_array.hpp
│ │ ├── parameter_traits_optional.hpp
│ │ ├── parameter_traits_pair.hpp
│ │ ├── parameter_traits_tuple.hpp
│ │ ├── pipeline.hpp
│ │ ├── pipeline_status.hpp
│ │ ├── poll.hpp
│ │ ├── result.hpp
│ │ ├── result_status.hpp
│ │ ├── result_traits.hpp
│ │ ├── result_traits_aggregate.hpp
│ │ ├── result_traits_array.hpp
│ │ ├── result_traits_optional.hpp
│ │ ├── result_traits_pair.hpp
│ │ ├── result_traits_tuple.hpp
│ │ ├── row.hpp
│ │ ├── table_field.hpp
│ │ ├── table_reader.hpp
│ │ ├── table_row.hpp
│ │ ├── table_writer.hpp
│ │ ├── transaction.hpp
│ │ ├── transaction_base.hpp
│ │ ├── transaction_status.hpp
│ │ └── version.hpp
│ └── pq.hpp
├── src/
│ └── lib/
│ └── pq/
│ ├── connection.cpp
│ ├── connection_pool.cpp
│ ├── exception.cpp
│ ├── field.cpp
│ ├── internal/
│ │ ├── demangle.cpp
│ │ ├── poll.cpp
│ │ └── strtox.cpp
│ ├── large_object.cpp
│ ├── parameter_traits.cpp
│ ├── pipeline.cpp
│ ├── result.cpp
│ ├── result_traits.cpp
│ ├── result_traits_array.cpp
│ ├── row.cpp
│ ├── table_field.cpp
│ ├── table_reader.cpp
│ ├── table_row.cpp
│ ├── table_writer.cpp
│ ├── transaction.cpp
│ └── transaction_base.cpp
└── test/
├── CMakeLists.txt
├── integration/
│ ├── aggregate.cpp
│ ├── array.cpp
│ ├── basic_datatypes.cpp
│ ├── chunk_mode.cpp
│ ├── connection.cpp
│ ├── connection_pool.cpp
│ ├── example.cpp
│ ├── exception.cpp
│ ├── large_object.cpp
│ ├── log.cpp
│ ├── notifications.cpp
│ ├── parameter.cpp
│ ├── password.cpp
│ ├── pipeline_mode.cpp
│ ├── result.cpp
│ ├── row.cpp
│ ├── single_row_mode.cpp
│ ├── table_reader.cpp
│ ├── table_writer.cpp
│ ├── traits.cpp
│ └── transaction.cpp
├── unit/
│ ├── getenv.cpp
│ ├── parameter_type.cpp
│ ├── resize_uninitialized.cpp
│ ├── result_type.cpp
│ └── strtox.cpp
└── utils/
├── compare.hpp
├── getenv.hpp
└── macros.hpp
================================================
FILE CONTENTS
================================================
================================================
FILE: .clang-format
================================================
# The Art of C++
# https://github.com/taocpp
# Copyright (c) 2016-2026 Dr. Colin Hirsch and Daniel Frey
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
# This is our official .clang-format style for https://github.com/taocpp
#
# clang-format -i -style=file $(find . -name '[^.]*.[hc]pp')
Language: Cpp
Standard: Latest
AccessModifierOffset: -3
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlinesLeft: false
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: false
BinPackParameters: false
BraceWrapping:
AfterClass: true
AfterControlStatement: false
AfterEnum : true
AfterFunction : true
AfterNamespace : true
AfterStruct : true
AfterUnion : true
AfterExternBlock: true
BeforeCatch : true
BeforeElse : true
IndentBraces : false
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: false
BreakBeforeBinaryOperators: All
BreakBeforeBraces: Custom
BreakBeforeTernaryOperators: false
BreakConstructorInitializers: BeforeColon
BreakInheritanceList: BeforeColon
BreakStringLiterals: false
ColumnLimit: 0
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 3
ContinuationIndentWidth: 3
Cpp11BracedListStyle: false
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
IncludeBlocks: Preserve
IndentCaseLabels: true
IndentPPDirectives: None
IndentWidth: 3
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: false
MaxEmptyLinesToKeep: 1
NamespaceIndentation: All
PointerAlignment: Left
ReflowComments: false
SortIncludes: true
SortUsingDeclarations: false
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: Never
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: true
SpacesInSquareBrackets: true
TabWidth: 8
UseTab: Never
================================================
FILE: .clang-tidy
================================================
# The Art of C++
# https://github.com/taocpp
# Copyright (c) 2016-2026 Dr. Colin Hirsch and Daniel Frey
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
# Note: The misc-include-cleaner is generally useful,
# but produces false positives with Oid/InvalidOid and libpq-fe.h.
# For that reason it is disabled, but it should be enabled
# manually from time to time.
Checks: >-
bugprone-*,
-bugprone-easily-swappable-parameters,
cppcoreguidelines-slicing,
cppcoreguidelines-special-member-functions,
google-build-explicit-make-pair,
google-build-namespaces,
google-default-arguments,
google-global-names-in-headers,
google-readability-casting,
llvm-*,
misc-*,
-misc-include-cleaner,
-misc-non-private-member-variables-in-classes,
-misc-unused-alias-decls,
modernize-*,
-modernize-avoid-c-arrays,
-modernize-concat-nested-namespaces,
-modernize-raw-string-literal,
performance-*,
readability-*,
-readability-avoid-const-params-in-decls,
-readability-function-cognitive-complexity,
-readability-identifier-length,
-readability-magic-numbers,
-readability-non-const-parameter,
CheckOptions:
- { key: readability-identifier-naming.ClassCase, value: lower_case }
- { key: readability-identifier-naming.FunctionCase, value: lower_case }
- { key: readability-identifier-naming.ParameterCase, value: lower_case }
- { key: readability-identifier-naming.StructCase, value: lower_case }
- { key: readability-identifier-naming.VariableCase, value: lower_case }
WarningsAsErrors: '*'
================================================
FILE: .github/conan/conanfile.py
================================================
from conan import ConanFile
from conan.tools.cmake import CMakeDeps, CMakeToolchain, cmake_layout
class TaopqRequirements(ConanFile):
settings = "os", "compiler", "build_type", "arch"
default_options = {
"libpq/*:with_openssl": False,
"libpq/*:with_icu": False,
"libpq/*:with_zlib": False,
"libpq/*:with_zstd": False,
"libpq/*:with_libxml2": False,
"libpq/*:with_lz4": False,
"libpq/*:with_xslt": False,
"libpq/*:with_readline": False
}
def layout(self):
cmake_layout(self)
def requirements(self):
self.requires("libpq/[*]")
def generate(self):
tc = CMakeToolchain(self)
tc.generate()
deps = CMakeDeps(self)
deps.set_property("libpq", "cmake_file_name", "PostgreSQL")
deps.set_property("libpq", "cmake_target_name", "PostgreSQL::PostgreSQL")
deps.set_property("libpq", "cmake_additional_variables_prefixes", ["PostgreSQL",])
deps.generate()
================================================
FILE: .github/conan/profiles/clangcl
================================================
[settings]
os=Windows
arch=x86_64
build_type=Release
compiler=clang
compiler.version=19
compiler.cppstd=20
compiler.runtime=dynamic
compiler.runtime_type=Release
compiler.runtime_version=v144
libpq/*:compiler=msvc
libpq/*:compiler.version=194
libpq/*:compiler.cppstd=20
libpq/*:compiler.runtime=dynamic
libpq/*:compiler.runtime_type=Release
[conf]
tools.cmake.cmaketoolchain:generator=Ninja
tools.meson.mesontoolchain:backend=ninja
tools.build:compiler_executables={"c": "clang-cl.exe", "cpp": "clang-cl.exe"}
libpq/*:tools.build:compiler_executables={"c": "cl.exe", "cpp": "cl.exe"}
================================================
FILE: .github/conan/profiles/msvc
================================================
[settings]
arch=x86_64
build_type=Release
compiler=msvc
compiler.cppstd=20
compiler.runtime=dynamic
compiler.runtime_type=Release
compiler.version=194
os=Windows
[conf]
tools.cmake.cmaketoolchain:generator=Ninja
tools.meson.mesontoolchain:backend=ninja
================================================
FILE: .github/workflows/clang-analyze.yml
================================================
name: clang-analyze
on:
push:
paths-ignore:
- 'README.md'
- 'doc/**'
pull_request:
paths-ignore:
- 'README.md'
- 'doc/**'
jobs:
clang-analyze:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: clang-tools libpq-dev
version: 1.0
- name: Configure CMake Project
run: scan-build cmake --preset unixlike-release-dev
- name: Build project files
run: scan-build cmake --build --preset unixlike-release-dev
================================================
FILE: .github/workflows/clang-format.yml
================================================
name: clang-format
on:
push:
paths-ignore:
- 'README.md'
- 'doc/**'
pull_request:
paths-ignore:
- 'README.md'
- 'doc/**'
jobs:
clang-format:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: DoozyX/clang-format-lint-action@v0.20
with:
extensions: 'hpp,cpp'
================================================
FILE: .github/workflows/clang-tidy.yml
================================================
name: clang-tidy
on:
push:
paths-ignore:
- 'README.md'
- 'doc/**'
pull_request:
paths-ignore:
- 'README.md'
- 'doc/**'
jobs:
clang-tidy:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: libpq-dev clang-tidy
version: 3.0
- name: Configure CMake Project
run: cmake --preset unixlike-debug-dev -DBUILD_EXAMPLES=OFF -DBUILD_TESTING=OFF
- name: Build project files
run: cmake --build --preset unixlike-debug-dev
- name: Run clang-tidy
run: run-clang-tidy -p build/unixlike-debug-dev/
================================================
FILE: .github/workflows/code-coverage.yml
================================================
name: code-coverage
on:
push:
paths-ignore:
- 'README.md'
- 'doc/**'
pull_request:
paths-ignore:
- 'README.md'
- 'doc/**'
jobs:
code-coverage:
runs-on: ubuntu-24.04
services:
postgres:
image: postgres:latest
env:
POSTGRES_DB: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
ports:
- 5432:5432
# Set health checks to wait until postgres has started
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
TAOPQ_TEST_DATABASE: host=localhost dbname=postgres user=postgres password=postgres
steps:
- uses: actions/checkout@v5
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: libpq-dev
version: 1.0
- name: Exclude example folder from code coverage
run: |
printf "ignore:\n - example/**\n" >> .codecov.yml
- name: Configure CMake Project
run: cmake --preset unixlike-release-dev -DCMAKE_CXX_FLAGS="-coverage" -DBUILD_EXAMPLES=OFF
- name: Build project files
run: cmake --build --preset unixlike-release-dev
- name: Run tests
run: cmake --build --preset unixlike-release-dev --target test
- uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
================================================
FILE: .github/workflows/linux.yml
================================================
name: Linux
on:
push:
paths-ignore:
- 'README.md'
- 'doc/**'
pull_request:
paths-ignore:
- 'README.md'
- 'doc/**'
jobs:
linux-next:
strategy:
matrix:
compiler:
- g++-13
- g++-14
- g++-15
- g++-16
- clang++-18
runs-on: ubuntu-24.04
services:
postgres:
image: postgres:latest
env:
POSTGRES_DB: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
ports:
- 5432:5432
# Set health checks to wait until postgres has started
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
CXX: ${{ matrix.compiler }}
TAOPQ_TEST_DATABASE: host=localhost dbname=postgres user=postgres password=postgres
steps:
- uses: actions/checkout@v5
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: libpq-dev libc++-dev
version: 2.0
- name: Install GCC-15
if: matrix.compiler == 'g++-15'
run: |
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt-get install -y g++-15
- name: Install GCC-16
if: matrix.compiler == 'g++-16'
run: |
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt-get install -y g++-16
- name: Configure CMake Project
run: cmake --preset unixlike-release-dev -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/taopq-install
- name: Build project files
run: cmake --build --preset unixlike-release-dev
- name: Run tests
run: cmake --build --preset unixlike-release-dev --target test
- name: Run examples
run: cmake --build --preset unixlike-release-dev --target examples
env:
PGDATABASE: ${{ env.TAOPQ_TEST_DATABASE }}
- name: Install Taocpp TaoPQ
run: cmake --build --preset unixlike-release-dev --target install
linux-gcc-old-abi:
runs-on: ubuntu-24.04
services:
postgres:
image: postgres:latest
env:
POSTGRES_DB: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
ports:
- 5432:5432
# Set health checks to wait until postgres has started
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
CXX: g++
TAOPQ_TEST_DATABASE: host=localhost dbname=postgres user=postgres password=postgres
steps:
- uses: actions/checkout@v5
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: libpq-dev libc++-dev
version: 2.0
- name: Configure CMake Project
run: cmake --preset unixlike-release-dev -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/taopq-install -DCMAKE_CXX_FLAGS="-D_GLIBCXX_USE_CXX11_ABI=0"
- name: Build project files
run: cmake --build --preset unixlike-release-dev
- name: Run tests
run: cmake --build --preset unixlike-release-dev --target test
linux-clang-extra:
strategy:
matrix:
flags: ["-stdlib=libc++","-fms-extensions"]
runs-on: ubuntu-24.04
services:
postgres:
image: postgres:latest
env:
POSTGRES_DB: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
ports:
- 5432:5432
# Set health checks to wait until postgres has started
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
CXX: clang++
TAOPQ_TEST_DATABASE: host=localhost dbname=postgres user=postgres password=postgres
steps:
- uses: actions/checkout@v5
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: libpq-dev libc++-dev
version: 2.0
- name: Configure CMake Project
run: cmake --preset unixlike-release-dev -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/taopq-install -DCMAKE_CXX_FLAGS="${{ matrix.flags }}"
- name: Build project files
run: cmake --build --preset unixlike-release-dev
- name: Run tests
run: cmake --build --preset unixlike-release-dev --target test
linux-makefile:
runs-on: ubuntu-24.04
services:
postgres:
image: postgres:latest
env:
POSTGRES_DB: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
ports:
- 5432:5432
# Set health checks to wait until postgres has started
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
TAOPQ_TEST_DATABASE: host=localhost dbname=postgres user=postgres password=postgres
CXX: g++-13
steps:
- uses: actions/checkout@v5
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: libpq-dev libc++-dev
version: 2.0
- name: Build project files with Makefile
run: make -j$(nproc)
- name: Run tests with Makefile
run: make test
env:
PGDATABASE: ${{ env.TAOPQ_TEST_DATABASE }}
================================================
FILE: .github/workflows/macos.yml
================================================
name: macOS
on:
push:
paths-ignore:
- 'README.md'
- 'doc/**'
pull_request:
paths-ignore:
- 'README.md'
- 'doc/**'
jobs:
xcode-macos-15:
runs-on: macos-15
env:
TAOPQ_TEST_DATABASE: host=localhost dbname=postgres user=postgres password=postgres
steps:
- uses: actions/checkout@v5
- uses: ikalnytskyi/action-setup-postgres@v8
- uses: conan-io/setup-conan@v1
with:
cache_packages: true
- name: Install dependencies with Conan
run: conan install ${{ github.workspace }}/.github/conan/conanfile.py -s compiler.cppstd=20 --build=missing --lockfile-partial
- name: Configure CMake Project
run: cmake --preset unixlike-release-dev -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/taopq-install -DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/.github/conan/build/Release/generators/conan_toolchain.cmake
- name: Build project files
run: cmake --build --preset unixlike-release-dev
- name: Run tests
run: cmake --build --preset unixlike-release-dev --target test
- name: Run examples
run: cmake --build --preset unixlike-release-dev --target examples
env:
PGDATABASE: ${{ env.TAOPQ_TEST_DATABASE }}
- name: Install Taocpp TaoPQ
run: cmake --build --preset unixlike-release-dev --target install
================================================
FILE: .github/workflows/sanitizer.yml
================================================
name: Sanitizer
on:
push:
paths-ignore:
- 'README.md'
- 'doc/**'
pull_request:
paths-ignore:
- 'README.md'
- 'doc/**'
jobs:
sanitizer:
strategy:
matrix:
sanitizer: [address, undefined, thread, leak]
runs-on: ubuntu-24.04
services:
postgres:
image: postgres:latest
env:
POSTGRES_DB: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
ports:
- 5432:5432
# Set health checks to wait until postgres has started
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
CXX: clang++
CC: clang
TAOPQ_TEST_DATABASE: host=localhost dbname=postgres user=postgres password=postgres
steps:
- uses: actions/checkout@v5
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: libpq-dev
version: 1.0
- name: Configure CMake Project
run: cmake --preset unixlike-debug-dev -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/taopq-install -DCMAKE_CXX_FLAGS="-fsanitize=${{ matrix.sanitizer }}"
- name: Build project files
run: cmake --build --preset unixlike-debug-dev
- name: Run tests
run: cmake --build --preset unixlike-debug-dev --target test
================================================
FILE: .github/workflows/windows.yml
================================================
name: Windows
on:
push:
paths-ignore:
- 'README.md'
- 'doc/**'
pull_request:
paths-ignore:
- 'README.md'
- 'doc/**'
jobs:
vs2022:
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
cxx: [ "msvc", "clangcl" ]
env:
TAOPQ_TEST_DATABASE: host=localhost dbname=postgres user=postgres password=postgres
steps:
- uses: actions/checkout@v5
- name: Set up PostgreSQL
uses: ikalnytskyi/action-setup-postgres@v8
- name: Set up MSVC dev cmd (x64)
uses: ilammy/msvc-dev-cmd@v1
with:
arch: x64
- name: Set up Conan
uses: conan-io/setup-conan@v1
with:
cache_packages: true
config_urls: .github/conan
- name: Install dependencies with Conan MSVC
run: conan install ${{ github.workspace }}/.github/conan/conanfile.py --build=missing -pr ${{ matrix.cxx }} --lockfile-partial
- name: CMake Configure
shell: pwsh
run: cmake --preset ${{ matrix.cxx }}-release-dev -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/taopq-install -DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/.github/conan/build/Release/generators/conan_toolchain.cmake
- name: Build project files
run: cmake --build --preset ${{ matrix.cxx }}-release-dev
- name: Run tests
run: cmake --build --preset ${{ matrix.cxx }}-release-dev --target test
- name: Run examples
run: cmake --build --preset ${{ matrix.cxx }}-release-dev --target examples
env:
PGDATABASE: ${{ env.TAOPQ_TEST_DATABASE }}
- name: Install Taocpp TaoPQ
run: cmake --build --preset ${{ matrix.cxx }}-release-dev --target install
================================================
FILE: .gitignore
================================================
*~
build
dummy.txt
================================================
FILE: CMakeLists.txt
================================================
cmake_minimum_required(VERSION 3.15)
# Read version from version.hpp
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/version.hpp" taopq_VERSION_DATA)
string(REGEX MATCH "#define TAO_PQ_VERSION \"([^\"]+)\"" _ ${taopq_VERSION_DATA})
set(taopq_VERSION "${CMAKE_MATCH_1}")
project(taopq
VERSION ${taopq_VERSION}
LANGUAGES CXX
DESCRIPTION "A lightweight C++ client library for accessing a PostgreSQL database"
HOMEPAGE_URL "https://github.com/taocpp/taopq"
)
option(BUILD_EXAMPLES "Build taopq examples" ON)
find_package(PostgreSQL REQUIRED)
add_library(${PROJECT_NAME})
add_library(taocpp::taopq ALIAS ${PROJECT_NAME})
target_sources(${PROJECT_NAME}
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src/lib/pq/connection.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/lib/pq/connection_pool.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/lib/pq/exception.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/lib/pq/field.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/lib/pq/internal/demangle.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/lib/pq/internal/poll.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/lib/pq/internal/strtox.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/lib/pq/large_object.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/lib/pq/parameter_traits.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/lib/pq/pipeline.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/lib/pq/result.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/lib/pq/result_traits.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/lib/pq/result_traits_array.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/lib/pq/row.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/lib/pq/table_field.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/lib/pq/table_reader.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/lib/pq/table_row.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/lib/pq/table_writer.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/lib/pq/transaction.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/lib/pq/transaction_base.cpp
PUBLIC FILE_SET HEADERS
BASE_DIRS include
FILES
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/access_mode.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/binary.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/bind.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/connection.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/connection_pool.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/connection_status.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/exception.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/field.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/internal/aggregate.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/internal/demangle.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/internal/exclusive_scan.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/internal/format_as.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/internal/from_chars.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/internal/gen.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/internal/parameter_traits_helper.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/internal/poll.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/internal/pool.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/internal/resize_uninitialized.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/internal/strtox.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/internal/unreachable.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/internal/zsv.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/is_aggregate.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/is_array.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/isolation_level.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/large_object.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/log.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/notification.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/null.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/oid.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/parameter.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/parameter_traits.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/parameter_traits_aggregate.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/parameter_traits_array.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/parameter_traits_optional.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/parameter_traits_pair.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/parameter_traits_tuple.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/pipeline.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/pipeline_status.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/poll.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/result.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/result_status.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/result_traits.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/result_traits_aggregate.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/result_traits_array.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/result_traits_optional.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/result_traits_pair.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/result_traits_tuple.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/row.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/table_field.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/table_reader.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/table_row.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/table_writer.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/transaction.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/transaction_base.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/transaction_status.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/tao/pq/version.hpp
)
target_include_directories(${PROJECT_NAME}
PUBLIC
$<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src
)
target_link_libraries(${PROJECT_NAME} PUBLIC PostgreSQL::PostgreSQL)
if(WIN32)
target_link_libraries(${PROJECT_NAME} PUBLIC ws2_32)
endif()
target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_20)
set_target_properties(${PROJECT_NAME} PROPERTIES
OUTPUT_NAME taopq
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
CXX_VISIBILITY_PRESET hidden
VISIBILITY_INLINES_HIDDEN ON
EXPORT_NAME taopq
)
if(PROJECT_IS_TOP_LEVEL)
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
install(TARGETS taopq
EXPORT taopq-targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
FILE_SET HEADERS
)
install(FILES LICENSE_1_0.txt DESTINATION ${CMAKE_INSTALL_DOCDIR})
install(EXPORT taopq-targets
FILE ${PROJECT_NAME}Targets.cmake
NAMESPACE taocpp::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/taopq
)
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion
)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
"include(CMakeFindDependencyMacro)
find_dependency(PostgreSQL REQUIRED CONFIG)
include(\"\${CMAKE_CURRENT_LIST_DIR}/taopqTargets.cmake\")
")
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/taopq
)
export(EXPORT taopq-targets
FILE "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Targets.cmake"
NAMESPACE taocpp::
)
endif()
if(BUILD_TESTING AND PROJECT_IS_TOP_LEVEL)
enable_testing()
add_subdirectory(test)
endif()
if(BUILD_EXAMPLES AND PROJECT_IS_TOP_LEVEL)
add_subdirectory(example)
endif()
================================================
FILE: CMakePresets.json
================================================
{
"version": 6,
"cmakeMinimumRequired": {
"major": 3,
"minor": 21,
"patch": 0
},
"configurePresets": [
{
"name": "default",
"hidden": true,
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/${presetName}",
"cacheVariables": {
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
}
},
{
"name": "dev-flags-gcc-clang",
"hidden": true,
"cacheVariables": {
"CMAKE_CXX_FLAGS": "-Wall -Wextra -Wpedantic -Werror -Wconversion -Wshadow -Wnon-virtual-dtor -Wold-style-cast -Wcast-align -Wunused -Woverloaded-virtual -Wnull-dereference -Wno-sign-conversion",
"BUILD_TESTING": "ON",
"BUILD_EXAMPLES": "ON"
}
},
{
"name": "dev-flags-msvc",
"hidden": true,
"cacheVariables": {
"CMAKE_CXX_FLAGS": "/EHsc /W4 /WX /permissive-",
"BUILD_TESTING": "ON",
"BUILD_EXAMPLES": "ON"
}
},
{
"name": "debug",
"inherits": "default",
"displayName": "Debug",
"description": "Debug build",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
}
},
{
"name": "release",
"inherits": "default",
"displayName": "Release",
"description": "Release build with optimizations",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release"
}
},
{
"name": "unixlike-debug",
"inherits": "debug",
"displayName": "Unix Like Compiler Debug",
"description": "Debug build using GCC or Clang"
},
{
"name": "unixlike-release",
"inherits": "release",
"displayName": "Unix Like Compiler Release",
"description": "Release build using GCC or Clang"
},
{
"name": "unixlike-debug-dev",
"inherits": ["debug", "dev-flags-gcc-clang"],
"displayName": "Unix Like Compiler Debug (Dev with -Werror)",
"description": "Debug build using Clang or GCC with warnings as errors"
},
{
"name": "unixlike-release-dev",
"inherits": ["release", "dev-flags-gcc-clang"],
"displayName": "Unix Like Compiler Release (Dev with -Werror)",
"description": "Release build using Clang or GCC with warnings as errors"
},
{
"name": "clangcl-debug",
"inherits": "debug",
"displayName": "MSVC Debug",
"description": "Debug build using MSVC",
"generator": "Ninja",
"cacheVariables": {
"CMAKE_C_COMPILER": "clang-cl",
"CMAKE_CXX_COMPILER": "clang-cl"
},
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
}
},
{
"name": "clangcl-release",
"inherits": "release",
"displayName": "MSVC Release",
"description": "Ninja",
"generator": "Ninja",
"cacheVariables": {
"CMAKE_C_COMPILER": "clang-cl",
"CMAKE_CXX_COMPILER": "clang-cl"
},
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
}
},
{
"name": "msvc-debug",
"inherits": "debug",
"displayName": "MSVC Debug",
"description": "Ninja",
"generator": "Ninja",
"cacheVariables": {
"CMAKE_C_COMPILER": "cl",
"CMAKE_CXX_COMPILER": "cl"
},
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
}
},
{
"name": "msvc-release",
"inherits": "release",
"displayName": "MSVC Release",
"description": "Release build using MSVC",
"generator": "Ninja",
"cacheVariables": {
"CMAKE_C_COMPILER": "cl",
"CMAKE_CXX_COMPILER": "cl"
},
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
}
},
{
"name": "msvc-debug-dev",
"inherits": ["msvc-debug", "dev-flags-msvc"],
"displayName": "MSVC Debug (Dev with /WX)",
"description": "Debug build using MSVC with warnings as errors"
},
{
"name": "msvc-release-dev",
"inherits": ["msvc-release", "dev-flags-msvc"],
"displayName": "MSVC Release (Dev with /WX)",
"description": "Release build using MSVC with warnings as errors"
},
{
"name": "clangcl-debug-dev",
"inherits": ["clangcl-debug", "dev-flags-msvc"],
"displayName": "ClangCL Debug (Dev with /WX)",
"description": "Debug build using ClangCL with warnings as errors"
},
{
"name": "clangcl-release-dev",
"inherits": ["clangcl-release", "dev-flags-msvc"],
"displayName": "ClangCL Release (Dev with /WX)"
}
],
"buildPresets": [
{
"name": "debug",
"configurePreset": "debug",
"displayName": "Debug Build",
"description": "Build in Debug mode"
},
{
"name": "release",
"configurePreset": "release",
"displayName": "Release Build",
"description": "Build in Release mode"
},
{
"name": "unixlike-debug",
"configurePreset": "unixlike-debug",
"displayName": "Unix Like Compiler Debug Build"
},
{
"name": "unixlike-release",
"configurePreset": "unixlike-release",
"displayName": "Unix Like Compiler Release Build"
},
{
"name": "unixlike-debug-dev",
"configurePreset": "unixlike-debug-dev",
"displayName": "Unix Like Compiler Debug Build (Dev)"
},
{
"name": "unixlike-release-dev",
"configurePreset": "unixlike-release-dev",
"displayName": "Unix Like Compiler Release Build (Dev)"
},
{
"name": "msvc-debug",
"configurePreset": "msvc-debug",
"displayName": "MSVC Debug Build"
},
{
"name": "msvc-release",
"configurePreset": "msvc-release",
"displayName": "MSVC Release Build"
},
{
"name": "msvc-debug-dev",
"configurePreset": "msvc-debug-dev",
"displayName": "MSVC Debug Build (Dev)"
},
{
"name": "msvc-release-dev",
"configurePreset": "msvc-release-dev",
"displayName": "MSVC Release Build (Dev)"
},
{
"name": "clangcl-debug",
"configurePreset": "clangcl-debug",
"displayName": "MSVC Clang Debug Build"
},
{
"name": "clangcl-release",
"configurePreset": "clangcl-release",
"displayName": "MSVC Clang Release Build"
},
{
"name": "clangcl-debug-dev",
"configurePreset": "clangcl-debug-dev",
"displayName": "ClangCL Debug Build (Dev)"
},
{
"name": "clangcl-release-dev",
"configurePreset": "clangcl-release-dev",
"displayName": "ClangCL Release Build (Dev)"
}
],
"testPresets": [
{
"name": "debug",
"configurePreset": "debug",
"displayName": "Test Debug",
"output": {
"outputOnFailure": true
}
},
{
"name": "release",
"configurePreset": "release",
"displayName": "Test Release",
"output": {
"outputOnFailure": true
}
},
{
"name": "unixlike-release",
"configurePreset": "unixlike-release",
"displayName": "Test Unix Like Compiler Release",
"output": {
"outputOnFailure": true
}
},
{
"name": "unixlike-debug",
"configurePreset": "unixlike-debug",
"displayName": "Test Unix Like Compiler Debug",
"output": {
"outputOnFailure": true
}
},
{
"name": "unixlike-debug-dev",
"configurePreset": "unixlike-debug-dev",
"displayName": "Test Unix Like Compiler Debug (Dev)",
"output": {
"outputOnFailure": true
}
},
{
"name": "unixlike-release-dev",
"configurePreset": "unixlike-release-dev",
"displayName": "Test Unix Like Compiler Release (Dev)",
"output": {
"outputOnFailure": true
}
},
{
"name": "msvc-debug-dev",
"configurePreset": "msvc-debug-dev",
"displayName": "Test MSVC Debug (Dev)",
"output": {
"outputOnFailure": true
}
},
{
"name": "msvc-release-dev",
"configurePreset": "msvc-release-dev",
"displayName": "Test MSVC Release (Dev)",
"output": {
"outputOnFailure": true
}
},
{
"name": "clangcl-debug-dev",
"configurePreset": "clangcl-debug-dev",
"displayName": "Test ClangCL Debug (Dev)",
"output": {
"outputOnFailure": true
}
},
{
"name": "clangcl-release-dev",
"configurePreset": "clangcl-release-dev",
"displayName": "Test ClangCL Release (Dev)",
"output": {
"outputOnFailure": true
}
}
]
}
================================================
FILE: LICENSE_1_0.txt
================================================
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
================================================
FILE: Makefile
================================================
# The Art of C++
# https://github.com/taocpp
# Copyright (c) 2016-2026 Daniel Frey
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
.SUFFIXES:
.SECONDARY:
ifeq ($(OS),Windows_NT)
UNAME_S := $(OS)
ifeq ($(shell gcc -dumpmachine),mingw32)
MINGW_CXXFLAGS = -U__STRICT_ANSI__
endif
else
UNAME_S := $(shell uname -s)
endif
# For Darwin (Mac OS X / macOS) we assume that the default compiler
# clang++ is used; when $(CXX) is some version of g++, then
# $(CXXSTD) has to be set to -std=c++20 (or newer) so
# that -stdlib=libc++ is not automatically added.
ifeq ($(CXXSTD),)
CXXSTD := -std=c++20
ifeq ($(UNAME_S),Darwin)
CXXSTD += -stdlib=libc++
endif
endif
# Ensure strict standard compliance and no warnings, can be
# changed if desired.
BUILDDIR ?= build
INCFLAGS ?= -Iinclude -Itest $(patsubst %,-I%,$(shell pg_config --includedir))
CPPFLAGS ?= -pedantic
CXXFLAGS ?= -Wall -Wextra -Wshadow -Werror -O3 $(MINGW_CXXFLAGS)
LDFLAGS ?= -rdynamic $(patsubst %,-L%,$(shell pg_config --libdir))
LIBS ?= -lpq
CLANG_TIDY ?= clang-tidy
HEADERS := $(shell find include -name '*.hpp')
SOURCES := $(shell find src -name '*.cpp')
TESTSOURCES := $(shell find test -name '*.cpp')
DEPENDS := $(SOURCES:%.cpp=$(BUILDDIR)/%.d) $(TESTSOURCES:%.cpp=$(BUILDDIR)/%.d)
BINARIES := $(SOURCES:%.cpp=$(BUILDDIR)/%) $(TESTSOURCES:%.cpp=$(BUILDDIR)/%)
UNIT_TESTS := $(filter $(BUILDDIR)/test/%,$(BINARIES))
LIBSOURCES := $(filter src/lib/%,$(SOURCES))
LIBNAME := taopq
.PHONY: all
all: check
.PHONY: compile
compile: $(UNIT_TESTS)
.PHONY: check
check: $(UNIT_TESTS)
@set -e; for T in $(UNIT_TESTS); do echo $$T; $$T; done
$(BUILDDIR)/%.clang-tidy: % .clang-tidy
$(CLANG_TIDY) -quiet $< -- $(CXXSTD) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) 2>/dev/null
@mkdir -p $(@D)
@touch $@
.PHONY: clang-tidy
clang-tidy: $(HEADERS:%=$(BUILDDIR)/%.clang-tidy) $(SOURCES:%=$(BUILDDIR)/%.clang-tidy)
@echo "All $(words $(HEADERS) $(SOURCES)) clang-tidy tests passed."
.PHONY: clean
clean:
@rm -rf $(BUILDDIR)/*
@find . -name '*~' -delete
$(BUILDDIR)/%.d: %.cpp Makefile
@mkdir -p $(@D)
$(CXX) $(CXXSTD) $(INCFLAGS) $(CPPFLAGS) -MM -MQ $@ $< -o $@
$(BUILDDIR)/%.o: %.cpp $(BUILDDIR)/%.d
$(CXX) $(CXXSTD) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@
$(BUILDDIR)/lib/lib$(LIBNAME).a: $(LIBSOURCES:%.cpp=$(BUILDDIR)/%.o)
@mkdir -p $(@D)
$(AR) -rcs $@ $^
.PHONY: lib
lib: $(BUILDDIR)/lib/lib$(LIBNAME).a
$(BUILDDIR)/%: $(BUILDDIR)/%.o $(BUILDDIR)/lib/lib$(LIBNAME).a
@mkdir -p $(@D)
$(CXX) $(CXXSTD) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $^ $(LIBS) -o $@
ifeq ($(findstring $(MAKECMDGOALS),clean),)
-include $(DEPENDS)
endif
================================================
FILE: README.md
================================================
# Welcome to taoPQ
[](https://github.com/taocpp/taopq/actions?query=workflow%3AWindows)
[](https://github.com/taocpp/taopq/actions?query=workflow%3AmacOS)
[](https://github.com/taocpp/taopq/actions?query=workflow%3ALinux)
<br>
[](https://github.com/taocpp/taopq/actions?query=workflow%3Aclang-analyze)
[](https://github.com/taocpp/taopq/actions?query=workflow%3Aclang-tidy)
[](https://github.com/taocpp/taopq/actions?query=workflow%3ASanitizer)
[](https://codecov.io/gh/taocpp/taopq)
taoPQ is a lightweight C++ client library for accessing a [PostgreSQL➚](https://www.postgresql.org/) database.
It has no dependencies beyond [`libpq`➚](https://www.postgresql.org/docs/current/libpq.html), the C application programmer's interface to PostgreSQL.
## Introduction
The library provides support for database connections, transactions, nested transactions, prepared statements, large objects, connection pools, pipeline mode, high-speed bulk data transfer, and more.
An extensible traits mechanism is used to convert C++ types into SQL statement parameters, and conversely to convert query results into arbitrary C++ types.
The following example shows the basic look and feel of the library.
```c++
#include <iostream>
#include <tao/pq.hpp>
int main()
{
// open a connection to the database
const auto conn = tao::pq::connection::create( "dbname=template1" );
// execute statements
conn->execute( "DROP TABLE IF EXISTS users" );
conn->execute( "CREATE TABLE users ( name TEXT PRIMARY KEY, age INTEGER NOT NULL )" );
// prepare statements
conn->prepare( "insert_user", "INSERT INTO users ( name, age ) VALUES ( $1, $2 )" );
{
// begin transaction
const auto tr = conn->transaction();
// execute previously prepared statements
tr->execute( "insert_user", "Daniel", 42 );
tr->execute( "insert_user", "Tom", 41 );
tr->execute( "insert_user", "Jerry", 29 );
// commit transaction
tr->commit();
}
// query data
const auto users = conn->execute( "SELECT name, age FROM users WHERE age >= $1", 40 );
// iterate and convert results
for( const auto& row : users ) {
std::cout << row[ "name" ].as< std::string >() << " is "
<< row[ "age" ].as< unsigned >() << " years old.\n";
}
}
```
## Documentation
* [Table of Content](doc/TOC.md)
* [Requirements](doc/Requirements.md)
* [Installation](doc/Installation.md)
* [Getting Started](doc/Getting-Started.md)
* [Connection](doc/Connection.md)
* [Transaction](doc/Transaction.md)
* [Statement](doc/Statement.md)
* [Result](doc/Result.md)
## Contact
For questions and suggestions regarding taoPQ, success or failure stories, and any other kind of feedback, please feel free to open a [discussion](https://github.com/taocpp/taopq/discussions), an [issue](https://github.com/taocpp/taopq/issues) or a [pull request](https://github.com/taocpp/taopq/pulls) on GitHub or contact the authors at `taocpp(at)icemx.net`.
## The Art of C++
taoPQ is part of [The Art of C++](https://taocpp.github.io/).
[<img alt="colinh" src="https://avatars.githubusercontent.com/u/113184" width="120">](https://github.com/colinh)
[<img alt="d-frey" src="https://avatars.githubusercontent.com/u/3956325" width="120">](https://github.com/d-frey)
[<img alt="uilianries" src="https://avatars.githubusercontent.com/u/4870173" width="120">](https://github.com/uilianries)
## License
<a href="https://opensource.org/licenses/BSL-1.0"><img align="right" src="https://opensource.org/wp-content/uploads/2009/06/OSIApproved.svg" width="150" hspace="20" alt="Open Source Initiative"></a>
Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch
taoPQ is certified [Open Source➚](http://www.opensource.org/docs/definition.html) software.
It is [licensed➚](https://pdimov.github.io/blog/2020/09/06/why-use-the-boost-license/) under the terms of the [Boost Software License, Version 1.0➚](https://www.boost.org/LICENSE_1_0.txt) reproduced here.
> Boost Software License - Version 1.0 - August 17th, 2003
>
> Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following:
>
> The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
[The Art of C++]: https://taocpp.github.io/
================================================
FILE: doc/Aggregate-Support.md
================================================
# Aggregate Support
taoPQ allows the direct use of "simple" aggregates as parameters and result types.
## Requirements
An aggregate data type `T` suitable for taoPQ support must meet the following requirements:
* [`std::is_aggregate_v< T >`➚](https://en.cppreference.com/w/cpp/types/is_aggregate) must yield `true`.
* [`std::is_empty_v< T >`➚](https://en.cppreference.com/w/cpp/types/is_empty) must yield `false`.
* [`std::is_union_v< T >`➚](https://en.cppreference.com/w/cpp/types/is_union) must yield `false`.
* `T` must not have any base classes.
* `T` must not have more than 99 member variables. (this limit can be raised, open an [issue](https://github.com/taocpp/taopq/issues) if necessary)
## Registration
We currently require explicit registration of aggregate data types.
This is done as a precaution, and to avoid conflicts with other data types.
A data type `T` can be registered as both a parameter and a result type by specializing `tao::pq::is_aggregate` as follows:
```c++
template<>
inline constexpr bool tao::pq::is_aggregate< T > = true;
```
If necessary, you can control independently whether a data type is suitable as a parameter or a result type by specializing `tao::pq::is_aggregate_parameter` and `tao::pq::is_aggregate_result` as follows:
```c++
template<>
inline constexpr bool tao::pq::is_aggregate_parameter< T > = true;
template<>
inline constexpr bool tao::pq::is_aggregate_result< T > = true;
```
## Direct Result Conversion
An aggregate data type `T` that is registered as a result type enables the direct conversion of a `tao::pq::row` to `T`.
This is convenient when retrieving results and iterating over them, it enables you to write:
```c++
const auto result = conn->execute( "SELECT ... FROM ..." ); // some query
for( const T t : result ) {
// use t
}
```
:interrobang: Compilers might complain about extra copies and that you should use `const T&`, but that would not work and there are no extra copies.
## Example
The following is a short, but complete example of how to use aggregates with taoPQ:
```c++
#include <iostream>
#include <tao/pq.hpp>
// an aggregate
struct user
{
std::string name;
unsigned age;
std::string planet;
};
template<>
inline constexpr bool tao::pq::is_aggregate< user > = true;
int main()
{
// open a connection to the database
const auto conn = tao::pq::connection::create( "dbname=template1" );
// execute statements
conn->execute( "DROP TABLE IF EXISTS users" );
conn->execute( "CREATE TABLE users ( name TEXT PRIMARY KEY, age INTEGER NOT NULL, planet TEXT NOT NULL )" );
// prepare statements
conn->prepare( "insert_user", "INSERT INTO users ( name, age, planet ) VALUES ( $1, $2, $3 )" );
// execute previously prepared statements
conn->execute( "insert_user", user{ "R. Daneel Olivaw", 19230, "Earth" } );
conn->execute( "insert_user", user{ "R. Giskard Reventlov", 42, "Aurora" } );
// query and convert data
for( const user u : conn->execute( "SELECT name, age, planet FROM users" ) ) {
std::cout << u.name << " from " << u.planet << " was " << u.age << " years old.\n";
}
}
```
---
This document is part of [taoPQ](https://github.com/taocpp/taopq).
Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch<br>
Distributed under the Boost Software License, Version 1.0<br>
See accompanying file [LICENSE_1_0.txt](../LICENSE_1_0.txt) or copy at https://www.boost.org/LICENSE_1_0.txt
================================================
FILE: doc/Binary-Data.md
================================================
# Binary Data
PostgreSQL stores binary data either as a field with the [`BYTEA`➚](https://www.postgresql.org/docs/current/datatype-binary.html) data type or as a [large object➚](https://www.postgresql.org/docs/current/largeobjects.html).
Large Objects in taoPQ have their own representation discussed in the [Large Object](Large-Object.md) chapter.
## The [`BYTEA`➚](https://www.postgresql.org/docs/current/datatype-binary.html) Data Type
In PostgreSQL strings are a sequence of bytes that is valid in a given encoding.
One or more bytes can represent individual characters or code points.
This means that not all sequences of bytes are a valid string and therefore binary data can generally not be represented by PostgreSQL as a string.
Binary data is different from strings, as binary data is a collection of an arbitrary sequence of bytes.
Any byte is treated independently of its surrounding bytes and can have any value, including '\0'.
It is therefore crucial to represent binary data with the dedicated [`BYTEA`➚](https://www.postgresql.org/docs/current/datatype-binary.html) data type.
## C++ Binary Data
The individual bytes are represented by [`std::byte`➚](https://en.cppreference.com/w/cpp/types/byte).
As there is no one-size-fits-all data type to handle binary data in C++, we allow several options.
We mostly represent binary data with `tao::pq::binary` and `tao::pq::binary_view`.
These are type aliases for [`std::vector<std::byte>`➚](https://en.cppreference.com/w/cpp/container/vector) and [`std::span<std::byte>`➚](https://en.cppreference.com/w/cpp/container/span), respectively.
## Passing Binary Data
When you pass binary data to taoPQ, we only require a view to be passed.
As a view is a non-owning data type, constructing an instance of it is cheap.
If you have other data types, you can create a binary data view by using
```c++
auto tao::pq::to_binary_view( const auto* data, const std::size_t size ) noexcept -> tao::pq::binary_view;
auto tao::pq::to_binary_view( const auto& data ) noexcept
{
return pq::to_binary_view( std::data( data ), std::size( data ) );
}
```
The former function requires (and checks) that `T` has a size of 1 byte.
If you want to store larger `T`s as binary data you need to manually convert the pointer and size appropriately.
The second method requires the data type `T` to be a suitable candidate for [`std::data()`➚](https://en.cppreference.com/w/cpp/iterator/data) and [`std::size()`➚](https://en.cppreference.com/w/cpp/iterator/size), which requires the data to be stored in a contiguous block of memory.
We do not offer any convenience methods to create binary data from distributed data structures, i.e. `std::list<std::byte>` is not supported.
## Receiving Binary Data
When receiving binary data, a non-owning view is insufficient, hence we return `tao::pq::binary`.
In some cases other alternatives are offered, i.e. you may provide a buffer that the data is written to.
---
This document is part of [taoPQ](https://github.com/taocpp/taopq).
Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch<br>
Distributed under the Boost Software License, Version 1.0<br>
See accompanying file [LICENSE_1_0.txt](../LICENSE_1_0.txt) or copy at https://www.boost.org/LICENSE_1_0.txt
================================================
FILE: doc/Bulk-Transfer.md
================================================
# Bulk Transfer
**TODO**
## Synopsis
Don't be intimidated by the size of the API, as you can see several methods are just single-line convenience forwarders.
We will first give the synopsis of everything, afterwards we will break down the API into small logical portions.
```c++
namespace tao::pq
{
namespace internal
{
class zsv; // zero-terminated string view
}
class transaction;
class table_writer final
{
public:
template< typename... As >
table_writer( const std::shared_ptr< transaction >& transaction, const internal::zsv statement, As&&... as );
~table_writer();
table_writer( const table_writer& ) = delete;
table_writer( table_writer&& ) = delete;
void operator=( const table_writer& ) = delete;
void operator=( table_writer&& ) = delete;
void insert_raw( const std::string_view data );
template< typename... As >
void insert( As&&... as );
auto commit() -> std::size_t;
};
using null_t = decltype( null );
class table_row;
class table_field;
class table_reader final
{
private:
class const_iterator;
public:
template< typename... As >
table_reader( const std::shared_ptr< transaction >& transaction, const internal::zsv statement, As&&... as );
~table_reader() = default;
table_reader( const table_reader& ) = delete;
table_reader( table_reader&& ) = delete;
void operator=( const table_reader& ) = delete;
void operator=( table_reader&& ) = delete;
auto columns() const noexcept -> std::size_t;
auto get_raw_data() -> std::string_view;
bool parse_data() noexcept;
bool get_row();
bool has_data() const noexcept;
auto raw_data() const noexcept
-> const std::vector< const char* >&;
auto row() noexcept -> table_row;
auto begin() -> const_iterator;
auto end() noexcept -> const_iterator;
auto cbegin() -> const_iterator;
auto cend() noexcept -> const_iterator;
template< typename T >
auto as_container() -> T;
// convenience conversions to standard containers
template< typename... Ts >
auto vector()
{
return as_container< std::vector< Ts... > >();
}
template< typename... Ts >
auto list()
{
return as_container< std::list< Ts... > >();
}
template< typename... Ts >
auto set()
{
return as_container< std::set< Ts... > >();
}
template< typename... Ts >
auto multiset()
{
return as_container< std::multiset< Ts... > >();
}
template< typename... Ts >
auto unordered_set()
{
return as_container< std::unordered_set< Ts... > >();
}
template< typename... Ts >
auto unordered_multiset()
{
return as_container< std::unordered_multiset< Ts... > >();
}
template< typename... Ts >
auto map()
{
return as_container< std::map< Ts... > >();
}
template< typename... Ts >
auto multimap()
{
return as_container< std::multimap< Ts... > >();
}
template< typename... Ts >
auto unordered_map()
{
return as_container< std::unordered_map< Ts... > >();
}
template< typename... Ts >
auto unordered_multimap()
{
return as_container< std::unordered_multimap< Ts... > >();
}
};
class table_row
{
private:
// satisfies LegacyRandomAccessIterator, see
// https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator
class const_iterator;
public:
auto slice( const std::size_t offset, const std::size_t in_columns ) const -> table_row;
auto columns() const noexcept -> std::size_t;
// iteration
auto begin() const -> const_iterator;
auto end() const -> const_iterator;
auto cbegin() const -> const_iterator;
auto cend() const -> const_iterator;
bool is_null( const std::size_t column ) const;
auto get( const std::size_t column ) const -> const char*;
template< typename T >
auto get( const std::size_t column ) const -> T;
template< typename T >
auto optional( const std::size_t column ) const
{
return get< std::optional< T > >( column );
}
template< typename T >
auto as() const -> T;
template< typename T >
auto optional() const
{
return as< std::optional< T > >();
}
template< typename T, typename U >
auto pair() const
{
return as< std::pair< T, U > >();
}
template< typename... Ts >
auto tuple() const
{
return as< std::tuple< Ts... > >();
}
auto at( const std::size_t column ) const -> table_field;
auto operator[]( const std::size_t column ) const noexcept -> table_field;
friend void swap( table_row& lhs, table_row& rhs ) noexcept;
};
class table_field
{
public:
auto index() const -> std::size_t;
bool is_null() const;
auto get() const -> const char*;
template< typename T >
auto as() const -> T;
template< typename T >
auto optional() const
{
return as< std::optional< T > >();
}
};
bool operator==( const table_field& f, null_t )
{
return f.is_null();
}
bool operator==( null_t, const table_field& f )
{
return f.is_null();
}
bool operator!=( const table_field& f, null_t )
{
return !f.is_null();
}
bool operator!=( null_t, const table_field& f )
{
return !f.is_null();
}
}
```
**TODO**
---
This document is part of [taoPQ](https://github.com/taocpp/taopq).
Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch<br>
Distributed under the Boost Software License, Version 1.0<br>
See accompanying file [LICENSE_1_0.txt](../LICENSE_1_0.txt) or copy at https://www.boost.org/LICENSE_1_0.txt
================================================
FILE: doc/Connection-Pool.md
================================================
# Connection Pool
Opening a new connection to the database server typically consists of several time-consuming steps.
A physical channel such as a socket or a named pipe must be established, the initial handshake with the server must occur, if encryption protocols (SSL) are enabled those need to be established, the connection string information must be parsed, the connection must be authenticated by the server, checks must be run for enlisting in the current transactions, and so on.
In practice, most applications use only one or a few different configurations for connections.
This means that during application execution, many identical connections will be repeatedly opened and closed.
To minimize the cost of opening connections, taoPQ provides connection pools.
Connection pools reduces the number of times that new connections must be opened.
They manage connections by keeping alive a set of active connections and borrowing them to the application on demand.
The connection pool maintains ownership of the connections when they are not used by the application.
## Synopsis
```c++
namespace tao::pq
{
namespace internal
{
class zsv; // zero-terminated string view
}
namespace poll
{
enum class status
{
timeout,
readable,
writable,
again
};
using callback = status( const int socket,
const bool wait_for_write,
const int timeout_ms );
}
class connection;
class connection_pool final
: public std::enable_shared_from_this< connection_pool >
{
public:
// create a new connection pool
static auto create( const std::string& connection_info,
std::function< tao::pq::poll::callback > poll_cb = /*unspecified*/ )
-> std::shared_ptr< connection_pool >;
// non-copyable, non-movable
connection_pool( const connection_pool& ) = delete;
connection_pool( connection_pool&& ) = delete;
void operator=( const connection_pool& ) = delete;
void operator=( connection_pool&& ) = delete;
virtual ~connection_pool() = default;
// timeout handling
auto timeout() const noexcept
-> const std::optional< std::chrono::milliseconds >&;
void set_timeout( const std::chrono::milliseconds timeout );
void reset_timeout() noexcept;
// customizable poll()-callback
auto poll_callback() const noexcept
-> const std::function< tao::pq::poll::callback >&;
void set_poll_callback( std::function< tao::pq::poll::callback > poll_cb ) noexcept;
void reset_poll_callback();
// borrow a connection
auto connection() const noexcept
-> std::shared_ptr< pq::connection >;
// direct statement execution
template< typename... As >
auto execute( const internal::zsv statement, As&&... as )
{
return connection()->execute( statement, std::forward< As >( as )... );
}
// checks whether the pool contains idle connections
auto empty() const noexcept
-> bool;
// number of idle connections
auto size() const noexcept
-> std::size_t;
// number of borrowed connections
auto attached() const noexcept
-> std::size_t;
// cleanup
void erase_invalid();
};
}
```
:point_up: Note that `tao::pq::internal::zsv` is explained in the [Statement](Statement.md) chapter.
## Creating Connection Pools
A connection pool is created by calling `tao::pq::connection_pool`'s static `create()`-method.
```c++
auto tao::pq::connection_pool::create( const std::string& connection_info )
-> std::shared_ptr< tao::pq::connection_pool >;
```
It takes a mandatory parameter, the [connection string➚](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING), that is used when new connections are opened by the pool.
The second, optional parameter can be used to specify the default `poll()`-callback for connections, see [Customizable `poll()`-callback](Connection.md#customizable-poll-callback).
## Borrowing Connections
When you need a connection, you simply call the `connection()`-method.
```c++
auto tao::pq::connection_pool::connection()
-> std::shared_ptr< tao::pq::connection >;
```
This will either open a new connection when the pool is empty, or it will give you a reused connection from the pool.
As long as you retain ownership of the returned shared pointer, it is yours to work with.
When the last remaining shared pointer is destroyed or assigned another value, the connection is returned to the pool.
## Executing Statements
You can [execute statements](Statement.md) on a connection pool directly, which is equivalent to borrowing a temporary connection (as if calling the `connection()`-method) and executing the statement on that [connection](Connection.md).
After the statement was executed, the temporary connection is returned to the pool.
## Cleanup
The connection pool will implicitly discard connections that are in a failed state when they are returned to the pool or when they are retrieved from the pool.
In some environments you might need to periodically clean up the connection pool to get rid of connections that are no longer valid.
In order to do so, just call the `erase_invalid()`-method, which will check the status of each pooled connection and discard the invalid ones.
```c++
void tao::pq::connection_pool::erase_invalid();
```
## Customizable `poll()`-callback
The default implementation for polling uses `poll()` or `WSAPoll()`, depending on your system.
This callback can be customized to support other I/O frameworks, e.g. Boost.Asio.
To access the current default callback for borrowed connections you can call the `poll_callback()`-method.
```c++
auto poll_callback() const noexcept
-> const std::function< tao::pq::poll::callback >&;
```
Setting the default `poll()`-callback for borrowed connections is done by calling the `set_poll_callback()`-method.
```c++
void set_poll_callback( std::function< tao::pq::poll::callback > poll_cb ) noexcept;
```
You can revert the current default `poll()`-callback for borrowed connections to the default by calling the `reset_poll_callback()`-method.
```c++
void reset_poll_callback();
```
## Thread Safety
The connection pool's borrowing mechanism is thread-safe, i.e. multiple threads can make calls to the `connection()`-method or return connections simultaneously.
You can also call the `erase_invalid()`-method at any time.
Internally, the connection pool uses a [mutex➚](https://en.cppreference.com/w/cpp/thread/mutex) to serialize the above operations.
We minimized the work in the [critical sections➚](https://en.wikipedia.org/wiki/Critical_section) as far as possible.
---
This document is part of [taoPQ](https://github.com/taocpp/taopq).
Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch<br>
Distributed under the Boost Software License, Version 1.0<br>
See accompanying file [LICENSE_1_0.txt](../LICENSE_1_0.txt) or copy at https://www.boost.org/LICENSE_1_0.txt
================================================
FILE: doc/Connection.md
================================================
# Connection
All communication with a database server is handled through a connection, represented by the `tao::pq::connection` type in taoPQ.
A connection object takes care of tracking [transactions](Transaction.md), [error handling](Error-Handling.md), and it has its own set of prepared statements.
## Synopsis
```c++
namespace tao::pq
{
namespace internal
{
class zsv; // zero-terminated string view
}
namespace poll
{
enum class status
{
timeout,
readable,
writable,
again
};
using callback = status( const int socket,
const bool wait_for_write,
const int timeout_ms );
}
enum class isolation_level
{
default_isolation_level,
serializable,
repeatable_read,
read_committed,
read_uncommitted
};
enum class access_mode
{
default_access_mode,
read_write,
read_only
};
class notification final
{
public:
auto channel() const noexcept -> const char*;
auto payload() const noexcept -> const char*;
auto underlying_raw_ptr() noexcept -> PGnotify*;
auto underlying_raw_ptr() const noexcept -> const PGnotify*;
};
class transaction;
class connection final
: public std::enable_shared_from_this< connection >
{
public:
// create a new connection
static auto create( const std::string& connection_info,
std::function< tao::pq::poll::callback > poll_cb = /*unspecified*/ )
-> std::shared_ptr< connection >;
// non-copyable, non-movable
connection( const connection& ) = delete;
connection( connection&& ) = delete;
void operator=( const connection& ) = delete;
void operator=( connection&& ) = delete;
~connection() = default;
// query status
bool is_open() const noexcept;
bool is_idle() const noexcept;
// create transactions
auto direct()
-> std::shared_ptr< pq::transaction >;
auto transaction()
-> std::shared_ptr< pq::transaction >;
auto transaction( const access_mode am,
const isolation_level il = isolation_level::default_isolation_level )
-> std::shared_ptr< pq::transaction >;
auto transaction( const isolation_level il,
const access_mode am = access_mode::default_access_mode )
-> std::shared_ptr< pq::transaction >;
// timeout handling
auto timeout() const noexcept
-> const std::optional< std::chrono::milliseconds >&;
void set_timeout( const std::chrono::milliseconds timeout );
void reset_timeout() noexcept;
// prepared statements
void prepare( const std::string& name, const std::string& statement );
void deallocate( const std::string& name );
// direct statement execution
template< typename... As >
auto execute( const internal::zsv statement, As&&... as )
{
return direct()->execute( statement, std::forward< As >( as )... );
}
// listen/notify support
void listen( const std::string_view channel );
void listen( const std::string_view channel, const std::function< void( const char* ) >& handler );
void unlisten( const std::string_view channel );
void notify( const std::string_view channel );
void notify( const std::string_view channel, const std::string_view payload );
auto notification_handler()
-> std::function< void( const notification& ) >;
void set_notification_handler( const std::function< void( const notification& ) >& handler );
void reset_notification_handler() noexcept;
auto notification_handler( const std::string_view channel )
-> std::function< void( const char* ) >;
void set_notification_handler( const std::string_view channel, const std::function< void( const char* ) >& handler );
void reset_notification_handler( const std::string_view channel ) noexcept;
void handle_notifications();
void get_notifications();
// customizable poll()-callback
auto poll_callback() const noexcept
-> const std::function< tao::pq::poll::callback >&;
void set_poll_callback( std::function< tao::pq::poll::callback > poll_cb ) noexcept;
void reset_poll_callback();
// access underlying connection pointer from libpq
auto underlying_raw_ptr() noexcept -> PGconn*;
auto underlying_raw_ptr() const noexcept -> const PGconn*;
// access the socket used by libpq
auto socket() const -> int;
// error message
auto error_message() const -> std::string;
};
}
```
:point_up: Note that `tao::pq::internal::zsv` is explained in the [Statement](Statement.md) chapter.
## Creating a Connection
A connection is created by calling `tao::pq::connection`'s static `create()`-method.
```c++
auto tao::pq::connection::create( const std::string& connection_info,
std::function< tao::pq::poll::callback > poll_cb = /*unspecified*/ )
-> std::shared_ptr< tao::pq::connection >;
```
It takes a mandatory parameter, the [connection string➚](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING), that is passed to the underlying `libpq` for opening the database connection.
The connection string contains parameters and options, such as the server address or the database name.
Connection parameters that are not specified in the connection string might also be set via [environment variables➚](https://www.postgresql.org/docs/current/libpq-envars.html).
The second, optional parameter can be used to specify a `poll()`-callback, see [Customizable `poll()`-callback](#customizable-poll-callback).
The method returns a `std::shared_ptr<tao::pq::connection>` or, in case of an error, throws an exception.
When the last reference to a connection is deleted, i.e. the last shared pointer referencing it is deleted or reset, the connection is closed via its destructor which takes care of freeing underlying resources.
The shared pointer might also be stored internally in other objects of taoPQ, i.e. a transaction.
This ensures, that the connection is kept alive as long as there are dependent objects like an active transaction, see below.
## Creating Transactions
You can create [transactions](Transaction.md) by calling either the `direct()`-method or the `transaction()`-method.
Both methods register the newly created transaction as the active transaction of a connection.
A connection can only have one active transaction at any given time.
Further details on how to use transactions are discussed in the [Transaction](Transaction.md) chapter.
### Creating a "Direct" Transaction
The `direct()`-method creates an auto-commit transaction proxy, i.e. all statements executed on this transaction are immediately committed to the database.
```c++
auto tao::pq::connection::direct()
-> std::shared_ptr< tao::pq::transaction >;
```
:point_up: This is not a real transaction from the database's point of view, therefore calling the `commit()`- or `rollback()`-method on the transaction has no immediate effect on the database.
However, calling either the `commit()`- or `rollback()`-method will end the transaction's logical lifetime and it will unregister itself from the connection.
### Creating a Database Transaction
The `transaction()`-method begins a real [database transaction➚](https://www.postgresql.org/docs/current/tutorial-transactions.html).
```c++
auto tao::pq::connection::transaction()
-> std::shared_ptr< tao::pq::transaction >;
auto tao::pq::connection::transaction( const tao::pq::isolation_level il,
const tao::pq::access_mode am = tao::pq::access_mode::default_access_mode )
-> std::shared_ptr< tao::pq::transaction >;
auto tao::pq::connection::transaction( const tao::pq::access_mode am,
const tao::pq::isolation_level il = tao::pq::isolation_level::default_isolation_level )
-> std::shared_ptr< tao::pq::transaction >;
```
You may specify two optional parameters, the [isolation level➚](https://www.postgresql.org/docs/current/transaction-iso.html) and the [access mode➚](https://www.postgresql.org/docs/current/sql-set-transaction.html).
When `tao::pq::isolation_level::default_isolation_level` or `tao::pq::access_mode::default_access_mode` are used the transaction inherits its isolation level or access mode from the session, as described in the [PostgreSQL documentation➚](https://www.postgresql.org/docs/current/sql-set-transaction.html).
## Executing Statements
You can [execute statements](Statement.md) on a connection object directly, which is equivalent to creating a temporary direct transaction (as if calling the `direct()`-method) and executing the statement on that [transaction](Transaction.md).
## Prepared Statements
Prepared statements only last for the duration of a connection, and are bound to a connection, i.e. the set of prepared statements is independent for each connection.
You can [prepare➚](https://www.postgresql.org/docs/current/sql-prepare.html) a statement by calling the `prepare()`-method.
```c++
void tao::pq::connection::prepare( const std::string& name, const std::string& statement );
```
It takes two parameters, the name of the prepared statement and the SQL statement itself.
taoPQ limits the name to classic C-style identifiers, i.e. a non-empty sequence of digits, underscores, and lowercase and uppercase Latin letters.
A valid identifier must begin with a non-digit character.
Identifiers are case-sensitive (lowercase and uppercase letters are distinct).
A previously prepared statement can be [deallocated➚](https://www.postgresql.org/docs/current/sql-deallocate.html), although this is rare in pratice.
To deallocate a prepared statement, call the `deallocate()`-method.
```c++
void tao::pq::connection::deallocate( const std::string& name );
```
Using the `prepare()`- and `deallocate()`-methods makes taoPQ's connection object aware of the names of the prepared statements.
This allows the [execution](Statement.md) of those prepared statements transparently via an `execute()`-method.
### Manually Prepared Statements
You can manually prepare statements by executing [`PREPARE`➚](https://www.postgresql.org/docs/current/sql-prepare.html) statements directly via an `execute()`-method.
While those prepared statements live on the same connection, there are some important differences.
You can only execute those prepared statements by executing [`EXECUTE`➚](https://www.postgresql.org/docs/current/sql-execute.html) statements directly via an `execute()`-method, and you can only deallocate them by executing [`DEALLOCATE`➚](https://www.postgresql.org/docs/current/sql-deallocate.html) statements directly via an `execute()`-method.
:point_up: We advise to use the methods offered by taoPQ's connection type.
## Checking Status
You can check a connection's status by calling the `is_open()`- or `is_idle()`-methods.
```c++
bool tao::pq::connection::is_open() const noexcept;
bool tao::pq::connection::is_idle() const noexcept;
```
The first method returns `true` when the connection is still open and usable, and `false` otherwise, i.e. if the connection is in a failed state.
For further details, check the documentation for the underlying [`PQstatus()`➚](https://www.postgresql.org/docs/current/libpq-status.html)-function provided by `libpq`.
The second method returns `true` when the connection is open and is in the idle state, and `false` otherwise.
For further details, check the documentation for the underlying [`PQtransactionStatus()`➚](https://www.postgresql.org/docs/current/libpq-status.html)-function provided by `libpq`.
## Notification Framework
PostgreSQL provides a simple [interprocess communication mechanism➚](https://www.postgresql.org/docs/current/sql-notify.html) for a collection of applications accessing the same database.
### Sending Messages
You can send events with the `notify()`-method, providing a channel name and optionally a payload as the second parameter.
```c++
void tao::pq::connection::notify( const std::string_view channel );
void tao::pq::connection::notify( const std::string_view channel, const std::string_view payload );
```
:point_up: The channel name is case sensitive when using taoPQ's methods.
### Receiving Messages
You can subscribe to channels to receive messages using the `listen()`-method, or unsubscribe by calling the `unlisten()`-method.
```c++
void tao::pq::connection::listen( const std::string_view channel );
void tao::pq::connection::unlisten( const std::string_view channel );
```
Note that subscriptions are per connection.
### Handling Messages
Processing received messages requires you to register a notification handler.
Each connection has its own notification handler.
The notification handler is managed by a `std::function< void( const tao::pq::notification& >` object.
The currently active notification handler is returned by the `notification_handler()`-method.
```c++
auto tao::pq::connection::notification_handler()
-> std::function< void( const tao::pq::notification& ) >;
```
If no notification handler is set, the [`std::function`➚](https://en.cppreference.com/w/cpp/utility/functional/function) will be empty.
Setting a notification handler is done by calling the `set_notification_handler()`-method.
```c++
void tao::pq::connection::set_notification_handler( const std::function< void( const tao::pq::notification& ) >& handler );
```
If you want to deregister the current notification handler, you can call the `reset_notification_handler()`-method.
```c++
void tao::pq::connection::reset_notification_handler() noexcept;
```
### Per Channel Handlers
Besides the above general notification handler, there is also the option to register a per channel handler.
Per channel handlers only receive the payload as a parameter.
```c++
auto tao::pq::connection::notification_handler( const std::string_view channel )
-> std::function< void( const char* ) >;
void tao::pq::connection::set_notification_handler( const std::string_view channel,
const std::function< void( const char* ) >& handler );
void tao::pq::connection::reset_notification_handler( const std::string_view channel ) noexcept;
```
When you subscribe to a channel with the `listen()`-method, you can optionally register a channel handler.
```c++
void tao::pq::connection::listen( const std::string_view channel,
const std::function< void( const char* ) >& handler );
```
This registers the handler first by calling `set_notification_handler( channel, handler )`, then calls `listen( channel )`.
### Asynchronous Notifications
taoPQ calls the registered notification handler(s) after successful execution by calling the `handle_notifications()`-method.
As a user, you rarely need to call the `handle_notifications()`-method manually.
```c++
void tao::pq::connection::handle_notifications();
```
When you don't have any statement to execute, you can call the `get_notifications()`-method which will actively query the server for new events.
```c++
void tao::pq::connection::get_notifications();
```
### Event Loop
**TODO** Support event loops? How?
## Customizable `poll()`-callback
The default implementation for polling uses `poll()` or `WSAPoll()`, depending on your system.
This callback can be customized to support other I/O frameworks, e.g. Boost.Asio.
To access the currently active callback you can call the `poll_callback()`-method.
```c++
auto poll_callback() const noexcept
-> const std::function< tao::pq::poll::callback >&;
```
Setting the `poll()`-callback is done by calling the `set_poll_callback()`-method.
```c++
void set_poll_callback( std::function< tao::pq::poll::callback > poll_cb ) noexcept;
```
You can revert the current `poll()`-callback to the default by calling the `reset_poll_callback()`-method.
```c++
void reset_poll_callback();
```
## Underlying Connection Pointer
If you need to access the underlying raw connection pointer from `libpq`, you can call the `underlying_raw_ptr()`-method.
```c++
auto tao::pq::connection::underlying_raw_ptr() noexcept -> PGconn*;
auto tao::pq::connection::underlying_raw_ptr() const noexcept -> const PGconn*;
```
## Error Messages
You can retrieve the last error message (if applicable) by calling the `error_message()`-method.
```c++
auto tao::pq::connection::error_message() const -> std::string;
```
When taoPQ throws an exception this is usually done internally and the message is part of the exception's `what()` message.
---
This document is part of [taoPQ](https://github.com/taocpp/taopq).
Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch<br>
Distributed under the Boost Software License, Version 1.0<br>
See accompanying file [LICENSE_1_0.txt](../LICENSE_1_0.txt) or copy at https://www.boost.org/LICENSE_1_0.txt
================================================
FILE: doc/Error-Handling.md
================================================
# Error Handling
## SQL errors
When an SQL statement is [executed](Statement.md) and the execution fails, an exception is thrown.
The base class for the exceptions thrown in this case is `tao::pq::sql_error`, which is derived from `tao::pq::error`, which in turn is derived from [`std::runtime_error`➚](https://en.cppreference.com/w/cpp/error/runtime_error).
```c++
namespace tao::pq
{
struct error
: std::runtime_error
{
using std::runtime_error::runtime_error;
};
struct sql_error
: error
{
std::string sqlstate;
// ctor...
};
}
```
The exception's `what()`-method will return the error message returned from the server.
## SQLSTATE
Depending on the [SQLSTATE➚](https://en.wikipedia.org/wiki/SQLSTATE) returned from the server as documented in [Appendix A➚](https://www.postgresql.org/docs/current/errcodes-appendix.html) of the PostgreSQL documentation, we throw an accordingly named exception class.
### Class of Error
The first two characters of the error code denote the class of errors, while the last three characters indicate a specific condition within that class.
Thus, an application that does not recognize the specific error code might still be able to infer what to do from the error class.
For each class of errors, there is an exception class derived from `tao::pq::sql_error`.
As an example, if the class is "02" ("no data"), the exception class that is thrown is either derived from `tao::pq::no_data` if a more specific error condition is recognized, or `tao::pq::no_data` itself will be the exception class that is thrown if only the class itself is recognized by taoPQ.
### Specific Error Conditions
If a specific error condition is recognized, an exception named after [Appendix A➚](https://www.postgresql.org/docs/current/errcodes-appendix.html) will be thrown, derived from the exception class of the class of error.
There are some cases in which the name can not be simply taken from that table, as they are used multiple times in different classes of errors.
In those cases the exception class is a class template and you need to add the class of error as a template parameter.
Specifically, this is necessary to distinguish the following exceptions:
* `tao::pq::string_data_right_truncation< tao::pq::warning >` (SQLSTATE "01004")
* `tao::pq::string_data_right_truncation< tao::pq::data_exception >` (SQLSTATE "22001")
and these exceptions from class "sql routine exception":
* `tao::pq::modifying_sql_data_not_permitted< tao::pq::sql_routine_exception >` (SQLSTATE "2F002")
* `tao::pq::prohibited_sql_statement_attempted< tao::pq::sql_routine_exception >` (SQLSTATE "2F003")
* `tao::pq::reading_sql_data_not_permitted< tao::pq::sql_routine_exception >` (SQLSTATE "2F004")
vs these exceptions from class "external routine exception":
* `tao::pq::modifying_sql_data_not_permitted< tao::pq::external_routine_exception >` (SQLSTATE "38002")
* `tao::pq::prohibited_sql_statement_attempted< tao::pq::external_routine_exception >` (SQLSTATE "38003")
* `tao::pq::reading_sql_data_not_permitted< tao::pq::external_routine_exception >` (SQLSTATE "38004")
## Connection Errors
PostgreSQL only delivers an SQLSTATE when a statement is executed.
In other situations, e.g. when opening a connection fails, no SQLSTATE is available.
We throw an exception of type `tao::pq::connection_error` in that case, with a dummy SQLSTATE of "08000".
The same exception can also be thrown when calling the connection's `get_notifications()`-method when the connection is broken.
## Other Exceptions
**TODO**
---
This document is part of [taoPQ](https://github.com/taocpp/taopq).
Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch<br>
Distributed under the Boost Software License, Version 1.0<br>
See accompanying file [LICENSE_1_0.txt](../LICENSE_1_0.txt) or copy at https://www.boost.org/LICENSE_1_0.txt
================================================
FILE: doc/Getting-Started.md
================================================
# Getting Started
Before we start with taoPQ, we'd like to point you to the excellent [PostgreSQL documentation➚](https://www.postgresql.org/docs/current/index.html).
We will assume that you are familiar with PostgreSQL and SQL in general, so we will *not* explain what a certain SQL statement does in the database.
Getting started with taoPQ is really simple, a minimalistic program looks as follows:
```c++
#include <iostream>
#include <string>
#include <tao/pq.hpp>
int main()
{
const auto connection = tao::pq::connection::create( "dbname=template1" );
const auto result = connection->execute( "SELECT version()" );
std::cout << result.as< std::string >() << std::endl;
return 0;
}
```
Let's go through the above code and explain some basic principles, slowly expanding our knowledge of taoPQ.
To use taoPQ, you include the top-level header with `#include <tao/pq.hpp>`.
The individual include files in `tao/pq/` are not meant to be included directly.
Starting with `tao::pq::connection::create("dbname=template1")`, we can see that the `tao::pq::connection` class has a static `create()`-method.
You provide a single parameter, the [connection string➚](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING), and the method then returns a `std::shared_ptr<tao::pq::connection>` that holds the connection object it opened.
The reason why connections (and several other objects in taoPQ) are handled via smart pointers will be explained later.
Note that you can use `auto` as shown above to simplify your code.
A connection has an `execute()`-method which can be used to run SQL statements.
The `execute()`-method returns a result object directly, meaning `tao::pq::result` objects are not handled via smart pointers.
As the statement we just executed was a `SELECT` statement, the result contains a set of rows containing the data returned from the `SELECT` statement.
The above shows a simple way of converting a result set that contains only a single row with a single column into a C++ `std::string`.
Of course there are other, more sophisticated ways to retrieve and convert result data when you received multiple rows with multiple columns, those will be shown later.
Congratulations, you now can write simple programs with taoPQ.
## Next Steps
The following chapters are good next steps to get to know taoPQ:
* The [Connection](Connection.md) chapter goes into more details on the methods offered by `tao::pq::connection`, introduces transactions, and explains why some objects in taoPQ are handled via smart pointers.
* The [Transaction](Transaction.md) chapter explains in more detail how taoPQ handles transactions, makes sure that you don't mess up the transaction ordering and nesting, and which transaction types are supported.
* The [Statement](Statement.md) chapter gives more information on how to send statements and parameters.
* The [Result](Result.md) chapter explains what types of results exist, how you can access the data they contain, and how to convert results into C++ types, including containers.
* The [Installation](Installation.md) chapter explains how to install taoPQ.
* The [Requirements](Requirements.md) chapter lists our requirements and assumptions about the used server and protocol versions, encoding support, etc.
## Advanced Topics
* The [Error Handling](Error-Handling.md) chapter gives some general hints as to how we manage error scenarios and how those are communicated to the application.
* The [Parameter Type Conversion](Parameter-Type-Conversion.md) chapter explains what C++ data types can be used as parameters when executing SQL statements, how NULL values are mapped to C++ data types, and how you can extend the supported types by registering your own types.
* The [Result Type Conversion](Result-Type-Conversion.md) chapter explains what C++ data types can be extracted from results, how you can extend the supported types by registering your own types, and how to use `tao::pq::result`'s API elegantly and efficiently.
* The [Binary Data](Binary-Data.md) chapter explains the support for PostgreSQL's [`BYTEA`➚](https://www.postgresql.org/docs/current/datatype-binary.html) data type in taoPQ and some design decisions regarding the C++ interface.
* The [Connection Pool](Connection-Pool.md) chapter explains how a connection pool might help your application, especially when you use multi-threading. Our connection pool offers some novel features that ease the handling of borrowed connections significantly.
* The [Bulk Transfer](Bulk-Transfer.md) chapter explains how we support high-speed [bulk data transfer➚](https://www.postgresql.org/docs/current/sql-copy.html) to or from the server.
* The [Large Object](Large-Object.md) chapter provides access to PostgreSQL's [large object➚](https://www.postgresql.org/docs/current/largeobjects.html) facility.
* The [Performance](Performance.md) chapter gives hints on how to improve your application's performance, as well as explaining some gotchas you might encounter when using taoPQ.
---
This document is part of [taoPQ](https://github.com/taocpp/taopq).
Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch<br>
Distributed under the Boost Software License, Version 1.0<br>
See accompanying file [LICENSE_1_0.txt](../LICENSE_1_0.txt) or copy at https://www.boost.org/LICENSE_1_0.txt
================================================
FILE: doc/Installation.md
================================================
# Installation
## Using CMake
Since CMake 3.11, the feature [FetchContent➚](https://cmake.org/cmake/help/latest/module/FetchContent.html) can be used to download and build project dependencies.
This mechanism makes our development much easier, but it lacks in terms of reproducibility, so be careful if you are using it for production. Also, we will use `FetchContent_MakeAvailable` which is available since CMake 3.14:
```cmake
cmake_minimum_required(VERSION 3.14)
project(example CXX)
include(FetchContent)
find_package(PostgreSQL REQUIRED)
FetchContent_Declare(
taocpp-taopq
GIT_REPOSITORY https://github.com/taocpp/taopq
GIT_TAG main
)
FetchContent_MakeAvailable(taocpp-taopq)
add_library(example main.cpp)
target_link_libraries(example taocpp::taopq)
set_property(TARGET example PROPERTY CXX_STANDARD 20)
```
Now, we just need to execute CMake as usual:
```sh
cmake .
cmake --build .
```
The CMake client will download taoPQ source files based on the `main` branch, but is highly recommended using a commit or tag to keep the reproducibility.
Besides that, PostgreSQL (libpq) is a pre-requirement. You can extend the `CMakeLists.txt` to download and build libpq too, or just consume from your system.
When executing the build step, taoPQ will be built first, as its target is required by our application, after that, the example application will be built and linked to both libpq and taoPQ.
---
## Using Conan
You can install pre-built binaries for taoPQ or build it from source using [Conan](https://conan.io/). Use the following command:
```bash
conan install --requires="taocpp-taopq/[*]" --build=missing
```
The taoPQ Conan recipe is kept up to date by Conan maintainers and community contributors.
If the version is out of date, please [create an issue or pull request](https://github.com/conan-io/conan-center-index) on the ConanCenterIndex repository.
This document is part of [taoPQ](https://github.com/taocpp/taopq).
Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch<br>
Distributed under the Boost Software License, Version 1.0<br>
See accompanying file [LICENSE_1_0.txt](../LICENSE_1_0.txt) or copy at https://www.boost.org/LICENSE_1_0.txt
================================================
FILE: doc/Large-Object.md
================================================
# Large Object
PostgreSQL has a [large object➚](https://www.postgresql.org/docs/current/largeobjects.html) facility, which provides stream-style access to user data that is stored in a special large-object structure.
Streaming access is useful when working with data values that are too large to manipulate conveniently as a whole.
## Synopsis
```c++
namespace tao::pq
{
enum class oid : Oid // Oid defined by libpq
{
invalid = InvalidOid, // InvalidOid defined by libpq
// undisclosed additional values
};
class transaction;
class large_object final
{
public:
static auto create( const std::shared_ptr< transaction >& transaction,
const oid desired_id = oid::invalid ) -> oid;
static void remove( const std::shared_ptr< transaction >& transaction,
const oid id );
static auto import_file( const std::shared_ptr< transaction >& transaction,
const char* filename,
const oid desired_id = oid::invalid ) -> oid;
static void export_file( const std::shared_ptr< transaction >& transaction,
const oid id,
const char* filename );
large_object( const std::shared_ptr< transaction >& transaction,
const oid id,
const std::ios_base::openmode m );
large_object( const large_object& ) = delete;
large_object( large_object&& other ) noexcept;
~large_object();
void operator=( const large_object& ) = delete;
auto operator=( large_object&& rhs ) -> large_object&;
void close();
auto read( char* data, const std::size_t size ) -> std::size_t;
auto read( std::byte* data, const std::size_t size ) -> std::size_t;
void write( const char* data, const std::size_t size );
void write( const std::byte* data, const std::size_t size );
void write( const char* data );
template< typename T = binary >
auto read( const std::size_t size ) -> T;
template< typename... Ts >
void write( Ts&&... ts );
void resize( const std::int64_t size );
auto seek( const std::int64_t offset, const std::ios_base::seekdir whence ) -> std::int64_t;
auto tell() const -> std::int64_t;
};
}
```
:point_up: All large object manipulation using these functions must take place within an SQL transaction block, since large object file descriptors are only valid for the duration of a transaction.
## Creating a Large Object
To [create➚](https://www.postgresql.org/docs/current/lo-interfaces.html#LO-CREATE) a new large object, call
```c++
static auto tao::pq::large_object::create( const std::shared_ptr<tao::pq::transaction>& transaction,
const tao::pq::oid desired_id = tao::pq::oid::invalid ) -> tao::pq::oid;
```
If no desired oid is given, the server will return the oid that was assigned to the new large object.
If you specify a desired oid and that oid is already used, or if any other error occurs, an exception will be thrown.
## Removing a Large Object
To [remove➚](https://www.postgresql.org/docs/current/lo-interfaces.html#LO-UNLINK) a large object from the database, call
```c++
static void tao::pq::large_object::remove( const std::shared_ptr<tao::pq::transaction>& transaction, const tao::pq::oid id );
```
## Importing a Large Object
To [import➚](https://www.postgresql.org/docs/current/lo-interfaces.html#LO-IMPORT) an operating system file as a large object, call
```c++
static auto tao::pq::large_object::import_file( const std::shared_ptr<tao::pq::transaction>& transaction,
const char* filename,
const tao::pq::oid desired_id = tao::pq::oid::invalid ) -> tao::pq::oid;
```
If no desired oid is given, the server will return the oid that was assigned to the new large object.
If you specify a desired oid and that oid is already used, or if any other error occurs, an exception will be thrown.
## Exporting a Large Object
To [export➚](https://www.postgresql.org/docs/current/lo-interfaces.html#LO-EXPORT) a large object into an operating system file, call
```c++
static void tao::pq::large_object::export_file( const std::shared_ptr<tao::pq::transaction>& transaction,
const tao::pq::oid id,
const char* filename );
```
If an error occurs an exception will be thrown.
## Opening an Existing Large Object
To [open➚](https://www.postgresql.org/docs/current/lo-interfaces.html#LO-OPEN) an existing large object for reading or writing, call
```c++
tao::pq::large_object::large_object( const std::shared_ptr<tao::pq::transaction>& transaction,
const tao::pq::oid id,
const std::ios_base::openmode m );
```
The mode `m` bits control whether the object is opened for reading (`std::ios_base::in`), writing (`std::ios_base::out`), or both.
If an error occurs an exception will be thrown.
The destructor will take care of [closing➚](https://www.postgresql.org/docs/current/lo-interfaces.html#LO-CLOSE) the large object descriptor.
## Writing Data to a Large Object
To [write➚](https://www.postgresql.org/docs/current/lo-interfaces.html#LO-WRITE) data to a large object, several methods are available.
```c++
void tao::pq::large_object::write( const char* data, const std::size_t size );
void tao::pq::large_object::write( const std::byte* data, const std::size_t size );
void tao::pq::large_object::write( const char* data );
template< typename... Ts >
void tao::pq::large_object::write( Ts&&... ts );
```
The first three methods write a chunk of data starting at `data` that is `size` bytes long to the large object.
The fourth method expects a zero-terminated string, which will be written to the large object.
The fifth method template forwards its arguments to a call to [`tao::pq::to_binary_view()`](Binary-Data.md), then writes the binary data to the large object.
This allows all data types that are accepted by `tao::pq::to_binary_view()` to be written seamlessly into large objects.
If an error occurs an exception will be thrown.
## Reading Data from a Large Object
To [read➚](https://www.postgresql.org/docs/current/lo-interfaces.html#LO-READ) data from a large object, several methods are available.
```c++
auto tao::pq::large_object::read( char* data, const std::size_t size ) -> std::size_t;
auto tao::pq::large_object::read( std::byte* data, const std::size_t size ) -> std::size_t;
template< typename T = tao::pq::binary >
auto tao::pq::large_object::read( const std::size_t size ) -> T;
```
The first three methods read up to `size` bytes from the large object into `data`.
The methods will return the number of bytes actually read; this will be less than `size` if the end of the large object is reached first.
The fourth method will create a new object of type `T` and read up to `size` bytes from the large object.
`T` must be one of the following types:
* `std::string`
* [`tao::pq::binary`](Binary-Data.md) aka `std::vector<std::byte>`
:point_up: Although the `size` parameter of the above methods is declared as `std::size_t`, the methods will reject values larger than `INT_MAX`.
In practice, it's best to transfer data in chunks of at most a few megabytes anyway.
If an error occurs an exception will be thrown.
## Seeking in a Large Object
To change the [current read or write➚](https://www.postgresql.org/docs/current/lo-interfaces.html#LO-SEEK) location associated with a large object, call
```c++
auto tao::pq::large_object::seek( const std::int64_t offset, const std::ios_base::seekdir whence ) -> std::int64_t;
```
This method moves the current location pointer for the large object to the new location specified by `offset`.
The valid values for `whence` are `std::ios_base::beg` (seek from object start), `std::ios_base::cur` (seek from current position), and `std::ios_base::end` (seek from object end).
The return value is the new location pointer.
If an error occurs an exception will be thrown.
## Obtaining the Seek Position of a Large Object
To [obtain➚](https://www.postgresql.org/docs/current/lo-interfaces.html#LO-TELL) the current read or write location of a large object, call
```c++
auto tao::pq::large_object::tell() const -> std::int64_t;
```
If an error occurs an exception will be thrown.
## Truncating a Large Object
To [truncate➚](https://www.postgresql.org/docs/current/lo-interfaces.html#LO-TRUNCATE) a large object to a given size, call
```c++
void tao::pq::large_object::resize( const std::int64_t size );
```
If `size` is greater than the large object's current length, the large object is extended to the specified length with null bytes ('\0').
If an error occurs an exception will be thrown.
---
This document is part of [taoPQ](https://github.com/taocpp/taopq).
Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch<br>
Distributed under the Boost Software License, Version 1.0<br>
See accompanying file [LICENSE_1_0.txt](../LICENSE_1_0.txt) or copy at https://www.boost.org/LICENSE_1_0.txt
================================================
FILE: doc/Parameter-Type-Conversion.md
================================================
# Parameter Type Conversion
When [executing statements](Statement.md), you can pass any number of parameters after the statement itself to the `execute()`-method.
Each parameter then gets converted through the parameter traits class template into one or more positional parameters for the SQL statement.
By default, the following C++ types are available for use as parameters.
## NULL
If you want to pass NULL to the database, you pass `tao::pq::null`.
## Fundamental Types
* Booleans
* `bool`
* Character
* `char`
* Integral Types
* `signed char` (8-bit signed integer)
* `unsigned char` (8-bit unsigned integer)
* `short`
* `unsigned short`
* `int`
* `unsigned int`
* `long`
* `unsigned long`
* `long long`
* `unsigned long long`
* Floating Point Types
* `float`
* `double`
* `long double`
* Strings
* `const char*`
* `std::string`
* `std::string_view`
* [Binary](Binary-Data.md) ([`BYTEA`➚](https://www.postgresql.org/docs/current/datatype-binary.html))
* `std::vector< std::byte >`
* `std::span< std::byte >`
* [`ARRAY`➚](https://www.postgresql.org/docs/current/arrays.html)
* `std::array< T, N >`
* `std::list< T >`
* `std::set< T >`
* `std::unordered_set< T >`
* `std::vector< T >`
## `std::optional< T >`
Represents a [nullable➚](https://en.wikipedia.org/wiki/Nullable_type) type.
If the optional is not empty, then the parameters from `T` are generated.
If the optional is empty, it is equivalent to one or more `tao::pq::null` parameter(s).
The number of NULL values generated depends on the number of parameters that `T` would generate.
## `std::pair< T, U >`
Generates all parameters from `T`, then all parameters from `U`, in that order.
Note that this generates at least two parameters, possibly more.
Pairs can be nested, e.g. `std::pair<std::pair<int,int>,int>` would generate three parameters.
## `std::tuple< Ts... >`
As a generalisation of pairs, tuples generate all parameters for their individual elements, in order.
## Aggregates
Any suitable aggregate data type can be used as a parameter when registered with taoPQ.
```c++
struct my_aggregate
{
std::string name;
unsigned age;
std::string address;
bool is_pet_owner;
};
template<>
inline constexpr bool tao::pq::is_aggregate< my_aggregate > = true;
```
See [Aggregate Support](Aggregate.md) for more information.
## Custom Data Types
Custom data types can be registered in two different ways, by using a `to_taopq()` function or method, or by specializing the `tao::pq::parameter_traits` class template.
### `to_taopq()`
You can use a function or method called `to_taopq()`, any value returned will then be fed into the parameters as outlined above.
Usually, that means a simple conversion will return a single known type, more complicated types return a `std::tuple` to return multiple parameters for the SQL statement.
There are multiple places where this function or method can be placed.
#### Intrusive Placement
If you have control over a class type, you can add a method called `to_taopq()` that can be called with no parameters.
The method can be marked `const` and/or `noexcept` as applicable.
```c++
class my_int_wrapper
{
private:
int value;
public:
explicit my_int_wrapper( int v ) : value( v ) {}
auto to_taopq() const noexcept
{
return value;
}
};
```
You can now pass values of type `my_int_wrapper` as parameters to call taoPQ's `execute()`-methods.
If your class has more members, you can return multiple values:
```c++
class my_coordinates
{
private:
double x,y,z;
public:
// ctors, etc.
auto to_taopq() const noexcept
{
return std::tie( x, y, z );
}
};
```
The above means that each time you pass a `my_coordinates` instance as a parameter to an `execute()`-method, three positional parameters are added and can be referenced from the SQL statement.
#### Non-Intrusive Placement
If you can't modify the class you could specialize `tao::pq::bind<...>` and place a static `to_taopq()`-method inside the specialization, or provide a free function called `to_taopq()` instead.
Those functions must accept a single parameter of the class you want to register.
Example for the specialization of `tao::pq::bind<...>`:
```c++
struct some_coordinates
{
double x,y,z;
};
template<>
struct tao::pq::bind< some_coordinates >
{
static auto to_taopq( const some_coordinates& v ) noexcept
{
return std::tie( v.x, v.y, v.z );
}
};
```
Example for the free function:
```c++
struct some_coordinates
{
double x,y,z;
};
auto to_taopq( const some_coordinates& v ) noexcept
{
return std::tie( v.x, v.y, v.z );
}
```
The free function is found either by [ADL➚](https://en.cppreference.com/w/cpp/language/adl) or in namespace `tao::pq`.
:point_up: Note that any returned value in the above examples can itself be a registered custom type.
taoPQ will simply expand parameters recursively.
### `tao::pq::parameter_traits< T >`
If the above custom data type registration via `to_taopq()` is somehow not sufficient, you can specialize the `tao::pq::parameter_traits` class template.
For now please consult the source code or ask the developers.
TODO: Write proper documentation.
---
This document is part of [taoPQ](https://github.com/taocpp/taopq).
Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch<br>
Distributed under the Boost Software License, Version 1.0<br>
See accompanying file [LICENSE_1_0.txt](../LICENSE_1_0.txt) or copy at https://www.boost.org/LICENSE_1_0.txt
================================================
FILE: doc/Performance.md
================================================
# Performance
**TODO**
---
This document is part of [taoPQ](https://github.com/taocpp/taopq).
Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch<br>
Distributed under the Boost Software License, Version 1.0<br>
See accompanying file [LICENSE_1_0.txt](../LICENSE_1_0.txt) or copy at https://www.boost.org/LICENSE_1_0.txt
================================================
FILE: doc/Requirements.md
================================================
# Requirements
## Operating System Support
* We support:
* [Windows➚](https://en.wikipedia.org/wiki/Microsoft_Windows).
* [macOS➚](https://en.wikipedia.org/wiki/MacOS).
* [Linux➚](https://en.wikipedia.org/wiki/Linux).
* Other systems might work.
## Compiler Support
* We support:
* [Visual Studio➚](https://en.wikipedia.org/wiki/Microsoft_Visual_Studio) version 2022 or newer.
* [Xcode➚](https://en.wikipedia.org/wiki/Xcode) version 15 or newer.
* [GCC➚](https://gcc.gnu.org/) version 13 or newer.
* [Clang➚](https://clang.llvm.org/) version 16 or newer.
* Other compilers might work.
## Language Requirements
* We require [C++20➚](https://en.wikipedia.org/wiki/C%2B%2B20) or newer.
* We require exception support. The `-fno-exceptions` option is not supported.
* We require RTTI support. The `-fno-rtti` option is not supported.
## Compiler Options/Warnings
* We support Clang's [`-fms-extensions`➚](https://clang.llvm.org/docs/MSVCCompatibility.html) option.
* We support the `/W4` option on [Visual Studio➚](https://docs.microsoft.com/en-us/cpp/build/reference/compiler-option-warning-level).
* We support the `-pedantic`, `-Wall`, and `-Wextra` options on [GCC➚](https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html) and [Clang➚](https://clang.llvm.org/docs/DiagnosticsReference.html).
:point_up: Note that we *support* these options, we don't *require* them to be used.
You can decide which options you want to use in your project, we just try to not get in the way by making sure that our code doesn't generate any of those warnings.
## Database Requirements
* We expect the database to use UTF-8 encoding.
* We expect the database to send `BYTEA` data in [`bytea` hex format➚](https://www.postgresql.org/docs/current/datatype-binary.html).
* We expect the database connection to use [protocol version 3➚](https://www.postgresql.org/docs/current/protocol.html).
---
This document is part of [taoPQ](https://github.com/taocpp/taopq).
Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch<br>
Distributed under the Boost Software License, Version 1.0<br>
See accompanying file [LICENSE_1_0.txt](../LICENSE_1_0.txt) or copy at https://www.boost.org/LICENSE_1_0.txt
================================================
FILE: doc/Result-Type-Conversion.md
================================================
# Result Type Conversion
Depending on what type of [statement](Statement.md) was executed, you receive a [result](Result.md) containing a query result set.
Those results then offer conversions to C++ data types through various methods, e.g. `tao::pq::row::as<T>()`.
This chapter discusses the data types that are available by default and how to register your own custom data types when needed.
## Fundamental Types
By default, the following C++ types are available for use as result types.
* Booleans
* `bool`
* Character
* `char`
* Integral Types
* `signed char` (8-bit signed integer)
* `unsigned char` (8-bit unsigned integer)
* `short`
* `unsigned short`
* `int`
* `unsigned int`
* `long`
* `unsigned long`
* `long long`
* `unsigned long long`
* Floating Point Types
* `float`
* `double`
* `long double`
* Strings
* `const char*`
* `std::string`
* `std::string_view`
* [Binary](Binary-Data.md) ([`BYTEA`➚](https://www.postgresql.org/docs/current/datatype-binary.html))
* `std::vector< std::byte >`
* [`ARRAY`➚](https://www.postgresql.org/docs/current/arrays.html)
* `std::list< T >`
* `std::set< T >`
* `std::unordered_set< T >`
* `std::vector< T >`
## `std::optional< T >`
Represents a [nullable➚](https://en.wikipedia.org/wiki/Nullable_type) type.
If the result field is NULL, an empty optional is returned.
If the result field is not NULL, the value is converted to `T` and returned in the optional.
## `std::pair< T, U >`
Returns a `std::pair< T, U >`, hence convertes two (or more) neighboring fields from the result's row.
It can read more than two fields when `T` or `U` themselves read more than one field, i.e. converting to `std::pair<int,std::pair<int,int>>` will read three fields from the result's row.
## `std::tuple< Ts... >`
As a generalisation of pairs, tuples read all fields for their individual elements, in order.
## Aggregates
Any suitable aggregate data type can be used as a result type when registered with taoPQ.
```c++
struct my_aggregate
{
std::string name;
unsigned age;
std::string address;
bool is_pet_owner;
};
template<>
inline constexpr bool tao::pq::is_aggregate< my_aggregate > = true;
```
See [Aggregate Support](Aggregate-Support.md) for more information.
## Custom Data Types
Custom data types can be registered in two different ways, by using a `from_taopq()` function or method, or by specializing the `tao::pq::result_traits` class template.
### `from_taopq()`
You can use a function or method called `from_taopq()`, which takes one or more suitable parameters and returns a new instance of your type.
There are multiple places where this function or method can be placed.
#### Intrusive Placement
If you have control over a class type, you can add a static method called `from_taopq()`.
The method can be marked `noexcept` if applicable.
```c++
class my_int_wrapper
{
private:
int value;
public:
explicit my_int_wrapper( int v ) : value( v ) {}
static auto from_taopq( const int v ) noexcept
{
return my_int_wrapper( v );
}
};
```
taoPQ will find the class' method, analyze the methods parameters and convert the result's row accordingly.
The method must have at least one parameter, each parameter will read the required number of fields.
#### Non-Intrusive Placement
If you can't modify the class you could specialize `tao::pq::bind<...>` and place a static `from_taopq()`-method inside the specialization.
The method behaves identical to the intrusive version.
Example for the specialization of `tao::pq::bind<...>`:
```c++
struct some_coordinates
{
double x,y,z;
};
template<>
struct tao::pq::bind< some_coordinates >
{
static auto from_taopq( const double x, const double y, const double z ) noexcept
{
return some_coordinates{ x, y, z };
}
};
```
:point_up: Note that unlike [`to_taopq()`](Parameter-Type-Conversion.md), there is no free function version for `from_taopq()` available.
This is due to the fact that the custom data type is not a parameter, but rather the returned value.
The parameter list can therefore be identical for multiple custom data types and this could leads to conflicting overloads.
Also, [ADL➚](https://en.cppreference.com/w/cpp/language/adl) would be unavailable as only the parameters' types are considered for ADL.
### `tao::pq::result_traits< T >`
If the above custom data type registration via `from_taopq()` is somehow not sufficient, you can specialize the `tao::pq::result_traits` class template.
For now please consult the source code or ask the developers.
TODO: Write proper documentation.
---
This document is part of [taoPQ](https://github.com/taocpp/taopq).
Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch<br>
Distributed under the Boost Software License, Version 1.0<br>
See accompanying file [LICENSE_1_0.txt](../LICENSE_1_0.txt) or copy at https://www.boost.org/LICENSE_1_0.txt
================================================
FILE: doc/Result.md
================================================
# Result
When [executing statements](Statement.md) you receive a result object.
A result comes in two flavours, depending on what statement was executed.
When executing a [query statement➚](https://www.postgresql.org/docs/current/queries-overview.html), the database returns a result set, i.e. any number of rows containing one or more fields of data.
When executing non-query statements, you can usually only extract the number of affected rows.
Query results can be iterated or conveniently converted into a C++ data structure.
Predefined types include most arithmetic C++ data types, STL containers, `std::pair`/`std::tuple`, and `std::optional` for [nullable➚](https://en.wikipedia.org/wiki/Nullable_type) values.
Again custom types can be added with custom conversion functions.
## Synopsis
Don't be intimidated by the size of the API, as you can see several methods are just single-line convenience forwarders.
We will first give the synopsis of everything, afterwards we will break down the API into small logical portions.
```c++
namespace tao::pq
{
namespace internal
{
class zsv; // zero-terminated string view
}
using null_t = decltype( null );
class row;
class field;
class result final
{
private:
// satisfies LegacyRandomAccessIterator, see
// https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator
class const_iterator;
public:
// non-query result access
bool has_rows_affected() const noexcept;
auto rows_affected() const -> std::size_t;
// information about the returned fields
auto columns() const noexcept -> std::size_t;
auto name( const std::size_t column ) const -> std::string;
auto index( const internal::zsv in_name ) const -> std::size_t;
// size of the result set
bool empty() const;
auto size() const -> std::size_t;
// iteration
auto begin() const -> const_iterator;
auto end() const -> const_iterator;
auto cbegin() const -> const_iterator;
auto cend() const -> const_iterator;
// get basic information about a field
bool is_null( const std::size_t row, const std::size_t column ) const;
auto get( const std::size_t row, const std::size_t column ) const -> const char*;
// access rows
auto operator[]( const std::size_t row ) const noexcept -> pq::row;
auto at( const std::size_t row ) const -> pq::row;
// convenience conversions for whole result sets
// expects size()==1, converts the only row to T
template< typename T >
auto as() const -> T;
template< typename T >
auto optional() const -> std::optional< T >;
// convenience conversions to pair/tuple
template< typename T, typename U >
auto pair() const
{
return as< std::pair< T, U > >();
}
template< typename... Ts >
auto tuple() const
{
return as< std::tuple< Ts... > >();
}
// convert each row into T::value_type and add to a container of type T
template< typename T >
auto as_container() const -> T;
// convenience conversions to standard containers
template< typename... Ts >
auto vector() const
{
return as_container< std::vector< Ts... > >();
}
template< typename... Ts >
auto list() const
{
return as_container< std::list< Ts... > >();
}
template< typename... Ts >
auto set() const
{
return as_container< std::set< Ts... > >();
}
template< typename... Ts >
auto multiset() const
{
return as_container< std::multiset< Ts... > >();
}
template< typename... Ts >
auto unordered_set() const
{
return as_container< std::unordered_set< Ts... > >();
}
template< typename... Ts >
auto unordered_multiset() const
{
return as_container< std::unordered_multiset< Ts... > >();
}
template< typename... Ts >
auto map() const
{
return as_container< std::map< Ts... > >();
}
template< typename... Ts >
auto multimap() const
{
return as_container< std::multimap< Ts... > >();
}
template< typename... Ts >
auto unordered_map() const
{
return as_container< std::unordered_map< Ts... > >();
}
template< typename... Ts >
auto unordered_multimap() const
{
return as_container< std::unordered_multimap< Ts... > >();
}
// access underlying result pointer from libpq
auto underlying_raw_ptr() noexcept -> PGresult*;
auto underlying_raw_ptr() const noexcept -> const PGresult*;
};
class row
{
private:
// satisfies LegacyRandomAccessIterator, see
// https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator
class const_iterator;
public:
auto slice( const std::size_t offset, const std::size_t in_columns ) const -> row;
auto columns() const noexcept -> std::size_t;
auto name( const std::size_t column ) const -> std::string;
auto index( const internal::zsv in_name ) const -> std::size_t;
// iteration
auto begin() const -> const_iterator;
auto end() const -> const_iterator;
auto cbegin() const -> const_iterator;
auto cend() const -> const_iterator;
bool is_null( const std::size_t column ) const;
auto get( const std::size_t column ) const -> const char*;
template< typename T >
auto get( const std::size_t column ) const -> T;
template< typename T >
auto optional( const std::size_t column ) const
{
return get< std::optional< T > >( column );
}
template< typename T >
auto as() const -> T;
template< typename T >
auto optional() const
{
return as< std::optional< T > >();
}
template< typename T, typename U >
auto pair() const
{
return as< std::pair< T, U > >();
}
template< typename... Ts >
auto tuple() const
{
return as< std::tuple< Ts... > >();
}
auto at( const std::size_t column ) const -> field;
auto operator[]( const std::size_t column ) const noexcept -> field;
auto at( const internal::zsv in_name ) const -> field;
auto operator[]( const internal::zsv in_name ) const -> field;
friend void swap( row& lhs, row& rhs ) noexcept;
};
class field
{
public:
auto name() const -> std::string;
auto index() const -> std::size_t;
bool is_null() const;
auto get() const -> const char*;
template< typename T >
auto as() const -> T;
template< typename T >
auto optional() const
{
return as< std::optional< T > >();
}
};
bool operator==( const field& f, null_t )
{
return f.is_null();
}
bool operator==( null_t, const field& f )
{
return f.is_null();
}
bool operator!=( const field& f, null_t )
{
return !f.is_null();
}
bool operator!=( null_t, const field& f )
{
return !f.is_null();
}
}
```
## Non-Query Results
For non-query results, i.e. when you called an `INSERT`-, `UPDATE`-, or `DELETE`-statement, you really only need the `rows_affected()`-method.
In generic programming, when you might not know what kind of result you have, you can check whether or not a result is a non-query result by calling the `has_rows_affected()`-method.
```c++
bool tao::pq::result::has_rows_affected() const;
auto tao::pq::result::rows_affected() const -> std::size_t;
```
## Query Results
[Query results➚](https://www.postgresql.org/docs/current/queries-overview.html) are non-mutable data sets, they are cheap to copy, move, or assign and you can iterate over the data multiple times in random order.
Likewise, rows are also non-mutable, as well as fields.
This also means iterators will behave as constant iterators.
Query results act similar to a random-access container.
The don't fully implement the [container requirements➚](https://en.cppreference.com/w/cpp/named_req/Container), but a reasonable subset of those are provided.
:point_up: Rows and fields are non-owning, meaning they are only valid as long as the query result instance is still valid.
### Basics
You can query the container's size, i.e. the number of rows it contains, by calling the `size()`-method.
The `empty()`-method will, of course, return whether the size of the container is zero or not.
```c++
bool tao::pq::result::empty() const;
auto tao::pq::result::size() const -> std::size_t;
```
The number of columns, column order, and the column name is the same for all rows of a result set.
You can query the number of columns by calling the `columns()`-method.
You can retrieve the name of a column using the `name()`-method, or the column index by using the `index()`-method.
```c++
auto tao::pq::result::columns() const -> std::size_t;
auto tao::pq::result::name( std::size_t column ) const -> std::string;
auto tao::pq::result::index( tao::pq::internal::zsv name ) const -> std::size_t;
```
Direct access to the data is provided by the `is_null()`- and the `get()`-methods.
The latter returns the raw string as returned by `libpq`, it is a low level access method that is rarely used directly.
```c++
bool tao::pq::result::is_null( std::size_t row, std::size_t column ) const;
auto tao::pq::result::get( std::size_t row, std::size_t column ) const -> const char*;
```
### Row Access
You can iterate over the container's elements, the rows, with the usual methods.
This is what the `begin()`- and `end()`-methods are for, also allowing for the convenient use of [range-based for loops➚](https://en.cppreference.com/w/cpp/language/range-for).
```c++
auto tao::pq::result::begin() const -> tao::pq::result::const_iterator;
auto tao::pq::result::end() const -> tao::pq::result::const_iterator;
```
The identical `cbegin()`- and `cend()`-methods are provided for completeness.
Here's an example of how to iterate all rows:
```c++
const tao::pq::result result = ...;
for( const auto& row : result ) {
// use row to access your data
}
```
or more traditionally:
```c++
const tao::pq::result result = ...;
for( auto it = std::begin( result ); it != std::end( result ); ++it ) {
// use *it to access your row's data
}
```
Alternatively, you can use an index to access the rows.
```c++
const tao::pq::result result = ...;
for( std::size_t i = 0; i < result.size(); ++i ) {
// use result[ i ] or result.at( i ) to access your row's data
}
```
This is enabled by the accessors, the `at()`-method and the `[]`-operator.
```c++
auto tao::pq::result::at( std::size_t index ) const -> tao::pq::row;
auto tao::pq::result::operator[]( std::size_t index ) const noexcept -> tao::pq::row;
```
More conversion methods will be discussed later, after we covered the basics for rows and fields.
### Field Access
Given a row, you can query information about the fields with the same methods as for the result itself.
```c++
auto tao::pq::row::columns() const -> std::size_t;
auto tao::pq::row::name( std::size_t column ) const -> std::string;
auto tao::pq::row::index( tao::pq::internal::zsv name ) const -> std::size_t;
```
Direct access to the data is provided by the `is_null()`- and the `get()`-methods.
The latter returns the raw string as returned by `libpq`, it is a low level access method that is rarely used directly.
```c++
bool tao::pq::row::is_null( std::size_t column ) const;
auto tao::pq::row::get( std::size_t column ) const -> const char*;
```
You can iterate over the row's elements, the fields, with the usual methods.
This is what the `begin()`- and `end()`-methods are for, also allowing for the convenient use of [range-based for loops➚](https://en.cppreference.com/w/cpp/language/range-for).
```c++
auto tao::pq::row::begin() const -> tao::pq::row::const_iterator;
auto tao::pq::row::end() const -> tao::pq::row::const_iterator;
```
The identical `cbegin()`- and `cend()`-methods are provided for completeness.
Here's an example of how to iterate all fields:
```c++
const tao::pq::result result = ...;
for( const auto& row : result ) {
for( const auto& field : row ) {
// use field to access your data
}
}
```
or more traditionally:
```c++
const tao::pq::result result = ...;
for( auto it = std::begin( result ); it != std::end( result ); ++it ) {
for( auto jt = std::begin( *it ); jt != std::end( *it ); ++jt ) {
// use *jt to access your fields's data
}
}
```
Alternatively, you can use an index to access the fields.
```c++
const tao::pq::result result = ...;
for( std::size_t i = 0; i < result.size(); ++i ) {
for( std::size_t j = 0; j < result[ i ].columns(); ++j ) {
// use result[ i ][ j ] or result.at( i ).at( j ) to access your field's data
}
}
```
This is enabled by the accessors, the `at()`-method and the `[]`-operator.
```c++
auto tao::pq::row::at( std::size_t index ) const -> tao::pq::field;
auto tao::pq::row::operator[]( std::size_t index ) const noexcept -> tao::pq::field;
```
More conversion methods will be discussed later, after we covered the basics for fields.
### Fields
You can query a field's name by calling the `name()`-method.
```c++
auto tao::pq::field::name() const -> std::string;
```
Direct access to the data is provided by the `is_null()`- and the `get()`-methods.
The latter returns the raw string as returned by `libpq`, it is a low level access method that is rarely used directly.
```c++
bool tao::pq::field::is_null() const;
auto tao::pq::field::get() const -> const char*;
```
Now that we covered the basics, we can retrieve the actual data and convert it to the data types we need.
## Field Data Conversion
A field can be converted to any data type `T` that is a single field wide.
What we mean by that is, that `tao::pq::result_traits_size< T >` yields 1.
This is the case for `const char*`, `std::string`, `int`, etc.
In order to convert a field to the data type you want, you can use the `as()`-method.
```c++
template< typename T >
auto tao::pq::field::as() const -> T;
```
The conversion is handled by the `tao::pq::result_traits` class template, which is documented in the [result type conversion](Result-Type-Conversion.md) chapter.
A field also has a convenience method to convert directly into a `std::optional<T>`.
```c++
template< typename T >
auto tao::pq::field::optional() const
{
return as< std::optional< T > >();
}
```
## Row Data Conversion
**TODO** Finish this up for rows and results...
---
This document is part of [taoPQ](https://github.com/taocpp/taopq).
Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch<br>
Distributed under the Boost Software License, Version 1.0<br>
See accompanying file [LICENSE_1_0.txt](../LICENSE_1_0.txt) or copy at https://www.boost.org/LICENSE_1_0.txt
================================================
FILE: doc/Statement.md
================================================
# Statement
:warning: Before showing you how to execute statements with taoPQ, we'd like to take a moment to talk about [SQL injection➚](https://en.wikipedia.org/wiki/SQL_injection).
SQL injection is a large family of security issues that has plagued the internet for decades.
We designed taoPQ to allow you to *safely* and *conveniently* write code that does not allow SQL injection.
With that said, let's start executing statements with taoPQ.
## `execute()`
All statements are executed by calling an `execute()`-method, either on a transaction, connection, or connection pool directly.
The synopsis of the execute methods of those types (`Type` being `tao::pq::transaction`, `tao::pq::connection`, or `tao::pq::connection_pool`) is:
```c++
template< typename... As >
auto Type::execute( const tao::pq::internal::zsv statement, As&&... as ) -> tao::pq::result;
```
For the purpose of this chapter, it makes no difference which `Type` is used.
The method takes the statement itself as its first parameter plus additional parameters that will be passed to the statement.
It returns a `tao::pq::result` that is documented in the [Result](Result.md) chapter.
In case of an error, i.e. if the statement execution failed, an exception is thrown as documented in the [Error Handling](Error-Handling.md) chapter.
### `tao::pq::internal::zsv`
The `tao::pq::internal::zsv` type (zero-terminated string view) that is used for the `statement` parameter ensures that you pass a zero-terminated string.
It is a non-owning type which has non-explicit constructor overloads for `const char*` and `const std::string&`.
For safety reasons, there is another overload for `std::nullptr_t` that is deleted.
Note that we do not accept `std::string_view`, as the underlying C-API of `libpq` requires a zero-terminated string.
## Positional Parameters
To reference the parameters you supplied in the statement, you use [positional parameters➚](https://www.postgresql.org/docs/current/sql-expressions.html).
Positional parameters are of the form `$n` where `n` is a number starting at 1.
Here's an example of how you can insert a row with two columns into the database:
```c++
tr->execute( "INSERT INTO user ( name, age ) VALUES ( $1, $2 )", "Daniel", 42 );
```
The actual data is separated from the statement itself.
The use of positional parameters makes passing strings and other types safe, as there is no need for manually escaping the data.
Our library now knows what is the actual SQL statement you want to send and what is the data you want to send.
This protects you from SQL injections and it is also quiet convenient.
The way the data is now transferred between the client and the server is also more efficient.
:warning: The only thing you have to remember is to **never** concatenate strings together to create the SQL statement including the data manually.
As this is such an important point, we will illustrate how it should **not** be done:
```c++
auto find_user( const std::string& name )
{
return connection->execute( "SELECT FROM user WHERE name = '" + name + "'" );
// ~~~~~~~~~~~~~~ WRONG!!!
}
```
:no_entry: Never concatenate SQL statements manually!
Consider `name` to be an input field coming from untrusted user input.
What happens, if a user enters the following "name":
`Robert'; DELETE FROM user WHERE name <> 'Little Bobby Tables`
Yupp, all users other than [`Little Bobby Tables`➚](https://xkcd.com/327/) have just been deleted from the database.
You might have seen other libraries where you should [escape the data explicitly➚](https://www.postgresql.org/docs/current/libpq-exec.html#LIBPQ-EXEC-ESCAPE-STRING), something like:
```c++
auto find_user( const std::string& name )
{
return connection->execute( "SELECT FROM user WHERE name = '" + connection->escape( name ) + "'" );
}
```
This is cumbersome and error-prone.
It is easy to forget calling the escape method, which the compiler will *not* catch for you, and for non-strings, the code needs to call explicit conversion methods to string.
This turns longer SQL statements into a long, ugly mess.
Positional parameters solve all of those problems and therefore taoPQ does not even offer any escaping methods.
To be safe and to make your life easier, with taoPQ always use positional parameters:
```c++
auto find_user( const std::string& name )
{
return connection->execute( "SELECT FROM user WHERE name = $1", name );
}
```
## Multi-Query Commands
Some SQL client libraries allow multi-query commands, i.e. the command string can include multiple SQL statements.
In `libpq`, this is supported by the [`PQexec()`➚](https://www.postgresql.org/docs/current/libpq-exec.html)-function.
As an extra defense against SQL injection, taoPQ *never* calls the `PQexec()`-function.
We allow at most one SQL command in the given statement passed to an `execute()`-method.
## Prepared Statements
In the [Connection](Connection.md) chapter we have shown how you can prepare (and deallocate) prepared statements.
In order to execute prepared statements, you simply pass the name of the prepared statement to the `execute()`-method instead of the actual SQL statement.
This might look like this:
```c++
connection->prepare( "insert_user", "INSERT INTO user ( name, age ) VALUES ( $1, $2 )" );
connection->execute( "insert_user", "Daniel", 42 );
connection->execute( "insert_user", "Tom", 41 );
connection->execute( "insert_user", "Jerry", 29 );
```
This is both more efficient and also allows you to change the statements in a central place if need be, without touching any of the places where it is actually used.
You might want to wrap calls to a (prepared) statement into an application-specific wrapper, that way you add C++'s type safety for the rest of the application calling that method (and also receiving the result).
Another idea that we already used in practice is to read the SQL statements from a configuration file.
When you then need to change a statement, e.g. to work around a performance issue with the database or because you renamed a column in the database, all you need to do is adapt the configuration.
No need to recompile the application.
## Type Conversion
The above example also shows that you can use different data types as parameters.
Besides basic types like strings or integers, you can also use more complex types like `std::tuple` which will decay into multiple parameters.
You can even register your own data types to generate one or more parameters from them.
The [Parameter Type Conversion](Parameter-Type-Conversion.md) chapter explains which data types are supported out-of-the-box, and how you can register your own custom data types.
---
This document is part of [taoPQ](https://github.com/taocpp/taopq).
Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch<br>
Distributed under the Boost Software License, Version 1.0<br>
See accompanying file [LICENSE_1_0.txt](../LICENSE_1_0.txt) or copy at https://www.boost.org/LICENSE_1_0.txt
================================================
FILE: doc/TOC.md
================================================
# Table of Content
* [Requirements](Requirements.md)
* [Operating System Support](Requirements.md#operator-system-support)
* [Compiler Support](Requirements.md#compiler-support)
* [Language Requirements](Requirements.md#language-requirements)
* [Compiler Options/Warnings](Requirements.md#compiler-optionswarnings)
* [Database Requirements](Requirements.md#database-requirements)
* [Installation](Installation.md)
* **TODO** after properly rewriting this chapter
* [Getting Started](Getting-Started.md)
* [Next Steps](Getting-Started.md#next-steps)
* [Advanced Topics](Getting-Started.md#advanced-topics)
* [Connection Pool](Connection-Pool.md)
* [Synopsis](Connection-Pool.md#synopsis)
* [Creating Connection Pools](Connection-Pool.md#creating-connection-pools)
* [Borrowing Connections](Connection-Pool.md#borrowing-connections)
* [Executing Statements](Connection-Pool.md#executing-statements)
* [Cleanup](Connection-Pool.md#cleanup)
* [Thread Safety](Connection-Pool.md#thread-safety)
* [Connection](Connection.md)
* [Synopsis](Connection.md#synopsis)
* [Creating a Connection](Connection.md#creating-a-connection)
* [Creating Transactions](Connection.md#creating-transactions)
* [Creating a "Direct" Transaction](Connection.md#creating-a-direct-transaction)
* [Creating a Database Transaction](Connection.md#creating-a-database-transaction)
* [Executing Statements](Connection.md#executing-statements)
* [Prepared Statements](Connection.md#prepared-statements)
* [Manually Prepared Statements](Connection.md#manually-prepared-statements)
* [Checking Status](Connection.md#checking-status)
* [Notification Framework](Connection.md#notification-framework)
* [Sending Messages](Connection.md#sending-messages)
* [Receiving Messages](Connection.md#receiving-messages)
* [Handling Messages](Connection.md#handling-messages)
* [Per Channel Handlers](Connection.md#per-channel-handlers)
* [Asynchronous Notifications](Connection.md#asynchronous-notifications)
* [Event Loop](Connection.md#event-loop)
* [Underlying Connection Pointer](Connection.md#underlying-connection-pointer)
* [Error Messages](Connection.md#error-messages)
* [Transaction](Transaction.md)
* [Synopsis](Transaction.md#synopsis)
* [Creating Transactions](Transaction.md#creating-transactions)
* [Statement Execution](Transaction.md#statement-execution)
* [Terminate Transaction](Transaction.md#terminate-transaction)
* [Commit a Transaction](Transaction.md#commit-a-transaction)
* [Abort a Transaction](Transaction.md#abort-a-transaction)
* [Transaction Ordering](Transaction.md#transaction-ordering)
* [Direct Transactions](Transaction.md#direct-transactions)
* [Manual Transaction Handling](Transaction.md#manual-transaction-handling)
* [Accessing the Connection](Transaction.md#accessing-the-connection)
* [Statement](Statement.md)
* [`execute()`](Statement.md#execute)
* [`tao::pq::internal::zsv`](Statement.md#taopqinternalzsv)
* [Positional Parameters](Statement.md#positional-parameters)
* [Multi-Query Commands](Statement.md#multi-query-commands)
* [Prepared Statements](Statement.md#prepared-statements)
* [Type Conversion](Statement.md#type-conversion)
* [Parameter Type Conversion](Parameter-Type-Conversion.md)
* [NULL](Parameter-Type-Conversion.md#null)
* [Fundamental Types](Parameter-Type-Conversion.md#fundamental-types)
* [`std::optional< T >`](Parameter-Type-Conversion.md#stdoptional-t-)
* [`std::pair< T, U >`](Parameter-Type-Conversion.md#stdpair-t-u-)
* [`std::tuple< Ts... >`](Parameter-Type-Conversion.md#stdtuple-ts-)
* [Aggregates](Parameter-Type-Conversion.md#aggregates)
* [Custom Data Types](Parameter-Type-Conversion.md#custom-data-types)
* [`to_taopq()`](Parameter-Type-Conversion.md#to_taopq-)
* [Intrusive Placement](Parameter-Type-Conversion.md#intrusive-placement)
* [Non-Intrusive Placement](Parameter-Type-Conversion.md#non-intrusive-placement)
* [`tao::pq::parameter_traits< T >`](Parameter-Type-Conversion.md#taopqparameter_traits-t-)
* [Result](Result.md)
* [Synopsis](Result.md#synopsis)
* [Non-Query Results](Result.md#non-query-results)
* [Query Results](Result.md#query-results)
* [Basics](Result.md#basics)
* [Row Access](Result.md#row-access)
* [Field Access](Result.md#field-access)
* [Fields](Result.md#fields)
* [Field Data Conversion](Result.md#field-data-conversion)
* [Row Data Conversion](Result.md#row-data-conversion)
* [Result Type Conversion](Result-Type-Conversion.md)
* [Fundamental Types](Result-Type-Conversion.md#fundamental-types)
* [`std::optional< T >`](Result-Type-Conversion.md#stdoptional-t-)
* [`std::pair< T, U >`](Result-Type-Conversion.md#stdpair-t-u-)
* [`std::tuple< Ts... >`](Result-Type-Conversion.md#stdtuple-ts-)
* [Aggregates](Result-Type-Conversion.md#aggregates)
* [Custom Data Types](Result-Type-Conversion.md#custom-data-types)
* [`from_taopq()`](Result-Type-Conversion.md#from_taopq)
* [Intrusive Placement](Result-Type-Conversion.md#intrusive-placement)
* [Non-Intrusive Placement](Result-Type-Conversion.md#non-intrusive-placement)
* [`tao::pq::result_traits< T >`](Result-Type-Conversion.md#taopqresult_traits-t-)
* [Aggregate Support](Aggregate-Support.md)
* [Status](Aggregate-Support.md#status)
* [Requirements](Aggregate-Support.md#requirements)
* [Registration](Aggregate-Support.md#registration)
* [Direct Result Conversion](Aggregate-Support.md#direct-result-conversion)
* [Example](Aggregate-Support.md#example)
* [Error Handling](Error-Handling.md)
* [SQLSTATE](Error-Handling.md#sqlstate)
* [Class of Error](Error-Handling.md#class-of-error)
* [Specific Error Conditions](Error-Handling.md#specific-error-conditions)
* [Connection Errors](Error-Handling.md#connection-errors)
* [Other Exceptions](Error-Handling.md#other-exceptions)
* [Binary Data](Binary-Data.md)
* [The `BYTEA` Data Type](Binary-Data.md#the-bytea-data-type)
* [C++ Binary Data](Binary-Data.md#c-binary-data)
* [Passing Binary Data](Binary-Data.md#passing-binary-data)
* [Receiving Binary Data](Binary-Data.md#receiving-binary-data)
* [Bulk Transfer](Bulk-Transfer.md)
* [Synopsis](Bulk-Transfer.md#synopsis)
* [Large Object](Large-Object.md)
* [Synopsis](Large-Object.md#synopsis)
* [Creating a Large Object](Large-Object.md#creating-a-large-object)
* [Removing a Large Object](Large-Object.md#removing-a-large-object)
* [Importing a Large Object](Large-Object.md#importing-a-large-object)
* [Exporting a Large Object](Large-Object.md#exporting-a-large-object)
* [Opening an Existing Large Object](Large-Object.md#opening-an-existing-large-object)
* [Writing Data to a Large Object](Large-Object.md#writing-data-to-a-large-object)
* [Reading Data from a Large Object](Large-Object.md#reading-data-from-a-large-object)
* [Seeking in a Large Object](Large-Object.md#seeking-in-a-large-object)
* [Obtaining the Seek Position of a Large Object](Large-Object.md#obtaining-the-seek-position-of-a-large-object)
* [Truncating a Large Object](Large-Object.md#truncating-a-large-object)
* [Performance](Performance.md)
================================================
FILE: doc/Transaction.md
================================================
# Transaction
Before we continue with our own documentation, we'd like to once again point you to the excellent [PostgreSQL documentation➚](https://www.postgresql.org/docs/current/tutorial-transactions.html) on transactions.
We will assume that you are familiar with how transactions work on PostgreSQL and in general, so we will *not* repeat this here.
## Synopsis
```c++
namespace tao::pq
{
namespace internal
{
class zsv; // zero-terminated string view
}
class connection;
class result;
class transaction
: public std::enable_shared_from_this< transaction >
{
public:
// non-copyable, non-movable
transaction( const transaction& ) = delete;
transaction( transaction&& ) = delete;
void operator=( const transaction& ) = delete;
void operator=( transaction&& ) = delete;
virtual ~transaction() = default;
// create transactions
auto subtransaction()
-> std::shared_ptr< transaction >;
// asynchronous statement execution
template< typename... As >
void send( const internal::zsv statement, As&&... as );
// asynchronous result retrieval
auto get_result() -> result;
// synchronous statement execution
template< typename... As >
auto execute( const internal::zsv statement, As&&... as )
{
send( statement, std::forward< As >( as )... );
return get_result();
}
// finalize
void commit();
void rollback();
// access connection
auto connection() const noexcept
-> const std::shared_ptr< pq::connection >&;
};
}
```
:point_up: Note that `tao::pq::internal::zsv` is explained in the [Statement](Statement.md) chapter.
## Creating Transactions
In taoPQ, you create a top-level transaction from a connection, the methods available to do so are described in the [Connection](Connection.md) chapter.
In short, you create a normal transaction with the connection's `transaction()`-method or a "direct transaction" with the connection's `direct()`-method.
Both return a shared pointer to a `tao::pq::transaction`-derived object.
From any transaction, you can create a subtransaction by calling the `subtransaction()`-method.
```c++
auto tao::pq::transaction::subtransaction()
-> std::shared_ptr< tao::pq::transaction >;
```
It returns just another `tao::pq::transaction`-derived object from which you may create further, nested subtransactions if needed.
All transactions then offer the above, unified interface.
## Statement Execution
On all transactions you can execute SQL statements.
If you execute a statement on a connection object directly, is creates an implicit direct transaction and forwards the execution to that temporary transaction.
The actual statement execution, i.e. the `execute()`-method, is described in the [Statement](Statement.md) chapter.
## Terminate Transaction
Transaction can be terminated in one of two ways.
### Commit a Transaction
In order to commit a transaction you call the `commit()`-method.
```c++
void tao::pq::transaction::commit();
```
All changes made by the transaction become visible to others and are guaranteed to be durable if a crash occurs.
### Abort a Transaction
In order to abort a transaction you call the `rollback()`-method.
```c++
void tao::pq::transaction::rollback();
```
Rolls back the current transaction and causes all the updates made by the transaction to be discarded.
## Transaction Ordering
Any transactions created via taoPQ is registered in the connection object as the currently active transaction.
At any given time, a connection can only have a single active transaction.
If you attempt to use a transaction object in the wrong order, taoPQ will notice and throw an appropriate `std::logic_error` exception.
:point_up: Note that the correct order depends on the *logical* lifetime of transactions.
The logical lifetime of a transactions ends when you explicitly call either the `commit()`- or the `rollback()`-method, or if the object's lifetime ends.
The destructor will automatically perform a call to the `rollback()`-method if the lifetime was not ended explicitly.
This comes in handy when exceptions are thrown and the destructor call happens due to the associated stack unwinding.
## Direct Transactions
Without an active transaction PostgreSQL works in ["autocommit"➚](https://www.postgresql.org/docs/current/sql-begin.html) mode.
This means that each statement is executed in its own internal transaction and a commit is implicitly performed at the end of the statement (if execution was successful, otherwise a rollback is done).
A "direct transaction" represents this concept in taoPQ.
A direct transaction is special, as the `commit()`- and `rollback()`-methods are available, but normally not needed.
Specifically, you don't need to call the `commit()`-method in order to make the changes you made permanent.
However, calling the `commit()`-method ends the logical lifetime of the transaction and the transaction deregisters itself from the connection.
In generic code you might receive a transaction from somewhere else and you might call the `commit()`-method regardless of whether the underlying transaction is a direct transaction or a normal transaction.
In case you need to know whether a given transaction object is a direct transaction or not, you can call the `is_direct()`-method.
```c++
bool tao::pq::transaction::is_direct() const noexcept;
```
Opening a subtransaction from a direct connection is possible and simply starts a normal transaction on the connection object.
## Manual Transaction Handling
You can manually begin, commit, or rollback transactions by executing [`BEGIN`➚](https://www.postgresql.org/docs/current/sql-begin.html), [`COMMIT`➚](https://www.postgresql.org/docs/current/sql-commit.html), or [`ROLLBACK`➚](https://www.postgresql.org/docs/current/sql-rollback.html) statements directly via the `execute()`-method.
Likewise, you can manually create, commit, or rollback subtransactions by executing [`SAVEPOINT`➚](https://www.postgresql.org/docs/current/sql-savepoint.html), [`RELEASE SAVEPOINT`➚](https://www.postgresql.org/docs/current/sql-release-savepoint.html), or [`ROLLBACK TO SAVEPOINT`➚](https://www.postgresql.org/docs/current/sql-rollback-to.html) statements directly via the `execute()`-method.
:point_up: We strongly advise against manual transaction handling, as it will not be tracked by taoPQ and might confuse our library's transaction ordering framework.
We advise to use the methods offered by taoPQ instead of manually handling transactions.
## Accessing the Connection
If you need to access the connection that a transaction is bound to, you can call the `connection()`-method.
```c++
auto tao::pq::transaction::connection() const noexcept
-> const std::shared_ptr< tao::pq::connection >&;
```
:point_up: Note that the shared pointer will be empty if the logical lifetime of the transaction ended.
---
This document is part of [taoPQ](https://github.com/taocpp/taopq).
Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch<br>
Distributed under the Boost Software License, Version 1.0<br>
See accompanying file [LICENSE_1_0.txt](../LICENSE_1_0.txt) or copy at https://www.boost.org/LICENSE_1_0.txt
================================================
FILE: example/CMakeLists.txt
================================================
cmake_minimum_required(VERSION 3.15)
add_subdirectory(get_version)
set(EXAMPLE_TARGETS
taopq_example_get_version
)
add_custom_target(examples
COMMENT "Run all examples"
DEPENDS ${EXAMPLE_TARGETS}
)
foreach(tgt IN LISTS EXAMPLE_TARGETS)
add_custom_command(TARGET examples POST_BUILD
COMMAND "$<TARGET_FILE:${tgt}>"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "Running ${tgt}"
VERBATIM
)
endforeach()
================================================
FILE: example/get_version/CMakeLists.txt
================================================
cmake_minimum_required(VERSION 3.15)
project(taopq_example_get_version CXX)
add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} PRIVATE taocpp::taopq)
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_20 c_std_11)
================================================
FILE: example/get_version/main.cpp
================================================
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
#include <tao/pq.hpp>
static std::string get_env( std::string_view name )
{
#if defined( _MSC_VER )
std::size_t required = 1024;
std::vector< char > buffer( required );
const auto err = ::getenv_s( &required, buffer.data(), buffer.size(), std::string( name ).c_str() );
if( err != 0 ) {
return {};
}
return std::string( buffer.data() );
#else
if( const char* v = std::getenv( std::string( name ).c_str() ) ) {
return std::string( v );
}
return {};
#endif
}
int main()
{
const auto database = get_env( "PGDATABASE" );
const auto connection = tao::pq::connection::create( database );
const auto result = connection->execute( "SELECT version()" );
std::cout << "PostgreSQL version: " << result.as< std::string >() << std::endl;
return EXIT_SUCCESS;
}
================================================
FILE: include/tao/pq/access_mode.hpp
================================================
// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
#ifndef TAO_PQ_ACCESS_MODE_HPP
#define TAO_PQ_ACCESS_MODE_HPP
#include <cstdint>
#include <string_view>
#include <tao/pq/internal/format_as.hpp>
namespace tao::pq
{
enum class access_mode : std::uint8_t
{
default_access_mode,
read_write,
read_only
};
[[nodiscard]] constexpr auto taopq_format_as( const access_mode am ) noexcept -> std::string_view
{
switch( am ) {
case access_mode::default_access_mode:
return "default_access_mode";
case access_mode::read_write:
return "read_write";
case access_mode::read_only:
return "read_only";
default:
return "<unknown>";
}
}
} // namespace tao::pq
#endif
================================================
FILE: include/tao/pq/binary.hpp
================================================
// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
#ifndef TAO_PQ_BINARY_HPP
#define TAO_PQ_BINARY_HPP
#include <cstddef>
#include <span>
#include <vector>
namespace tao::pq
{
using binary = std::vector< std::byte >;
using binary_view = std::span< const std::byte >;
[[nodiscard]] auto to_binary_view( const auto* data, const std::size_t size ) noexcept -> binary_view
requires( sizeof( *data ) == 1 )
{
return { reinterpret_cast< const std::byte* >( data ), size };
}
[[nodiscard]] auto to_binary_view( const auto& value ) noexcept -> binary_view
{
return pq::to_binary_view( std::data( value ), std::size( value ) );
}
[[nodiscard]] auto to_binary( const auto* data, const std::size_t size ) -> binary
requires( sizeof( *data ) == 1 )
{
const auto* ptr = reinterpret_cast< const std::byte* >( data );
return { ptr, ptr + size };
}
[[nodiscard]] auto to_binary( const auto& value ) -> binary
{
return pq::to_binary( std::data( value ), std::size( value ) );
}
} // namespace tao::pq
#endif
================================================
FILE: include/tao/pq/bind.hpp
================================================
// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
#ifndef TAO_PQ_BIND_HPP
#define TAO_PQ_BIND_HPP
namespace tao::pq
{
template< typename >
struct bind;
} // namespace tao::pq
#endif
================================================
FILE: include/tao/pq/connection.hpp
================================================
// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
#ifndef TAO_PQ_CONNECTION_HPP
#define TAO_PQ_CONNECTION_HPP
#include <chrono>
#include <cstddef>
#include <functional>
#include <map>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <string_view>
#include <utility>
#include <libpq-fe.h>
#include <tao/pq/access_mode.hpp>
#include <tao/pq/connection_status.hpp>
#include <tao/pq/internal/poll.hpp>
#include <tao/pq/internal/zsv.hpp>
#include <tao/pq/isolation_level.hpp>
#include <tao/pq/log.hpp>
#include <tao/pq/notification.hpp>
#include <tao/pq/parameter.hpp>
#include <tao/pq/pipeline_status.hpp>
#include <tao/pq/poll.hpp>
#include <tao/pq/transaction.hpp>
#include <tao/pq/transaction_base.hpp>
#include <tao/pq/transaction_status.hpp>
namespace tao::pq
{
class connection_pool;
class pipeline;
class table_reader;
class table_writer;
namespace internal
{
class top_level_transaction;
class top_level_subtransaction;
class nested_subtransaction;
} // namespace internal
class connection final
: public std::enable_shared_from_this< connection >
{
private:
friend class connection_pool;
friend class table_reader;
friend class table_writer;
friend class transaction;
friend class transaction_base;
friend class internal::top_level_transaction;
friend class internal::top_level_subtransaction;
friend class internal::nested_subtransaction;
std::unique_ptr< PGconn, decltype( &PQfinish ) > m_pgconn;
transaction_base* m_current_transaction;
std::optional< std::chrono::milliseconds > m_timeout;
std::set< std::string, std::less<> > m_prepared_statements;
std::function< poll::callback > m_poll;
std::function< void( const notification& ) > m_notification_handler;
std::map< std::string, std::function< void( const char* ) >, std::less<> > m_notification_handlers;
std::shared_ptr< log > m_log;
[[nodiscard]] auto escape_identifier( const std::string_view identifier ) const -> std::unique_ptr< char, decltype( &PQfreemem ) >;
[[nodiscard]] auto attempt_rollback() const noexcept -> bool;
static void check_prepared_name( const std::string_view name );
void send_params( const char* statement,
const int n_params,
const Oid types[],
const char* const values[],
const int lengths[],
const int formats[] );
[[nodiscard]] auto timeout_end( const std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now() ) const noexcept -> std::chrono::steady_clock::time_point
{
return m_timeout ? ( start + *m_timeout ) : start;
}
void wait( const bool wait_for_write, const std::chrono::steady_clock::time_point end );
void cancel();
[[nodiscard]] auto get_result( const std::chrono::steady_clock::time_point end ) -> std::unique_ptr< PGresult, decltype( &PQclear ) >;
[[nodiscard]] auto get_fatal_error( const std::chrono::steady_clock::time_point end ) -> std::unique_ptr< PGresult, decltype( &PQclear ) >;
void consume_empty_result( const std::chrono::steady_clock::time_point end );
[[nodiscard]] auto get_copy_data( char*& buffer, const std::chrono::steady_clock::time_point end ) -> std::size_t;
[[nodiscard]] auto get_copy_data( char*& buffer ) -> std::size_t;
void put_copy_data( const char* buffer, const std::size_t size );
void put_copy_end( const char* error_message = nullptr );
void clear_copy_data( const std::chrono::steady_clock::time_point end );
// pass-key idiom
class private_key final
{
private_key() = default;
friend class connection;
friend class connection_pool;
};
public:
connection( const private_key /*unused*/, const std::string& connection_info );
connection( const connection& ) = delete;
connection( connection&& ) = delete;
void operator=( const connection& ) = delete;
void operator=( connection&& ) = delete;
~connection() = default;
[[nodiscard]] static auto create( const std::string& connection_info ) -> std::shared_ptr< connection >;
[[nodiscard]] auto error_message() const -> const char*;
[[nodiscard]] auto poll_callback() const noexcept -> decltype( auto )
{
return m_poll;
}
void set_poll_callback( std::function< poll::callback > poll_cb ) noexcept
{
m_poll = std::move( poll_cb );
}
void reset_poll_callback()
{
m_poll = internal::poll;
}
[[nodiscard]] auto notification_handler() const noexcept -> decltype( auto )
{
return m_notification_handler;
}
void set_notification_handler( std::function< void( const notification& ) > handler ) noexcept
{
m_notification_handler = std::move( handler );
}
void reset_notification_handler() noexcept
{
m_notification_handler = nullptr;
}
[[nodiscard]] auto notification_handler( const std::string_view channel ) const -> std::function< void( const char* payload ) >;
void set_notification_handler( const std::string_view channel, const std::function< void( const char* payload ) >& handler );
void reset_notification_handler( const std::string_view channel ) noexcept;
[[nodiscard]] auto log_handler() const noexcept -> decltype( auto )
{
return m_log;
}
void set_log_handler( const std::shared_ptr< pq::log >& log ) noexcept
{
m_log = log;
}
void reset_log_handler() noexcept
{
m_log = nullptr;
}
[[nodiscard]] auto status() const noexcept -> connection_status;
[[nodiscard]] auto transaction_status() const noexcept -> pq::transaction_status;
[[nodiscard]] auto pipeline_status() const noexcept -> pq::pipeline_status;
void enter_pipeline_mode();
void exit_pipeline_mode();
void pipeline_sync();
[[nodiscard]] auto is_open() const noexcept -> bool
{
return status() == connection_status::ok;
}
[[nodiscard]] auto is_idle() const noexcept -> bool
{
return transaction_status() == transaction_status::idle;
}
[[nodiscard]] auto is_busy() const noexcept -> bool;
[[nodiscard]] auto flush() -> bool;
void consume_input();
[[nodiscard]] auto direct() -> std::shared_ptr< pq::transaction >;
[[nodiscard]] auto transaction() -> std::shared_ptr< pq::transaction >;
[[nodiscard]] auto transaction( const access_mode am, const isolation_level il = isolation_level::default_isolation_level ) -> std::shared_ptr< pq::transaction >;
[[nodiscard]] auto transaction( const isolation_level il, const access_mode am = access_mode::default_access_mode ) -> std::shared_ptr< pq::transaction >;
[[nodiscard]] auto pipeline() -> std::shared_ptr< pq::pipeline >;
void prepare( std::string name, const internal::zsv statement );
void deallocate( const std::string_view name );
template< parameter_type... As >
auto execute( const internal::zsv statement, As&&... as )
{
return direct()->execute( statement, std::forward< As >( as )... );
}
void listen( const std::string_view channel );
void listen( const std::string_view channel, const std::function< void( const char* payload ) >& handler );
void unlisten( const std::string_view channel );
void notify( const std::string_view channel );
void notify( const std::string_view channel, const std::string_view payload );
void handle_notifications();
void get_notifications();
[[nodiscard]] auto socket() const -> int;
[[nodiscard]] auto timeout() const noexcept -> decltype( auto )
{
return m_timeout;
}
void set_timeout( const std::chrono::milliseconds timeout ) noexcept
{
m_timeout = timeout;
}
void reset_timeout() noexcept
{
m_timeout = std::nullopt;
}
[[nodiscard]] auto password( const internal::zsv passwd, const internal::zsv user, const internal::zsv algorithm = "scram-sha-256" ) -> std::string;
[[nodiscard]] auto underlying_raw_ptr() noexcept -> PGconn*
{
return m_pgconn.get();
}
[[nodiscard]] auto underlying_raw_ptr() const noexcept -> const PGconn*
{
return m_pgconn.get();
}
};
} // namespace tao::pq
#endif
================================================
FILE: include/tao/pq/connection_pool.hpp
================================================
// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
#ifndef TAO_PQ_CONNECTION_POOL_HPP
#define TAO_PQ_CONNECTION_POOL_HPP
#include <chrono>
#include <functional>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <utility>
#include <tao/pq/connection.hpp>
#include <tao/pq/internal/poll.hpp>
#include <tao/pq/internal/pool.hpp>
#include <tao/pq/internal/zsv.hpp>
#include <tao/pq/parameter.hpp>
#include <tao/pq/poll.hpp>
#include <tao/pq/result.hpp>
namespace tao::pq
{
class connection_pool
: public internal::pool< pq::connection >
{
private:
const std::string m_connection_info;
std::optional< std::chrono::milliseconds > m_timeout;
std::function< poll::callback > m_poll;
protected:
[[nodiscard]] auto v_create() const -> std::unique_ptr< pq::connection > override;
[[nodiscard]] auto v_is_valid( pq::connection& c ) const noexcept -> bool override
{
return c.is_idle();
}
private:
// pass-key idiom
class private_key final
{
private_key() = default;
friend class connection_pool;
};
public:
connection_pool( const private_key /*unused*/, const std::string_view connection_info );
void get() const = delete;
template< typename T = connection_pool >
[[nodiscard]] static auto create( const std::string_view connection_info ) -> std::shared_ptr< T >
{
return std::make_shared< T >( private_key(), connection_info );
}
[[nodiscard]] auto timeout() const noexcept -> decltype( auto )
{
return m_timeout;
}
void set_timeout( const std::chrono::milliseconds timeout ) noexcept
{
m_timeout = timeout;
}
void reset_timeout() noexcept
{
m_timeout = std::nullopt;
}
[[nodiscard]] auto poll_callback() const noexcept -> decltype( auto )
{
return m_poll;
}
void set_poll_callback( std::function< poll::callback > poll_cb ) noexcept
{
m_poll = std::move( poll_cb );
}
void reset_poll_callback()
{
m_poll = internal::poll;
}
[[nodiscard]] auto connection() -> std::shared_ptr< pq::connection >;
template< parameter_type... As >
auto execute( const internal::zsv statement, As&&... as )
{
return connection()->direct()->execute( statement, std::forward< As >( as )... );
}
};
} // namespace tao::pq
#endif
================================================
FILE: include/tao/pq/connection_status.hpp
================================================
// Copyright (c) 2022-2026 Daniel Frey and Dr. Colin Hirsch
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
#ifndef TAO_PQ_CONNECTION_STATUS_HPP
#define TAO_PQ_CONNECTION_STATUS_HPP
#include <cstdint>
#include <string_view>
#include <libpq-fe.h>
#include <tao/pq/internal/format_as.hpp>
namespace tao::pq
{
enum class connection_status : std::uint8_t
{
ok = CONNECTION_OK,
bad = CONNECTION_BAD
};
[[nodiscard]] constexpr auto taopq_format_as( const connection_status cs ) noexcept -> std::string_view
{
switch( cs ) {
case connection_status::ok:
return "ok";
case connection_status::bad:
return "bad";
default:
return "<unknown>";
}
}
} // namespace tao::pq
#endif
================================================
FILE: include/tao/pq/exception.hpp
================================================
// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
#ifndef TAO_PQ_EXCEPTION_HPP
#define TAO_PQ_EXCEPTION_HPP
#include <stdexcept>
#include <string>
#include <string_view>
#include <libpq-fe.h>
namespace tao::pq
{
struct error
: std::runtime_error
{
using std::runtime_error::runtime_error;
};
struct timeout_reached
: error
{
using error::error;
};
struct network_error
: error
{
using error::error;
};
// https://www.postgresql.org/docs/current/errcodes-appendix.html
struct sql_error
: error
{
std::string sqlstate;
sql_error( const char* what, const std::string_view in_sqlstate );
};
// when a condition name from PostgreSQL is ambiguous,
// we qualify the error class via a template parameter
template< typename >
struct string_data_right_truncation;
template< typename >
struct modifying_sql_data_not_permitted;
template< typename >
struct prohibited_sql_statement_attempted;
template< typename >
struct reading_sql_data_not_permitted;
struct success // 00xxx
: sql_error
{
using sql_error::sql_error;
};
struct warning // 01xxx
: sql_error
{
using sql_error::sql_error;
};
struct null_value_eliminated_in_set_function // 01003
: warning
{
using warning::warning;
};
template<>
struct string_data_right_truncation< warning > // 01004
: warning
{
using warning::warning;
};
struct privilege_not_revoked // 01006
: warning
{
using warning::warning;
};
struct privilege_not_granted // 01007
: warning
{
using warning::warning;
};
struct implicit_zero_bit_padding // 01008
: warning
{
using warning::warning;
};
struct dynamic_result_sets_returned // 0100C
: warning
{
using warning::warning;
};
struct deprecated_feature // 01P01
: warning
{
using warning::warning;
};
struct no_data // 02xxx
: sql_error
{
using sql_error::sql_error;
};
struct no_additional_dynamic_result_sets_returned // 02001
: no_data
{
using no_data::no_data;
};
struct sql_statement_not_yet_complete // 03xxx
: sql_error
{
using sql_error::sql_error;
};
struct connection_error // 08xxx
: sql_error
{
using sql_error::sql_error;
explicit connection_error( const char* what );
};
struct sqlclient_unable_to_establish_sqlconnection // 08001
: connection_error
{
using connection_error::connection_error;
};
struct connection_does_not_exist // 08003
: connection_error
{
using connection_error::connection_error;
};
struct sqlserver_rejected_establishment_of_sqlconnection // 08004
: connection_error
{
using connection_error::connection_error;
};
struct connection_failure // 08006
: connection_error
{
using connection_error::connection_error;
};
struct transaction_resolution_unknown // 08007
: connection_error
{
using connection_error::connection_error;
};
struct protocol_violation // 08P01
: connection_error
{
using connection_error::connection_error;
};
struct triggered_action_exception // 09xxx
: sql_error
{
using sql_error::sql_error;
};
struct feature_not_supported // 0Axxx
: sql_error
{
using sql_error::sql_error;
};
struct invalid_transaction_initiation // 0Bxxx
: sql_error
{
using sql_error::sql_error;
};
struct locator_exception // 0Fxxx
: sql_error
{
using sql_error::sql_error;
};
struct invalid_locator_specification // 0F001
: locator_exception
{
using locator_exception::locator_exception;
};
struct invalid_grantor // 0Lxxx
: sql_error
{
using sql_error::sql_error;
};
struct invalid_grant_operation // 0LP01
: invalid_grantor
{
using invalid_grantor::invalid_grantor;
};
struct invalid_role_specification // 0Pxxx
: sql_error
{
using sql_error::sql_error;
};
struct diagnostics_exception // 0Zxxx
: sql_error
{
using sql_error::sql_error;
};
struct stacked_diagnostics_accessed_without_active_handler // 0Z002
: diagnostics_exception
{
using diagnostics_exception::diagnostics_exception;
};
struct case_not_found // 20xxx
: sql_error
{
using sql_error::sql_error;
};
struct cardinality_violation // 21xxx
: sql_error
{
using sql_error::sql_error;
};
struct data_exception // 22xxx
: sql_error
{
using sql_error::sql_error;
};
struct array_subscript_error // 2202E
: data_exception
{
using data_exception::data_exception;
};
struct character_not_in_repertoire // 22021
: data_exception
{
using data_exception::data_exception;
};
struct datetime_field_overflow // 22008
: data_exception
{
using data_exception::data_exception;
};
struct division_by_zero // 22012
: data_exception
{
using data_exception::data_exception;
};
struct error_in_assignment // 22005
: data_exception
{
using data_exception::data_exception;
};
struct escape_character_conflict // 2200B
: data_exception
{
using data_exception::data_exception;
};
struct indicator_overflow // 22022
: data_exception
{
using data_exception::data_exception;
};
struct interval_field_overflow // 22015
: data_exception
{
using data_exception::data_exception;
};
struct invalid_argument_for_logarithm // 2201E
: data_exception
{
using data_exception::data_exception;
};
struct invalid_argument_for_ntile_function // 22014
: data_exception
{
using data_exception::data_exception;
};
struct invalid_argument_for_nth_value_function // 22016
: data_exception
{
using data_exception::data_exception;
};
struct invalid_argument_for_power_function // 2201F
: data_exception
{
using data_exception::data_exception;
};
struct invalid_argument_for_width_bucket_function // 2201G
: data_exception
{
using data_exception::data_exception;
};
struct invalid_character_value_for_cast // 22018
: data_exception
{
using data_exception::data_exception;
};
struct invalid_datetime_format // 22007
: data_exception
{
using data_exception::data_exception;
};
struct invalid_escape_character // 22019
: data_exception
{
using data_exception::data_exception;
};
struct invalid_escape_octet // 2200D
: data_exception
{
using data_exception::data_exception;
};
struct invalid_escape_sequence // 22025
: data_exception
{
using data_exception::data_exception;
};
struct nonstandard_use_of_escape_character // 22P06
: data_exception
{
using data_exception::data_exception;
};
struct invalid_indicator_parameter_value // 22010
: data_exception
{
using data_exception::data_exception;
};
struct invalid_parameter_value // 22023
: data_exception
{
using data_exception::data_exception;
};
struct invalid_preceding_or_following_size // 22013
: data_exception
{
using data_exception::data_exception;
};
struct invalid_regular_expression // 2201B
: data_exception
{
using data_exception::data_exception;
};
struct invalid_row_count_in_limit_clause // 2201W
: data_exception
{
using data_exception::data_exception;
};
struct invalid_row_count_in_result_offset_clause // 2201X
: data_exception
{
using data_exception::data_exception;
};
struct invalid_tablesample_argument // 2202H
: data_exception
{
using data_exception::data_exception;
};
struct invalid_tablesample_repeat // 2202G
: data_exception
{
using data_exception::data_exception;
};
struct invalid_time_zone_displacement_value // 22009
: data_exception
{
using data_exception::data_exception;
};
struct invalid_use_of_escape_character // 2200C
: data_exception
{
using data_exception::data_exception;
};
struct most_specific_type_mismatch // 2200G
: data_exception
{
using data_exception::data_exception;
};
struct null_value_not_allowed // 22004
: data_exception
{
using data_exception::data_exception;
};
struct null_value_no_indicator_parameter // 22002
: data_exception
{
using data_exception::data_exception;
};
struct numeric_value_out_of_range // 22003
: data_exception
{
using data_exception::data_exception;
};
struct sequence_generator_limit_exceeded // 2200H
: data_exception
{
using data_exception::data_exception;
};
struct string_data_length_mismatch // 22026
: data_exception
{
using data_exception::data_exception;
};
template<>
struct string_data_right_truncation< data_exception > // 22001
: data_exception
{
using data_exception::data_exception;
};
struct substring_error // 22011
: data_exception
{
using data_exception::data_exception;
};
struct trim_error // 22027
: data_exception
{
using data_exception::data_exception;
};
struct unterminated_c_string // 22024
: data_exception
{
using data_exception::data_exception;
};
struct zero_length_character_string // 2200F
: data_exception
{
using data_exception::data_exception;
};
struct floating_point_exception // 22P01
: data_exception
{
using data_exception::data_exception;
};
struct invalid_text_representation // 22P02
: data_exception
{
using data_exception::data_exception;
};
struct invalid_binary_representation // 22P03
: data_exception
{
using data_exception::data_exception;
};
struct bad_copy_file_format // 22P04
: data_exception
{
using data_exception::data_exception;
};
struct untranslatable_character // 22P05
: data_exception
{
using data_exception::data_exception;
};
struct not_an_xml_document // 2200L
: data_exception
{
using data_exception::data_exception;
};
struct invalid_xml_document // 2200M
: data_exception
{
using data_exception::data_exception;
};
struct invalid_xml_content // 2200N
: data_exception
{
using data_exception::data_exception;
};
struct invalid_xml_comment // 2200S
: data_exception
{
using data_exception::data_exception;
};
struct invalid_xml_processing_instruction // 2200T
: data_exception
{
using data_exception::data_exception;
};
struct duplicate_json_object_key_value // 22030
: data_exception
{
using data_exception::data_exception;
};
struct invalid_argument_for_sql_json_datetime_function // 22031
: data_exception
{
using data_exception::data_exception;
};
struct invalid_json_text // 22032
: data_exception
{
using data_exception::data_exception;
};
struct invalid_sql_json_subscript // 22033
: data_exception
{
using data_exception::data_exception;
};
struct more_than_one_sql_json_item // 22034
: data_exception
{
using data_exception::data_exception;
};
struct no_sql_json_item // 22035
: data_exception
{
using data_exception::data_exception;
};
struct non_numeric_sql_json_item // 22036
: data_exception
{
using data_exception::data_exception;
};
struct non_unique_keys_in_a_json_object // 22037
: data_exception
{
using data_exception::data_exception;
};
struct singleton_sql_json_item_required // 22038
: data_exception
{
using data_exception::data_exception;
};
struct sql_json_array_not_found // 22039
: data_exception
{
using data_exception::data_exception;
};
struct sql_json_member_not_found // 2203A
: data_exception
{
using data_exception::data_exception;
};
struct sql_json_number_not_found // 2203B
: data_exception
{
using data_exception::data_exception;
};
struct sql_json_object_not_found // 2203C
: data_exception
{
using data_exception::data_exception;
};
struct too_many_json_array_elements // 2203D
: data_exception
{
using data_exception::data_exception;
};
struct too_many_json_object_members // 2203E
: data_exception
{
using data_exception::data_exception;
};
struct sql_json_scalar_required // 2203F
: data_exception
{
using data_exception::data_exception;
};
struct integrity_constraint_violation // 23xxx
: sql_error
{
using sql_error::sql_error;
};
struct restrict_violation // 23001
: integrity_constraint_violation
{
using integrity_constraint_violation::integrity_constraint_violation;
};
struct not_null_violation // 23502
: integrity_constraint_violation
{
using integrity_constraint_violation::integrity_constraint_violation;
};
struct foreign_key_violation // 23503
: integrity_constraint_violation
{
using integrity_constraint_violation::integrity_constraint_violation;
};
struct unique_violation // 23505
: integrity_constraint_violation
{
using integrity_constraint_violation::integrity_constraint_violation;
};
struct check_violation // 23514
: integrity_constraint_violation
{
using integrity_constraint_violation::integrity_constraint_violation;
};
struct exclusion_violation // 23P01
: integrity_constraint_violation
{
using integrity_constraint_violation::integrity_constraint_violation;
};
struct invalid_cursor_state // 24xxx
: sql_error
{
using sql_error::sql_error;
};
struct invalid_transaction_state // 25xxx
: sql_error
{
using sql_error::sql_error;
};
struct active_sql_transaction // 25001
: invalid_transaction_state
{
using invalid_transaction_state::invalid_transaction_state;
};
struct branch_transaction_already_active // 25002
: invalid_transaction_state
{
using invalid_transaction_state::invalid_transaction_state;
};
struct held_cursor_requires_same_isolation_level // 25008
: invalid_transaction_state
{
using invalid_transaction_state::invalid_transaction_state;
};
struct inappropriate_access_mode_for_branch_transaction // 25003
: invalid_transaction_state
{
using invalid_transaction_state::invalid_transaction_state;
};
struct inappropriate_isolation_level_for_branch_transaction // 25004
: invalid_transaction_state
{
using invalid_transaction_state::invalid_transaction_state;
};
struct no_active_sql_transaction_for_branch_transaction // 25005
: invalid_transaction_state
{
using invalid_transaction_state::invalid_transaction_state;
};
struct read_only_sql_transaction // 25006
: invalid_transaction_state
{
using invalid_transaction_state::invalid_transaction_state;
};
struct schema_and_data_statement_mixing_not_supported // 25007
: invalid_transaction_state
{
using invalid_transaction_state::invalid_transaction_state;
};
struct no_active_sql_transaction // 25P01
: invalid_transaction_state
{
using invalid_transaction_state::invalid_transaction_state;
};
struct in_failed_sql_transaction // 25P02
: invalid_transaction_state
{
using invalid_transaction_state::invalid_transaction_state;
};
struct idle_in_transaction_session_timeout // 25P03
: invalid_transaction_state
{
using invalid_transaction_state::invalid_transaction_state;
};
struct invalid_sql_statement_name // 26xxx
: sql_error
{
using sql_error::sql_error;
};
struct triggered_data_change_violation // 27xxx
: sql_error
{
using sql_error::sql_error;
};
struct invalid_authorization_specification // 28xxx
: sql_error
{
using sql_error::sql_error;
};
struct invalid_password // 28P01
: invalid_authorization_specification
{
using invalid_authorization_specification::invalid_authorization_specification;
};
struct dependent_privilege_descriptors_still_exist // 2Bxxx
: sql_error
{
using sql_error::sql_error;
};
struct dependent_objects_still_exist // 2BP01
: dependent_privilege_descriptors_still_exist
{
using dependent_privilege_descriptors_still_exist::dependent_privilege_descriptors_still_exist;
};
struct invalid_transaction_termination // 2Dxxx
: sql_error
{
using sql_error::sql_error;
};
struct sql_routine_exception // 2Fxxx
: sql_error
{
using sql_error::sql_error;
};
template<>
struct modifying_sql_data_not_permitted< sql_routine_exception > // 2F002
: sql_routine_exception
{
using sql_routine_exception::sql_routine_exception;
};
template<>
struct prohibited_sql_statement_attempted< sql_routine_exception > // 2F003
: sql_routine_exception
{
using sql_routine_exception::sql_routine_exception;
};
template<>
struct reading_sql_data_not_permitted< sql_routine_exception > // 2F004
: sql_routine_exception
{
using sql_routine_exception::sql_routine_exception;
};
struct function_executed_no_return_statement // 2F005
: sql_routine_exception
{
using sql_routine_exception::sql_routine_exception;
};
struct invalid_cursor_name // 34xxx
: sql_error
{
using sql_error::sql_error;
};
struct external_routine_exception // 38xxx
: sql_error
{
using sql_error::sql_error;
};
struct containing_sql_not_permitted // 38001
: external_routine_exception
{
using external_routine_exception::external_routine_exception;
};
template<>
struct modifying_sql_data_not_permitted< external_routine_exception > // 38002
: external_routine_exception
{
using external_routine_exception::external_routine_exception;
};
template<>
struct prohibited_sql_statement_attempted< external_routine_exception > // 38003
: external_routine_exception
{
using external_routine_exception::external_routine_exception;
};
template<>
struct reading_sql_data_not_permitted< external_routine_exception > // 38004
: external_routine_exception
{
using external_routine_exception::external_routine_exception;
};
struct external_routine_invocation_exception // 39xxx
: sql_error
{
using sql_error::sql_error;
};
struct invalid_sqlstate_returned // 39001
: external_routine_invocation_exception
{
using external_routine_invocation_exception::external_routine_invocation_exception;
};
struct external_null_value_not_allowed // 39004
: external_routine_invocation_exception
{
using external_routine_invocation_exception::external_routine_invocation_exception;
};
struct trigger_protocol_violated // 39P01
: external_routine_invocation_exception
{
using external_routine_invocation_exception::external_routine_invocation_exception;
};
struct srf_protocol_violated // 39P02
: external_routine_invocation_exception
{
using external_routine_invocation_exception::external_routine_invocation_exception;
};
struct event_trigger_protocol_violated // 39P03
: external_routine_invocation_exception
{
using external_routine_invocation_exception::external_routine_invocation_exception;
};
struct savepoint_exception // 3Bxxx
: sql_error
{
using sql_error::sql_error;
};
struct invalid_savepoint_specification // 3B001
: savepoint_exception
{
using savepoint_exception::savepoint_exception;
};
struct invalid_catalog_name // 3Dxxx
: sql_error
{
using sql_error::sql_error;
};
struct invalid_schema_name // 3Fxxx
: sql_error
{
using sql_error::sql_error;
};
struct transaction_rollback // 40xxx
: sql_error
{
using sql_error::sql_error;
};
struct serialization_failure // 40001
: transaction_rollback
{
using transaction_rollback::transaction_rollback;
};
struct transaction_integrity_constraint_violation // 40002
: transaction_rollback
{
using transaction_rollback::transaction_rollback;
};
struct statement_completion_unknown // 40003
: transaction_rollback
{
using transaction_rollback::transaction_rollback;
};
struct deadlock_detected // 40P01
: transaction_rollback
{
using transaction_rollback::transaction_rollback;
};
struct syntax_error_or_access_rule_violation // 42xxx
: sql_error
{
using sql_error::sql_error;
};
struct insufficient_privilege // 42501
: syntax_error_or_access_rule_violation
{
using syntax_error_or_access_rule_violation::syntax_error_or_access_rule_violation;
};
struct syntax_error // 42601
: syntax_error_or_access_rule_violation
{
using syntax_error_or_access_rule_violation::syntax_error_or_access_rule_violation;
};
struct invalid_name // 42602
: syntax_error_or_access_rule_violation
{
using syntax_error_or_access_rule_violation::syntax_error_or_access_rule_violation;
};
struct invalid_column_definition // 42611
: syntax_error_or_access_rule_violation
{
using syntax_error_or_access_rule_violation::syntax_error_or_access_rule_violation;
};
struct name_too_long // 42622
: syntax_error_or_access_rule_violation
{
using syntax_error_or_access_rule_violation::syntax_error_or_access_rule_violation;
};
struct duplicate_column // 42701
: syntax_error_or_access_rule_violation
{
using syntax_error_or_access_rule_violation::syntax_error_or_access_rule_violation;
};
struct ambiguous_column // 42702
: syntax_error_or_access_rule_violation
{
using syntax_error_or_access_rule_violation::syntax_error_or_access_rule_violation;
};
struct undefined_column // 42703
: syntax_error_or_access_rule_violation
{
using syntax_error_or_access_rule_violation::syntax_error_or_access_rule_violation;
};
struct undefined_object // 42704
: syntax_error_or_access_rule_violation
{
using syntax_error_or_access_rule_violation::syntax_error_or_access_rule_violation;
};
struct duplicate_object // 42710
: syntax_error_or_access_rule_violation
{
using syntax_error_or_access_rule_violation::syntax_error_or_access_rule_violation;
};
struct duplicate_alias // 42712
: syntax_error_or_access_rule_violation
{
using syntax_error_or_access_rule_violation::syntax_error_or_access_rule_violation;
};
struct duplicate_function // 42723
: syntax_error_or_access_rule_violation
{
using syntax_error_or_access_rule_violation::syntax_error_or_access_rule_violation;
};
struct ambiguous_function // 42725
: syntax_error_or_access_rule_violation
{
using syntax_error_or_access_rule_violation::syntax_error_or_access_rule_violation;
};
struct grouping_error // 42803
: syntax_error_or_access_rule_violation
{
using syntax_error_or_access_rule_violation::syntax_error_or_access_rule_violation;
};
struct datatype_mismatch // 42804
: syntax_error_or_access_rule_violation
{
using syntax_error_or_access_rule_violation::syntax_error_or_access_rule_violation;
};
struct wrong_object_type // 42809
: syntax_error_or_access_rule_violation
{
using syntax_error_or_access_rule_violation::syntax_error_or_access_rule_violation;
};
struct invalid_foreign_key // 42830
: syntax_error_or_access_rule_violation
{
using syntax_error_or_access_rule_violation::syntax_error_or_access_rule_violation;
};
struct cannot_coerce // 42846
: syntax_error_or_access_rule_violation
{
using syntax_error_or_access_rule_violation::syntax_error_or_access_rule_violation;
};
struct undefined_function //
gitextract_iares_uf/
├── .clang-format
├── .clang-tidy
├── .github/
│ ├── conan/
│ │ ├── conanfile.py
│ │ └── profiles/
│ │ ├── clangcl
│ │ └── msvc
│ └── workflows/
│ ├── clang-analyze.yml
│ ├── clang-format.yml
│ ├── clang-tidy.yml
│ ├── code-coverage.yml
│ ├── linux.yml
│ ├── macos.yml
│ ├── sanitizer.yml
│ └── windows.yml
├── .gitignore
├── CMakeLists.txt
├── CMakePresets.json
├── LICENSE_1_0.txt
├── Makefile
├── README.md
├── doc/
│ ├── Aggregate-Support.md
│ ├── Binary-Data.md
│ ├── Bulk-Transfer.md
│ ├── Connection-Pool.md
│ ├── Connection.md
│ ├── Error-Handling.md
│ ├── Getting-Started.md
│ ├── Installation.md
│ ├── Large-Object.md
│ ├── Parameter-Type-Conversion.md
│ ├── Performance.md
│ ├── Requirements.md
│ ├── Result-Type-Conversion.md
│ ├── Result.md
│ ├── Statement.md
│ ├── TOC.md
│ └── Transaction.md
├── example/
│ ├── CMakeLists.txt
│ └── get_version/
│ ├── CMakeLists.txt
│ └── main.cpp
├── include/
│ └── tao/
│ ├── pq/
│ │ ├── access_mode.hpp
│ │ ├── binary.hpp
│ │ ├── bind.hpp
│ │ ├── connection.hpp
│ │ ├── connection_pool.hpp
│ │ ├── connection_status.hpp
│ │ ├── exception.hpp
│ │ ├── field.hpp
│ │ ├── internal/
│ │ │ ├── aggregate.hpp
│ │ │ ├── demangle.hpp
│ │ │ ├── exclusive_scan.hpp
│ │ │ ├── format_as.hpp
│ │ │ ├── from_chars.hpp
│ │ │ ├── gen.hpp
│ │ │ ├── parameter_traits_helper.hpp
│ │ │ ├── poll.hpp
│ │ │ ├── pool.hpp
│ │ │ ├── resize_uninitialized.hpp
│ │ │ ├── strtox.hpp
│ │ │ ├── unreachable.hpp
│ │ │ └── zsv.hpp
│ │ ├── is_aggregate.hpp
│ │ ├── is_array.hpp
│ │ ├── isolation_level.hpp
│ │ ├── large_object.hpp
│ │ ├── log.hpp
│ │ ├── notification.hpp
│ │ ├── null.hpp
│ │ ├── oid.hpp
│ │ ├── parameter.hpp
│ │ ├── parameter_traits.hpp
│ │ ├── parameter_traits_aggregate.hpp
│ │ ├── parameter_traits_array.hpp
│ │ ├── parameter_traits_optional.hpp
│ │ ├── parameter_traits_pair.hpp
│ │ ├── parameter_traits_tuple.hpp
│ │ ├── pipeline.hpp
│ │ ├── pipeline_status.hpp
│ │ ├── poll.hpp
│ │ ├── result.hpp
│ │ ├── result_status.hpp
│ │ ├── result_traits.hpp
│ │ ├── result_traits_aggregate.hpp
│ │ ├── result_traits_array.hpp
│ │ ├── result_traits_optional.hpp
│ │ ├── result_traits_pair.hpp
│ │ ├── result_traits_tuple.hpp
│ │ ├── row.hpp
│ │ ├── table_field.hpp
│ │ ├── table_reader.hpp
│ │ ├── table_row.hpp
│ │ ├── table_writer.hpp
│ │ ├── transaction.hpp
│ │ ├── transaction_base.hpp
│ │ ├── transaction_status.hpp
│ │ └── version.hpp
│ └── pq.hpp
├── src/
│ └── lib/
│ └── pq/
│ ├── connection.cpp
│ ├── connection_pool.cpp
│ ├── exception.cpp
│ ├── field.cpp
│ ├── internal/
│ │ ├── demangle.cpp
│ │ ├── poll.cpp
│ │ └── strtox.cpp
│ ├── large_object.cpp
│ ├── parameter_traits.cpp
│ ├── pipeline.cpp
│ ├── result.cpp
│ ├── result_traits.cpp
│ ├── result_traits_array.cpp
│ ├── row.cpp
│ ├── table_field.cpp
│ ├── table_reader.cpp
│ ├── table_row.cpp
│ ├── table_writer.cpp
│ ├── transaction.cpp
│ └── transaction_base.cpp
└── test/
├── CMakeLists.txt
├── integration/
│ ├── aggregate.cpp
│ ├── array.cpp
│ ├── basic_datatypes.cpp
│ ├── chunk_mode.cpp
│ ├── connection.cpp
│ ├── connection_pool.cpp
│ ├── example.cpp
│ ├── exception.cpp
│ ├── large_object.cpp
│ ├── log.cpp
│ ├── notifications.cpp
│ ├── parameter.cpp
│ ├── password.cpp
│ ├── pipeline_mode.cpp
│ ├── result.cpp
│ ├── row.cpp
│ ├── single_row_mode.cpp
│ ├── table_reader.cpp
│ ├── table_writer.cpp
│ ├── traits.cpp
│ └── transaction.cpp
├── unit/
│ ├── getenv.cpp
│ ├── parameter_type.cpp
│ ├── resize_uninitialized.cpp
│ ├── result_type.cpp
│ └── strtox.cpp
└── utils/
├── compare.hpp
├── getenv.hpp
└── macros.hpp
SYMBOL INDEX (1002 symbols across 104 files)
FILE: .github/conan/conanfile.py
class TaopqRequirements (line 4) | class TaopqRequirements(ConanFile):
method layout (line 17) | def layout(self):
method requirements (line 20) | def requirements(self):
method generate (line 23) | def generate(self):
FILE: example/get_version/main.cpp
function get_env (line 8) | static std::string get_env( std::string_view name )
function main (line 26) | int main()
FILE: include/tao/pq/access_mode.hpp
type tao::pq (line 13) | namespace tao::pq
type access_mode (line 15) | enum class access_mode : std::uint8_t
function taopq_format_as (line 22) | [[nodiscard]] constexpr auto taopq_format_as( const access_mode am ) n...
FILE: include/tao/pq/binary.hpp
type tao::pq (line 12) | namespace tao::pq
function to_binary_view (line 17) | [[nodiscard]] auto to_binary_view( const auto* data, const std::size_t...
function to_binary_view (line 23) | [[nodiscard]] auto to_binary_view( const auto& value ) noexcept -> bin...
function to_binary (line 28) | [[nodiscard]] auto to_binary( const auto* data, const std::size_t size...
function to_binary (line 35) | [[nodiscard]] auto to_binary( const auto& value ) -> binary
FILE: include/tao/pq/bind.hpp
type tao::pq (line 8) | namespace tao::pq
type bind (line 11) | struct bind
FILE: include/tao/pq/connection.hpp
type tao::pq (line 35) | namespace tao::pq
class connection_pool (line 37) | class connection_pool
class pipeline (line 38) | class pipeline
class table_reader (line 39) | class table_reader
class table_writer (line 40) | class table_writer
type internal (line 42) | namespace internal
class top_level_transaction (line 44) | class top_level_transaction
class top_level_subtransaction (line 45) | class top_level_subtransaction
class nested_subtransaction (line 46) | class nested_subtransaction
class connection (line 50) | class connection final
method timeout_end (line 86) | [[nodiscard]] auto timeout_end( const std::chrono::steady_clock::tim...
class private_key (line 107) | class private_key final
method private_key (line 109) | private_key() = default;
method connection (line 117) | connection( const connection& ) = delete;
method connection (line 118) | connection( connection&& ) = delete;
method poll_callback (line 128) | [[nodiscard]] auto poll_callback() const noexcept -> decltype( auto )
method set_poll_callback (line 133) | void set_poll_callback( std::function< poll::callback > poll_cb ) no...
method reset_poll_callback (line 138) | void reset_poll_callback()
method notification_handler (line 143) | [[nodiscard]] auto notification_handler() const noexcept -> decltype...
method set_notification_handler (line 148) | void set_notification_handler( std::function< void( const notificati...
method reset_notification_handler (line 153) | void reset_notification_handler() noexcept
method log_handler (line 164) | [[nodiscard]] auto log_handler() const noexcept -> decltype( auto )
method set_log_handler (line 169) | void set_log_handler( const std::shared_ptr< pq::log >& log ) noexcept
method reset_log_handler (line 174) | void reset_log_handler() noexcept
method is_open (line 188) | [[nodiscard]] auto is_open() const noexcept -> bool
method is_idle (line 193) | [[nodiscard]] auto is_idle() const noexcept -> bool
method execute (line 216) | auto execute( const internal::zsv statement, As&&... as )
method timeout (line 233) | [[nodiscard]] auto timeout() const noexcept -> decltype( auto )
method set_timeout (line 238) | void set_timeout( const std::chrono::milliseconds timeout ) noexcept
method reset_timeout (line 243) | void reset_timeout() noexcept
method underlying_raw_ptr (line 250) | [[nodiscard]] auto underlying_raw_ptr() noexcept -> PGconn*
method underlying_raw_ptr (line 255) | [[nodiscard]] auto underlying_raw_ptr() const noexcept -> const PGconn*
FILE: include/tao/pq/connection_pool.hpp
type tao::pq (line 24) | namespace tao::pq
class connection_pool (line 26) | class connection_pool
method v_is_valid (line 37) | [[nodiscard]] auto v_is_valid( pq::connection& c ) const noexcept ->...
class private_key (line 44) | class private_key final
method private_key (line 46) | private_key() = default;
method get (line 53) | void get() const = delete;
method create (line 56) | [[nodiscard]] static auto create( const std::string_view connection_...
method timeout (line 61) | [[nodiscard]] auto timeout() const noexcept -> decltype( auto )
method set_timeout (line 66) | void set_timeout( const std::chrono::milliseconds timeout ) noexcept
method reset_timeout (line 71) | void reset_timeout() noexcept
method poll_callback (line 76) | [[nodiscard]] auto poll_callback() const noexcept -> decltype( auto )
method set_poll_callback (line 81) | void set_poll_callback( std::function< poll::callback > poll_cb ) no...
method reset_poll_callback (line 86) | void reset_poll_callback()
method execute (line 94) | auto execute( const internal::zsv statement, As&&... as )
FILE: include/tao/pq/connection_status.hpp
type tao::pq (line 15) | namespace tao::pq
type connection_status (line 17) | enum class connection_status : std::uint8_t
function taopq_format_as (line 23) | [[nodiscard]] constexpr auto taopq_format_as( const connection_status ...
FILE: include/tao/pq/exception.hpp
type tao::pq (line 14) | namespace tao::pq
type error (line 16) | struct error
type timeout_reached (line 22) | struct timeout_reached
type network_error (line 28) | struct network_error
type sql_error (line 35) | struct sql_error
type string_data_right_truncation (line 46) | struct string_data_right_truncation
type modifying_sql_data_not_permitted (line 49) | struct modifying_sql_data_not_permitted
type prohibited_sql_statement_attempted (line 52) | struct prohibited_sql_statement_attempted
type reading_sql_data_not_permitted (line 55) | struct reading_sql_data_not_permitted
type success (line 57) | struct success // 00xxx
type warning (line 63) | struct warning // 01xxx
type null_value_eliminated_in_set_function (line 69) | struct null_value_eliminated_in_set_function // 01003
type string_data_right_truncation< warning > (line 76) | struct string_data_right_truncation< warning > // 01004
type privilege_not_revoked (line 82) | struct privilege_not_revoked // 01006
type privilege_not_granted (line 88) | struct privilege_not_granted // 01007
type implicit_zero_bit_padding (line 94) | struct implicit_zero_bit_padding // 01008
type dynamic_result_sets_returned (line 100) | struct dynamic_result_sets_returned // 0100C
type deprecated_feature (line 106) | struct deprecated_feature // 01P01
type no_data (line 112) | struct no_data // 02xxx
type no_additional_dynamic_result_sets_returned (line 118) | struct no_additional_dynamic_result_sets_returned // 02001
type sql_statement_not_yet_complete (line 124) | struct sql_statement_not_yet_complete // 03xxx
type connection_error (line 130) | struct connection_error // 08xxx
type sqlclient_unable_to_establish_sqlconnection (line 138) | struct sqlclient_unable_to_establish_sqlconnection // 08001
type connection_does_not_exist (line 144) | struct connection_does_not_exist // 08003
type sqlserver_rejected_establishment_of_sqlconnection (line 150) | struct sqlserver_rejected_establishment_of_sqlconnection // 08004
type connection_failure (line 156) | struct connection_failure // 08006
type transaction_resolution_unknown (line 162) | struct transaction_resolution_unknown // 08007
type protocol_violation (line 168) | struct protocol_violation // 08P01
type triggered_action_exception (line 174) | struct triggered_action_exception // 09xxx
type feature_not_supported (line 180) | struct feature_not_supported // 0Axxx
type invalid_transaction_initiation (line 186) | struct invalid_transaction_initiation // 0Bxxx
type locator_exception (line 192) | struct locator_exception // 0Fxxx
type invalid_locator_specification (line 198) | struct invalid_locator_specification // 0F001
type invalid_grantor (line 204) | struct invalid_grantor // 0Lxxx
type invalid_grant_operation (line 210) | struct invalid_grant_operation // 0LP01
type invalid_role_specification (line 216) | struct invalid_role_specification // 0Pxxx
type diagnostics_exception (line 222) | struct diagnostics_exception // 0Zxxx
type stacked_diagnostics_accessed_without_active_handler (line 228) | struct stacked_diagnostics_accessed_without_active_handler // 0Z002
type case_not_found (line 234) | struct case_not_found // 20xxx
type cardinality_violation (line 240) | struct cardinality_violation // 21xxx
type data_exception (line 246) | struct data_exception // 22xxx
type array_subscript_error (line 252) | struct array_subscript_error // 2202E
type character_not_in_repertoire (line 258) | struct character_not_in_repertoire // 22021
type datetime_field_overflow (line 264) | struct datetime_field_overflow // 22008
type division_by_zero (line 270) | struct division_by_zero // 22012
type error_in_assignment (line 276) | struct error_in_assignment // 22005
type escape_character_conflict (line 282) | struct escape_character_conflict // 2200B
type indicator_overflow (line 288) | struct indicator_overflow // 22022
type interval_field_overflow (line 294) | struct interval_field_overflow // 22015
type invalid_argument_for_logarithm (line 300) | struct invalid_argument_for_logarithm // 2201E
type invalid_argument_for_ntile_function (line 306) | struct invalid_argument_for_ntile_function // 22014
type invalid_argument_for_nth_value_function (line 312) | struct invalid_argument_for_nth_value_function // 22016
type invalid_argument_for_power_function (line 318) | struct invalid_argument_for_power_function // 2201F
type invalid_argument_for_width_bucket_function (line 324) | struct invalid_argument_for_width_bucket_function // 2201G
type invalid_character_value_for_cast (line 330) | struct invalid_character_value_for_cast // 22018
type invalid_datetime_format (line 336) | struct invalid_datetime_format // 22007
type invalid_escape_character (line 342) | struct invalid_escape_character // 22019
type invalid_escape_octet (line 348) | struct invalid_escape_octet // 2200D
type invalid_escape_sequence (line 354) | struct invalid_escape_sequence // 22025
type nonstandard_use_of_escape_character (line 360) | struct nonstandard_use_of_escape_character // 22P06
type invalid_indicator_parameter_value (line 366) | struct invalid_indicator_parameter_value // 22010
type invalid_parameter_value (line 372) | struct invalid_parameter_value // 22023
type invalid_preceding_or_following_size (line 378) | struct invalid_preceding_or_following_size // 22013
type invalid_regular_expression (line 384) | struct invalid_regular_expression // 2201B
type invalid_row_count_in_limit_clause (line 390) | struct invalid_row_count_in_limit_clause // 2201W
type invalid_row_count_in_result_offset_clause (line 396) | struct invalid_row_count_in_result_offset_clause // 2201X
type invalid_tablesample_argument (line 402) | struct invalid_tablesample_argument // 2202H
type invalid_tablesample_repeat (line 408) | struct invalid_tablesample_repeat // 2202G
type invalid_time_zone_displacement_value (line 414) | struct invalid_time_zone_displacement_value // 22009
type invalid_use_of_escape_character (line 420) | struct invalid_use_of_escape_character // 2200C
type most_specific_type_mismatch (line 426) | struct most_specific_type_mismatch // 2200G
type null_value_not_allowed (line 432) | struct null_value_not_allowed // 22004
type null_value_no_indicator_parameter (line 438) | struct null_value_no_indicator_parameter // 22002
type numeric_value_out_of_range (line 444) | struct numeric_value_out_of_range // 22003
type sequence_generator_limit_exceeded (line 450) | struct sequence_generator_limit_exceeded // 2200H
type string_data_length_mismatch (line 456) | struct string_data_length_mismatch // 22026
type string_data_right_truncation< data_exception > (line 463) | struct string_data_right_truncation< data_exception > // 22001
type substring_error (line 469) | struct substring_error // 22011
type trim_error (line 475) | struct trim_error // 22027
type unterminated_c_string (line 481) | struct unterminated_c_string // 22024
type zero_length_character_string (line 487) | struct zero_length_character_string // 2200F
type floating_point_exception (line 493) | struct floating_point_exception // 22P01
type invalid_text_representation (line 499) | struct invalid_text_representation // 22P02
type invalid_binary_representation (line 505) | struct invalid_binary_representation // 22P03
type bad_copy_file_format (line 511) | struct bad_copy_file_format // 22P04
type untranslatable_character (line 517) | struct untranslatable_character // 22P05
type not_an_xml_document (line 523) | struct not_an_xml_document // 2200L
type invalid_xml_document (line 529) | struct invalid_xml_document // 2200M
type invalid_xml_content (line 535) | struct invalid_xml_content // 2200N
type invalid_xml_comment (line 541) | struct invalid_xml_comment // 2200S
type invalid_xml_processing_instruction (line 547) | struct invalid_xml_processing_instruction // 2200T
type duplicate_json_object_key_value (line 553) | struct duplicate_json_object_key_value // 22030
type invalid_argument_for_sql_json_datetime_function (line 559) | struct invalid_argument_for_sql_json_datetime_function // 22031
type invalid_json_text (line 565) | struct invalid_json_text // 22032
type invalid_sql_json_subscript (line 571) | struct invalid_sql_json_subscript // 22033
type more_than_one_sql_json_item (line 577) | struct more_than_one_sql_json_item // 22034
type no_sql_json_item (line 583) | struct no_sql_json_item // 22035
type non_numeric_sql_json_item (line 589) | struct non_numeric_sql_json_item // 22036
type non_unique_keys_in_a_json_object (line 595) | struct non_unique_keys_in_a_json_object // 22037
type singleton_sql_json_item_required (line 601) | struct singleton_sql_json_item_required // 22038
type sql_json_array_not_found (line 607) | struct sql_json_array_not_found // 22039
type sql_json_member_not_found (line 613) | struct sql_json_member_not_found // 2203A
type sql_json_number_not_found (line 619) | struct sql_json_number_not_found // 2203B
type sql_json_object_not_found (line 625) | struct sql_json_object_not_found // 2203C
type too_many_json_array_elements (line 631) | struct too_many_json_array_elements // 2203D
type too_many_json_object_members (line 637) | struct too_many_json_object_members // 2203E
type sql_json_scalar_required (line 643) | struct sql_json_scalar_required // 2203F
type integrity_constraint_violation (line 649) | struct integrity_constraint_violation // 23xxx
type restrict_violation (line 655) | struct restrict_violation // 23001
type not_null_violation (line 661) | struct not_null_violation // 23502
type foreign_key_violation (line 667) | struct foreign_key_violation // 23503
type unique_violation (line 673) | struct unique_violation // 23505
type check_violation (line 679) | struct check_violation // 23514
type exclusion_violation (line 685) | struct exclusion_violation // 23P01
type invalid_cursor_state (line 691) | struct invalid_cursor_state // 24xxx
type invalid_transaction_state (line 697) | struct invalid_transaction_state // 25xxx
type active_sql_transaction (line 703) | struct active_sql_transaction // 25001
type branch_transaction_already_active (line 709) | struct branch_transaction_already_active // 25002
type held_cursor_requires_same_isolation_level (line 715) | struct held_cursor_requires_same_isolation_level // 25008
type inappropriate_access_mode_for_branch_transaction (line 721) | struct inappropriate_access_mode_for_branch_transaction // 25003
type inappropriate_isolation_level_for_branch_transaction (line 727) | struct inappropriate_isolation_level_for_branch_transaction // 25004
type no_active_sql_transaction_for_branch_transaction (line 733) | struct no_active_sql_transaction_for_branch_transaction // 25005
type read_only_sql_transaction (line 739) | struct read_only_sql_transaction // 25006
type schema_and_data_statement_mixing_not_supported (line 745) | struct schema_and_data_statement_mixing_not_supported // 25007
type no_active_sql_transaction (line 751) | struct no_active_sql_transaction // 25P01
type in_failed_sql_transaction (line 757) | struct in_failed_sql_transaction // 25P02
type idle_in_transaction_session_timeout (line 763) | struct idle_in_transaction_session_timeout // 25P03
type invalid_sql_statement_name (line 769) | struct invalid_sql_statement_name // 26xxx
type triggered_data_change_violation (line 775) | struct triggered_data_change_violation // 27xxx
type invalid_authorization_specification (line 781) | struct invalid_authorization_specification // 28xxx
type invalid_password (line 787) | struct invalid_password // 28P01
type dependent_privilege_descriptors_still_exist (line 793) | struct dependent_privilege_descriptors_still_exist // 2Bxxx
type dependent_objects_still_exist (line 799) | struct dependent_objects_still_exist // 2BP01
type invalid_transaction_termination (line 805) | struct invalid_transaction_termination // 2Dxxx
type sql_routine_exception (line 811) | struct sql_routine_exception // 2Fxxx
type modifying_sql_data_not_permitted< sql_routine_exception > (line 818) | struct modifying_sql_data_not_permitted< sql_routine_exception > // 2...
type prohibited_sql_statement_attempted< sql_routine_exception > (line 825) | struct prohibited_sql_statement_attempted< sql_routine_exception > //...
type reading_sql_data_not_permitted< sql_routine_exception > (line 832) | struct reading_sql_data_not_permitted< sql_routine_exception > // 2F004
type function_executed_no_return_statement (line 838) | struct function_executed_no_return_statement // 2F005
type invalid_cursor_name (line 844) | struct invalid_cursor_name // 34xxx
type external_routine_exception (line 850) | struct external_routine_exception // 38xxx
type containing_sql_not_permitted (line 856) | struct containing_sql_not_permitted // 38001
type modifying_sql_data_not_permitted< external_routine_exception > (line 863) | struct modifying_sql_data_not_permitted< external_routine_exception > ...
type prohibited_sql_statement_attempted< external_routine_exception > (line 870) | struct prohibited_sql_statement_attempted< external_routine_exception ...
type reading_sql_data_not_permitted< external_routine_exception > (line 877) | struct reading_sql_data_not_permitted< external_routine_exception > /...
type external_routine_invocation_exception (line 883) | struct external_routine_invocation_exception // 39xxx
type invalid_sqlstate_returned (line 889) | struct invalid_sqlstate_returned // 39001
type external_null_value_not_allowed (line 895) | struct external_null_value_not_allowed // 39004
type trigger_protocol_violated (line 901) | struct trigger_protocol_violated // 39P01
type srf_protocol_violated (line 907) | struct srf_protocol_violated // 39P02
type event_trigger_protocol_violated (line 913) | struct event_trigger_protocol_violated // 39P03
type savepoint_exception (line 919) | struct savepoint_exception // 3Bxxx
type invalid_savepoint_specification (line 925) | struct invalid_savepoint_specification // 3B001
type invalid_catalog_name (line 931) | struct invalid_catalog_name // 3Dxxx
type invalid_schema_name (line 937) | struct invalid_schema_name // 3Fxxx
type transaction_rollback (line 943) | struct transaction_rollback // 40xxx
type serialization_failure (line 949) | struct serialization_failure // 40001
type transaction_integrity_constraint_violation (line 955) | struct transaction_integrity_constraint_violation // 40002
type statement_completion_unknown (line 961) | struct statement_completion_unknown // 40003
type deadlock_detected (line 967) | struct deadlock_detected // 40P01
type syntax_error_or_access_rule_violation (line 973) | struct syntax_error_or_access_rule_violation // 42xxx
type insufficient_privilege (line 979) | struct insufficient_privilege // 42501
type syntax_error (line 985) | struct syntax_error // 42601
type invalid_name (line 991) | struct invalid_name // 42602
type invalid_column_definition (line 997) | struct invalid_column_definition // 42611
type name_too_long (line 1003) | struct name_too_long // 42622
type duplicate_column (line 1009) | struct duplicate_column // 42701
type ambiguous_column (line 1015) | struct ambiguous_column // 42702
type undefined_column (line 1021) | struct undefined_column // 42703
type undefined_object (line 1027) | struct undefined_object // 42704
type duplicate_object (line 1033) | struct duplicate_object // 42710
type duplicate_alias (line 1039) | struct duplicate_alias // 42712
type duplicate_function (line 1045) | struct duplicate_function // 42723
type ambiguous_function (line 1051) | struct ambiguous_function // 42725
type grouping_error (line 1057) | struct grouping_error // 42803
type datatype_mismatch (line 1063) | struct datatype_mismatch // 42804
type wrong_object_type (line 1069) | struct wrong_object_type // 42809
type invalid_foreign_key (line 1075) | struct invalid_foreign_key // 42830
type cannot_coerce (line 1081) | struct cannot_coerce // 42846
type undefined_function (line 1087) | struct undefined_function // 42883
type generated_always (line 1093) | struct generated_always // 428C9
type reserved_name (line 1099) | struct reserved_name // 42939
type undefined_table (line 1105) | struct undefined_table // 42P01
type undefined_parameter (line 1111) | struct undefined_parameter // 42P02
type duplicate_cursor (line 1117) | struct duplicate_cursor // 42P03
type duplicate_database (line 1123) | struct duplicate_database // 42P04
type duplicate_prepared_statement (line 1129) | struct duplicate_prepared_statement // 42P05
type duplicate_schema (line 1135) | struct duplicate_schema // 42P06
type duplicate_table (line 1141) | struct duplicate_table // 42P07
type ambiguous_parameter (line 1147) | struct ambiguous_parameter // 42P08
type ambiguous_alias (line 1153) | struct ambiguous_alias // 42P09
type invalid_column_reference (line 1159) | struct invalid_column_reference // 42P10
type invalid_cursor_definition (line 1165) | struct invalid_cursor_definition // 42P11
type invalid_database_definition (line 1171) | struct invalid_database_definition // 42P12
type invalid_function_definition (line 1177) | struct invalid_function_definition // 42P13
type invalid_prepared_statement_definition (line 1183) | struct invalid_prepared_statement_definition // 42P14
type invalid_schema_definition (line 1189) | struct invalid_schema_definition // 42P15
type invalid_table_definition (line 1195) | struct invalid_table_definition // 42P16
type invalid_object_definition (line 1201) | struct invalid_object_definition // 42P17
type indeterminate_datatype (line 1207) | struct indeterminate_datatype // 42P18
type invalid_recursion (line 1213) | struct invalid_recursion // 42P19
type windowing_error (line 1219) | struct windowing_error // 42P20
type collation_mismatch (line 1225) | struct collation_mismatch // 42P21
type indeterminate_collation (line 1231) | struct indeterminate_collation // 42P22
type with_check_option_violation (line 1237) | struct with_check_option_violation // 44xxx
type insufficient_resources (line 1243) | struct insufficient_resources // 53xxx
type disk_full (line 1249) | struct disk_full // 53100
type out_of_memory (line 1255) | struct out_of_memory // 53200
type too_many_connections (line 1261) | struct too_many_connections // 53300
type configuration_limit_exceeded (line 1267) | struct configuration_limit_exceeded // 53400
type program_limit_exceeded (line 1273) | struct program_limit_exceeded // 54xxx
type statement_too_complex (line 1279) | struct statement_too_complex // 54001
type too_many_columns (line 1285) | struct too_many_columns // 54011
type too_many_arguments (line 1291) | struct too_many_arguments // 54023
type object_not_in_prerequisite_state (line 1297) | struct object_not_in_prerequisite_state // 55xxx
type object_in_use (line 1303) | struct object_in_use // 55006
type cant_change_runtime_param (line 1309) | struct cant_change_runtime_param // 55P02
type lock_not_available (line 1315) | struct lock_not_available // 55P03
type unsafe_new_enum_value_usage (line 1321) | struct unsafe_new_enum_value_usage // 55P04
type operator_intervention (line 1327) | struct operator_intervention // 57xxx
type query_canceled (line 1333) | struct query_canceled // 57014
type admin_shutdown (line 1339) | struct admin_shutdown // 57P01
type crash_shutdown (line 1345) | struct crash_shutdown // 57P02
type cannot_connect_now (line 1351) | struct cannot_connect_now // 57P03
type database_dropped (line 1357) | struct database_dropped // 57P04
type system_error (line 1363) | struct system_error // 58xxx
type io_error (line 1369) | struct io_error // 58030
type undefined_file (line 1375) | struct undefined_file // 58P01
type duplicate_file (line 1381) | struct duplicate_file // 58P02
type snapshot_too_old (line 1387) | struct snapshot_too_old // 72xxx
type config_file_error (line 1393) | struct config_file_error // F0xxx
type lock_file_exists (line 1399) | struct lock_file_exists // F0001
type fdw_error (line 1405) | struct fdw_error // HVxxx
type fdw_out_of_memory (line 1411) | struct fdw_out_of_memory // HV001
type fdw_dynamic_parameter_value_needed (line 1417) | struct fdw_dynamic_parameter_value_needed // HV002
type fdw_invalid_data_type (line 1423) | struct fdw_invalid_data_type // HV004
type fdw_column_name_not_found (line 1429) | struct fdw_column_name_not_found // HV005
type fdw_invalid_data_type_descriptors (line 1435) | struct fdw_invalid_data_type_descriptors // HV006
type fdw_invalid_column_name (line 1441) | struct fdw_invalid_column_name // HV007
type fdw_invalid_column_number (line 1447) | struct fdw_invalid_column_number // HV008
type fdw_invalid_use_of_null_pointer (line 1453) | struct fdw_invalid_use_of_null_pointer // HV009
type fdw_invalid_string_format (line 1459) | struct fdw_invalid_string_format // HV00A
type fdw_invalid_handle (line 1465) | struct fdw_invalid_handle // HV00B
type fdw_invalid_option_index (line 1471) | struct fdw_invalid_option_index // HV00C
type fdw_invalid_option_name (line 1477) | struct fdw_invalid_option_name // HV00D
type fdw_option_name_not_found (line 1483) | struct fdw_option_name_not_found // HV00J
type fdw_reply_handle (line 1489) | struct fdw_reply_handle // HV00K
type fdw_unable_to_create_execution (line 1495) | struct fdw_unable_to_create_execution // HV00L
type fdw_unable_to_create_reply (line 1501) | struct fdw_unable_to_create_reply // HV00M
type fdw_unable_to_establish_connection (line 1507) | struct fdw_unable_to_establish_connection // HV00N
type fdw_no_schemas (line 1513) | struct fdw_no_schemas // HV00P
type fdw_schema_not_found (line 1519) | struct fdw_schema_not_found // HV00Q
type fdw_table_not_found (line 1525) | struct fdw_table_not_found // HV00R
type fdw_function_sequence_error (line 1531) | struct fdw_function_sequence_error // HV010
type fdw_too_many_handles (line 1537) | struct fdw_too_many_handles // HV014
type fdw_inconsistent_descriptor_information (line 1543) | struct fdw_inconsistent_descriptor_information // HV021
type fdw_invalid_attribute_value (line 1549) | struct fdw_invalid_attribute_value // HV024
type fdw_invalid_string_length_or_buffer_length (line 1555) | struct fdw_invalid_string_length_or_buffer_length // HV090
type fdw_invalid_descriptor_field_identifier (line 1561) | struct fdw_invalid_descriptor_field_identifier // HV091
type plpgsql_error (line 1567) | struct plpgsql_error // P0xxx
type raise_exception (line 1573) | struct raise_exception // P0001
type no_data_found (line 1579) | struct no_data_found // P0002
type too_many_rows (line 1585) | struct too_many_rows // P0003
type assert_failure (line 1591) | struct assert_failure // P0004
type internal_error (line 1597) | struct internal_error // XXxxx
type data_corrupted (line 1603) | struct data_corrupted // XX001
type index_corrupted (line 1609) | struct index_corrupted // XX002
type internal (line 1615) | namespace internal
FILE: include/tao/pq/field.hpp
type tao::pq (line 16) | namespace tao::pq
class row (line 18) | class row
class field (line 20) | class field
method field (line 28) | field() = default;
method field (line 30) | field( const row& row, const std::size_t column ) noexcept
method optional (line 48) | [[nodiscard]] auto optional() const
method swap (line 58) | void swap( field& lhs, field& rhs ) noexcept
FILE: include/tao/pq/internal/aggregate.hpp
type tao::pq::internal (line 16) | namespace tao::pq::internal
function tie_aggregate (line 25) | constexpr auto tie_aggregate( const T& value ) noexcept
type convert_to_any (line 35) | struct convert_to_any
function tie_aggregate (line 91) | constexpr auto tie_aggregate( const T& value ) noexcept
FILE: include/tao/pq/internal/demangle.hpp
type tao::pq::internal (line 11) | namespace tao::pq::internal
function demangle (line 15) | [[nodiscard]] inline auto demangle( const std::type_info& type_info )
function demangle (line 21) | [[nodiscard]] auto demangle()
FILE: include/tao/pq/internal/exclusive_scan.hpp
type tao::pq::internal (line 11) | namespace tao::pq::internal
type exclusive_scan (line 14) | struct exclusive_scan
type exclusive_scan< std::integer_sequence< T, Ns... >, std::index_sequence< Is... > > (line 17) | struct exclusive_scan< std::integer_sequence< T, Ns... >, std::index_seq...
FILE: include/tao/pq/internal/format_as.hpp
type std::formatter< T > (line 14) | struct std::formatter< T > : std::formatter< decltype( taopq_format_as( ...
method format (line 16) | auto format( const T& v, auto& ctx ) const
FILE: include/tao/pq/internal/from_chars.hpp
type tao::pq::internal (line 17) | namespace tao::pq::internal
function from_chars (line 20) | [[nodiscard]] auto from_chars( const std::string_view value ) -> T
FILE: include/tao/pq/internal/gen.hpp
type tao::pq::internal (line 13) | namespace tao::pq::internal
type make (line 16) | struct make
type make< std::index_sequence< Is... >,
std::index_sequence< Js... >,
std::index_sequence< Ns... > > (line 21) | struct make< std::index_sequence< Is... >,
FILE: include/tao/pq/internal/parameter_traits_helper.hpp
type tao::pq::internal (line 16) | namespace tao::pq::internal
type char_pointer_helper (line 18) | struct char_pointer_helper
method char_pointer_helper (line 24) | explicit char_pointer_helper( const char* p ) noexcept
method type (line 32) | [[nodiscard]] static constexpr auto type() noexcept -> oid
method value (line 38) | [[nodiscard]] constexpr auto value() const noexcept -> const char*
method length (line 44) | [[nodiscard]] static constexpr auto length() noexcept -> int
method format (line 50) | [[nodiscard]] static constexpr auto format() noexcept -> int
type buffer_helper (line 57) | struct buffer_helper
method type (line 67) | [[nodiscard]] static constexpr auto type() noexcept -> oid
method value (line 73) | [[nodiscard]] auto value() const noexcept -> const char*
method length (line 79) | [[nodiscard]] static constexpr auto length() noexcept -> int
method format (line 85) | [[nodiscard]] static constexpr auto format() noexcept -> int
method element (line 91) | void element( std::string& data ) const
method copy_to (line 97) | void copy_to( std::string& data ) const
type to_chars_helper (line 104) | struct to_chars_helper
method to_chars_helper (line 107) | explicit to_chars_helper( const auto v ) noexcept
FILE: include/tao/pq/internal/poll.hpp
type tao::pq::internal (line 10) | namespace tao::pq::internal
FILE: include/tao/pq/internal/pool.hpp
type tao::pq::internal (line 16) | namespace tao::pq::internal
class pool (line 19) | class pool
type deleter (line 27) | struct deleter final
method deleter (line 31) | deleter() = default;
method deleter (line 33) | explicit deleter( std::weak_ptr< pool >&& p ) noexcept
method pool (line 48) | pool() = default;
method push (line 55) | void push( std::unique_ptr< T >& up ) noexcept
method pull (line 65) | [[nodiscard]] auto pull() noexcept
method pool (line 77) | pool( const pool& ) = delete;
method pool (line 78) | pool( pool&& ) = delete;
method attach (line 82) | static void attach( const std::shared_ptr< T >& sp, std::weak_ptr< p...
method detach (line 95) | static void detach( const std::shared_ptr< T >& sp ) noexcept
method create (line 106) | [[nodiscard]] auto create() -> std::shared_ptr< T >
method get (line 114) | [[nodiscard]] auto get() -> std::shared_ptr< T >
method empty (line 128) | [[nodiscard]] auto empty() const noexcept -> bool
method size (line 134) | [[nodiscard]] auto size() const noexcept -> std::size_t
method attached (line 140) | [[nodiscard]] auto attached() const noexcept -> std::size_t
method erase_invalid (line 145) | void erase_invalid()
FILE: include/tao/pq/internal/resize_uninitialized.hpp
type tao::pq::internal (line 12) | namespace tao::pq::internal
type odr_helper (line 19) | struct odr_helper
type string_proxy (line 27) | struct string_proxy
method resize_uninitialized_proxy (line 30) | void resize_uninitialized_proxy( T& v, const std::size_t n ) noexcept
method resize_uninitialized_proxy (line 46) | void resize_uninitialized_proxy( T& v, const std::size_t n ) noexcept
method resize_uninitialized_proxy (line 59) | void resize_uninitialized_proxy( T& v, const std::size_t n ) noexcept
method resize_uninitialized_proxy (line 73) | void resize_uninitialized_proxy( T& v, const std::size_t n ) noexcept
type string_proxy< std::string, &std::string::__set_size > (line 39) | struct string_proxy< std::string, &std::string::__set_size >
type string_proxy (line 44) | struct string_proxy
method resize_uninitialized_proxy (line 30) | void resize_uninitialized_proxy( T& v, const std::size_t n ) noexcept
method resize_uninitialized_proxy (line 46) | void resize_uninitialized_proxy( T& v, const std::size_t n ) noexcept
method resize_uninitialized_proxy (line 59) | void resize_uninitialized_proxy( T& v, const std::size_t n ) noexcept
method resize_uninitialized_proxy (line 73) | void resize_uninitialized_proxy( T& v, const std::size_t n ) noexcept
type string_proxy< std::string, &std::string::_M_set_length > (line 52) | struct string_proxy< std::string, &std::string::_M_set_length >
type string_proxy (line 57) | struct string_proxy
method resize_uninitialized_proxy (line 30) | void resize_uninitialized_proxy( T& v, const std::size_t n ) noexcept
method resize_uninitialized_proxy (line 46) | void resize_uninitialized_proxy( T& v, const std::size_t n ) noexcept
method resize_uninitialized_proxy (line 59) | void resize_uninitialized_proxy( T& v, const std::size_t n ) noexcept
method resize_uninitialized_proxy (line 73) | void resize_uninitialized_proxy( T& v, const std::size_t n ) noexcept
type string_proxy< std::string, &std::string::_M_rep > (line 66) | struct string_proxy< std::string, &std::string::_M_rep >
type string_proxy (line 71) | struct string_proxy
method resize_uninitialized_proxy (line 30) | void resize_uninitialized_proxy( T& v, const std::size_t n ) noexcept
method resize_uninitialized_proxy (line 46) | void resize_uninitialized_proxy( T& v, const std::size_t n ) noexcept
method resize_uninitialized_proxy (line 59) | void resize_uninitialized_proxy( T& v, const std::size_t n ) noexcept
method resize_uninitialized_proxy (line 73) | void resize_uninitialized_proxy( T& v, const std::size_t n ) noexcept
type string_proxy< std::string, &std::string::_Eos > (line 79) | struct string_proxy< std::string, &std::string::_Eos >
type vector_proxy (line 90) | struct vector_proxy
method resize_uninitialized_proxy (line 92) | void resize_uninitialized_proxy( T& v, const std::size_t n ) noexcept
method resize_uninitialized_proxy (line 115) | void resize_uninitialized_proxy( T& v, const std::size_t n ) noexcept
method resize_uninitialized_proxy (line 134) | void resize_uninitialized_proxy( T& v, const std::size_t n ) noexcept
type vector_proxy< std::vector< std::byte >, &std::vector< std::byte >::__end_ > (line 106) | struct vector_proxy< std::vector< std::byte >, &std::vector< std::byte...
type vector_proxy (line 113) | struct vector_proxy
method resize_uninitialized_proxy (line 92) | void resize_uninitialized_proxy( T& v, const std::size_t n ) noexcept
method resize_uninitialized_proxy (line 115) | void resize_uninitialized_proxy( T& v, const std::size_t n ) noexcept
method resize_uninitialized_proxy (line 134) | void resize_uninitialized_proxy( T& v, const std::size_t n ) noexcept
type vector_proxy (line 132) | struct vector_proxy
method resize_uninitialized_proxy (line 92) | void resize_uninitialized_proxy( T& v, const std::size_t n ) noexcept
method resize_uninitialized_proxy (line 115) | void resize_uninitialized_proxy( T& v, const std::size_t n ) noexcept
method resize_uninitialized_proxy (line 134) | void resize_uninitialized_proxy( T& v, const std::size_t n ) noexcept
type no_init_byte (line 150) | struct no_init_byte
method no_init_byte (line 153) | no_init_byte() noexcept {}
function resize_uninitialized_proxy (line 159) | inline void resize_uninitialized_proxy( std::vector< std::byte >& v, c...
function resize_uninitialized (line 170) | void resize_uninitialized( std::string& v, const std::size_t n )
function resize_uninitialized (line 184) | void resize_uninitialized( std::vector< std::byte >& v, const std::siz...
type vector_proxy< std::vector< std::byte >,
std::vector< std::byte >::_Base,
&std::vector< std::byte >::_M_impl,
&decltype( std::declval< std::vector< std::byte > >()._M_impl )::_M_finish > (line 122) | struct vector_proxy< std::vector< std::byte >,
type vector_proxy< std::vector< std::byte >,
&std::vector< std::byte >::_Mypair,
&decltype( std::declval< std::vector< std::byte > >()._Mypair )::_Myval2,
&decltype( std::declval< std::vector< std::byte > >()._Mypair._Myval2 )::_Mylast > (line 141) | struct vector_proxy< std::vector< std::byte >,
FILE: include/tao/pq/internal/strtox.hpp
type tao::pq::internal (line 8) | namespace tao::pq::internal
FILE: include/tao/pq/internal/zsv.hpp
type tao::pq::internal (line 12) | namespace tao::pq::internal
type zsv (line 15) | struct zsv
method zsv (line 19) | zsv( std::nullptr_t ) = delete;
method zsv (line 21) | constexpr zsv( const char* v ) noexcept
method zsv (line 25) | zsv( const std::string& v ) noexcept
FILE: include/tao/pq/is_aggregate.hpp
type tao::pq (line 8) | namespace tao::pq
FILE: include/tao/pq/is_array.hpp
type tao::pq (line 17) | namespace tao::pq
type internal (line 19) | namespace internal
type internal (line 44) | namespace internal
type internal (line 66) | namespace internal
FILE: include/tao/pq/isolation_level.hpp
type tao::pq (line 13) | namespace tao::pq
type isolation_level (line 15) | enum class isolation_level : std::uint8_t
function taopq_format_as (line 24) | [[nodiscard]] constexpr auto taopq_format_as( const isolation_level il...
FILE: include/tao/pq/large_object.hpp
type tao::pq (line 18) | namespace tao::pq
class transaction (line 20) | class transaction
class large_object (line 22) | class large_object final
method large_object (line 38) | large_object( const large_object& ) = delete;
method read (line 51) | [[nodiscard]] auto read( std::byte* data, const std::size_t size ) -...
method write (line 56) | void write( const std::byte* data, const std::size_t size )
method write (line 64) | void write( const char* data )
method write (line 70) | void write( Ts&&... ts )
FILE: include/tao/pq/log.hpp
type tao::pq (line 15) | namespace tao::pq
class connection (line 17) | class connection
class transaction (line 18) | class transaction
type log (line 20) | struct log
type connection_pool_t (line 22) | struct connection_pool_t
type connection_t (line 28) | struct connection_t
type transaction_t (line 122) | struct transaction_t
FILE: include/tao/pq/notification.hpp
type tao::pq (line 13) | namespace tao::pq
class connection (line 15) | class connection
class notification (line 17) | class notification final
method notification (line 24) | explicit notification( PGnotify* notify ) noexcept
method channel (line 31) | [[nodiscard]] auto channel() const noexcept -> const char*
method payload (line 36) | [[nodiscard]] auto payload() const noexcept -> const char*
method underlying_raw_ptr (line 41) | [[nodiscard]] auto underlying_raw_ptr() noexcept -> PGnotify*
method underlying_raw_ptr (line 46) | [[nodiscard]] auto underlying_raw_ptr() const noexcept -> const PGno...
FILE: include/tao/pq/null.hpp
type tao::pq (line 8) | namespace tao::pq
type null_t (line 10) | struct null_t final
method null_t (line 12) | explicit constexpr null_t( int /*unused*/ ) {}
FILE: include/tao/pq/oid.hpp
type tao::pq (line 10) | namespace tao::pq
type oid (line 14) | enum class oid : Oid // NOLINT(performance-enum-size)
FILE: include/tao/pq/parameter.hpp
type tao::pq (line 18) | namespace tao::pq
class transaction (line 20) | class transaction
class parameter (line 23) | class parameter
type vbase (line 54) | struct vbase
method vbase (line 56) | vbase() noexcept = default;
method vbase (line 59) | vbase( const vbase& ) = delete;
method vbase (line 60) | vbase( vbase&& ) = delete;
type binder (line 67) | struct binder : vbase
method binder (line 71) | explicit binder( const T& t ) noexcept( noexcept( parameter_traits...
type holder (line 77) | struct holder : vbase
method holder (line 82) | explicit holder( T&& t ) noexcept( noexcept( parameter_traits< T >...
method fill (line 103) | void fill( const auto& t, std::index_sequence< Is... > /*unused*/ )
method bind_impl (line 112) | void bind_impl( A&& a )
method bind_impl (line 132) | void bind_impl( const parameter< N >& p )
method bind_impl (line 150) | void bind_impl( parameter< N >& p )
method parameter (line 160) | explicit parameter( As&&... as ) noexcept( noexcept( std::declval< p...
method parameter (line 179) | explicit parameter( const parameter& p )
method parameter (line 184) | explicit parameter( parameter&& p ) = delete;
method bind (line 190) | void bind( As&&... as ) noexcept( sizeof...( As ) == 0 )
method reset (line 196) | void reset( As&&... as ) noexcept( noexcept( std::declval< parameter...
type internal (line 25) | namespace internal
class parameter (line 51) | class parameter
type vbase (line 54) | struct vbase
method vbase (line 56) | vbase() noexcept = default;
method vbase (line 59) | vbase( const vbase& ) = delete;
method vbase (line 60) | vbase( vbase&& ) = delete;
type binder (line 67) | struct binder : vbase
method binder (line 71) | explicit binder( const T& t ) noexcept( noexcept( parameter_traits...
type holder (line 77) | struct holder : vbase
method holder (line 82) | explicit holder( T&& t ) noexcept( noexcept( parameter_traits< T >...
method fill (line 103) | void fill( const auto& t, std::index_sequence< Is... > /*unused*/ )
method bind_impl (line 112) | void bind_impl( A&& a )
method bind_impl (line 132) | void bind_impl( const parameter< N >& p )
method bind_impl (line 150) | void bind_impl( parameter< N >& p )
method parameter (line 160) | explicit parameter( As&&... as ) noexcept( noexcept( std::declval< p...
method parameter (line 179) | explicit parameter( const parameter& p )
method parameter (line 184) | explicit parameter( parameter&& p ) = delete;
method bind (line 190) | void bind( As&&... as ) noexcept( sizeof...( As ) == 0 )
method reset (line 196) | void reset( As&&... as ) noexcept( noexcept( std::declval< parameter...
FILE: include/tao/pq/parameter_traits.hpp
type tao::pq (line 27) | namespace tao::pq
type parameter_traits (line 30) | struct parameter_traits
type internal (line 32) | namespace internal
function snprintf (line 41) | void snprintf( char ( &buffer )[ N ], const char* format, const auto...
type parameter_holder (line 478) | struct parameter_holder
method parameter_holder (line 483) | explicit parameter_holder( const T& t ) noexcept( noexcept( result...
type parameter_traits< null_t > (line 86) | struct parameter_traits< null_t >
method parameter_traits (line 88) | explicit parameter_traits( null_t /*unused*/ ) noexcept
method type (line 95) | [[nodiscard]] static constexpr auto type() noexcept -> oid
method value (line 101) | [[nodiscard]] static constexpr auto value() noexcept -> const char*
method length (line 107) | [[nodiscard]] static constexpr auto length() noexcept -> int
method format (line 113) | [[nodiscard]] static constexpr auto format() noexcept -> int
method element (line 119) | static void element( std::string& data )
method copy_to (line 125) | static void copy_to( std::string& data )
type parameter_traits< bool > (line 132) | struct parameter_traits< bool >
method parameter_traits (line 137) | explicit parameter_traits( const bool v ) noexcept
method element (line 142) | void element( std::string& data ) const
method copy_to (line 148) | void copy_to( std::string& data ) const
type parameter_traits< char > (line 155) | struct parameter_traits< char >
method parameter_traits (line 159) | explicit parameter_traits( const char v ) noexcept
method type (line 167) | [[nodiscard]] static constexpr auto type() noexcept -> oid
method value (line 173) | [[nodiscard]] auto value() const noexcept -> const char*
method length (line 179) | [[nodiscard]] static constexpr auto length() noexcept -> int
method format (line 185) | [[nodiscard]] static constexpr auto format() noexcept -> int
method element (line 191) | void element( std::string& data ) const
method copy_to (line 197) | void copy_to( std::string& data ) const
type parameter_traits< signed char > (line 204) | struct parameter_traits< signed char >
type parameter_traits< unsigned char > (line 211) | struct parameter_traits< unsigned char >
type parameter_traits< short > (line 218) | struct parameter_traits< short >
type parameter_traits< unsigned short > (line 225) | struct parameter_traits< unsigned short >
type parameter_traits< int > (line 232) | struct parameter_traits< int >
type parameter_traits< unsigned int > (line 239) | struct parameter_traits< unsigned int >
type parameter_traits< long > (line 246) | struct parameter_traits< long >
type parameter_traits< unsigned long > (line 253) | struct parameter_traits< unsigned long >
type parameter_traits< long long > (line 260) | struct parameter_traits< long long >
type parameter_traits< unsigned long long > (line 267) | struct parameter_traits< unsigned long long >
type parameter_traits< float > (line 274) | struct parameter_traits< float >
method parameter_traits (line 277) | explicit parameter_traits( const float v ) noexcept
type parameter_traits< double > (line 284) | struct parameter_traits< double >
method parameter_traits (line 287) | explicit parameter_traits( const double v ) noexcept
type parameter_traits< long double > (line 294) | struct parameter_traits< long double >
method parameter_traits (line 297) | explicit parameter_traits( const long double v ) noexcept
type parameter_traits< const char* > (line 304) | struct parameter_traits< const char* >
method element (line 310) | void element( std::string& data ) const
method copy_to (line 316) | void copy_to( std::string& data ) const
type parameter_traits< std::string_view > (line 326) | struct parameter_traits< std::string_view >
method parameter_traits (line 332) | explicit parameter_traits( const std::string_view v ) noexcept
method type (line 340) | [[nodiscard]] static constexpr auto type() noexcept -> oid
method value (line 346) | [[nodiscard]] auto value() const noexcept -> const char*
method length (line 352) | [[nodiscard]] auto length() const noexcept -> int
method format (line 358) | [[nodiscard]] static constexpr auto format() noexcept -> int
method element (line 364) | void element( std::string& data ) const
method copy_to (line 370) | void copy_to( std::string& data ) const
type parameter_traits< std::string > (line 377) | struct parameter_traits< std::string >
type parameter_traits< std::span< const std::byte, Extent > > (line 384) | struct parameter_traits< std::span< const std::byte, Extent > >
method parameter_traits (line 390) | explicit parameter_traits( const std::span< const std::byte, Extent ...
method type (line 398) | [[nodiscard]] static constexpr auto type() noexcept -> oid
method value (line 404) | [[nodiscard]] constexpr auto value() const noexcept -> const char*
method length (line 410) | [[nodiscard]] constexpr auto length() const noexcept -> int
method format (line 416) | [[nodiscard]] static constexpr auto format() noexcept -> int
method element (line 422) | void element( std::string& data ) const
method copy_to (line 438) | void copy_to( std::string& data ) const
type parameter_traits< std::span< std::byte, Extent > > (line 445) | struct parameter_traits< std::span< std::byte, Extent > >
type parameter_traits< std::vector< std::byte, Allocator > > (line 452) | struct parameter_traits< std::vector< std::byte, Allocator > >
function to_taopq (line 459) | [[nodiscard]] auto to_taopq( const auto& t ) noexcept( noexcept( t.to_...
function to_taopq (line 467) | [[nodiscard]] auto to_taopq( const T& t ) noexcept( noexcept( bind< T ...
type internal (line 475) | namespace internal
function snprintf (line 41) | void snprintf( char ( &buffer )[ N ], const char* format, const auto...
type parameter_holder (line 478) | struct parameter_holder
method parameter_holder (line 483) | explicit parameter_holder( const T& t ) noexcept( noexcept( result...
type parameter_traits< T > (line 492) | struct parameter_traits< T >
method parameter_traits (line 500) | explicit parameter_traits( const T& t ) noexcept( noexcept( internal...
FILE: include/tao/pq/parameter_traits_aggregate.hpp
type tao::pq (line 12) | namespace tao::pq
type internal (line 14) | namespace internal
type parameter_tie_aggregate (line 17) | struct parameter_tie_aggregate
method parameter_tie_aggregate (line 22) | explicit parameter_tie_aggregate( const T& t ) noexcept
type parameter_traits< T > (line 31) | struct parameter_traits< T >
method parameter_traits (line 37) | explicit parameter_traits( const T& t ) noexcept( noexcept( internal...
FILE: include/tao/pq/parameter_traits_array.hpp
type tao::pq (line 15) | namespace tao::pq
type internal (line 17) | namespace internal
function to_array (line 23) | void to_array( std::string& data, const T& v )
function to_array (line 30) | void to_array( std::string& data, const T& v )
type parameter_traits< T > (line 48) | struct parameter_traits< T >
method parameter_traits (line 54) | explicit parameter_traits( const T& v )
method type (line 63) | [[nodiscard]] static constexpr auto type() noexcept -> oid
method value (line 69) | [[nodiscard]] auto value() const noexcept -> const char*
method length (line 75) | [[nodiscard]] static constexpr auto length() noexcept -> int
method format (line 81) | [[nodiscard]] static constexpr auto format() noexcept -> int
method element (line 87) | void element( std::string& data ) const
method copy_to (line 93) | void copy_to( std::string& data ) const
FILE: include/tao/pq/parameter_traits_optional.hpp
type tao::pq::parameter_traits< std::optional< T > > (line 18) | struct tao::pq::parameter_traits< std::optional< T > >
method parameter_traits (line 25) | explicit parameter_traits( const std::optional< T >& v ) noexcept( noe...
method parameter_traits (line 32) | explicit parameter_traits( std::optional< T >&& v ) noexcept( noexcept...
method type (line 43) | [[nodiscard]] static constexpr auto type() noexcept -> oid
method value (line 49) | [[nodiscard]] constexpr auto value() const noexcept( noexcept( m_forwa...
method length (line 55) | [[nodiscard]] constexpr auto length() const noexcept( noexcept( m_forw...
method format (line 61) | [[nodiscard]] static constexpr auto format() noexcept -> int
method element (line 67) | void element( std::string& data ) const
method copy_to (line 78) | void copy_to( std::string& data ) const
FILE: include/tao/pq/parameter_traits_pair.hpp
type tao::pq::parameter_traits< std::pair< T, U > > (line 18) | struct tao::pq::parameter_traits< std::pair< T, U > >
method parameter_traits (line 30) | explicit parameter_traits( const std::pair< T, U >& pair ) noexcept( n...
method parameter_traits (line 34) | explicit parameter_traits( std::pair< T, U >&& pair ) noexcept( noexce...
method type (line 42) | [[nodiscard]] constexpr auto type() const noexcept( noexcept( std::get...
method value (line 48) | [[nodiscard]] constexpr auto value() const noexcept( noexcept( std::ge...
method length (line 54) | [[nodiscard]] constexpr auto length() const noexcept( noexcept( std::g...
method format (line 60) | [[nodiscard]] constexpr auto format() const noexcept( noexcept( std::g...
method copy_to (line 66) | void copy_to( std::string& data ) const
FILE: include/tao/pq/parameter_traits_tuple.hpp
type tao::pq::parameter_traits< std::tuple< Ts... > > (line 20) | struct tao::pq::parameter_traits< std::tuple< Ts... > >
method parameter_traits (line 29) | explicit parameter_traits( const std::tuple< Ts... >& tuple ) noexcept...
method parameter_traits (line 33) | explicit parameter_traits( std::tuple< Ts... >&& tuple ) noexcept( noe...
method type (line 41) | [[nodiscard]] constexpr auto type() const noexcept( noexcept( std::get...
method value (line 47) | [[nodiscard]] constexpr auto value() const noexcept( noexcept( std::ge...
method length (line 53) | [[nodiscard]] constexpr auto length() const noexcept( noexcept( std::g...
method format (line 59) | [[nodiscard]] constexpr auto format() const noexcept( noexcept( std::g...
method element (line 66) | void element( std::string& data ) const
method copy_to (line 72) | void copy_to( std::string& data ) const
FILE: include/tao/pq/pipeline.hpp
type tao::pq (line 13) | namespace tao::pq
class connection (line 15) | class connection
class transaction (line 16) | class transaction
class pipeline (line 18) | class pipeline
class private_key (line 27) | class private_key final
method private_key (line 29) | private_key() = default;
method pipeline (line 48) | pipeline( const pipeline& ) = delete;
method pipeline (line 49) | pipeline( pipeline&& ) = delete;
FILE: include/tao/pq/pipeline_status.hpp
type tao::pq (line 15) | namespace tao::pq
type pipeline_status (line 17) | enum class pipeline_status : std::uint8_t
function taopq_format_as (line 24) | [[nodiscard]] constexpr auto taopq_format_as( const pipeline_status ps...
FILE: include/tao/pq/poll.hpp
type tao::pq::poll (line 13) | namespace tao::pq::poll
type status (line 15) | enum class status : std::uint8_t
function taopq_format_as (line 23) | [[nodiscard]] constexpr auto taopq_format_as( const status st ) noexce...
FILE: include/tao/pq/result.hpp
type tao::pq (line 32) | namespace tao::pq
class connection (line 34) | class connection
class table_reader (line 35) | class table_reader
class table_writer (line 36) | class table_writer
class transaction_base (line 37) | class transaction_base
class result (line 39) | class result final
method columns (line 60) | [[nodiscard]] auto columns() const noexcept -> std::size_t
method size (line 68) | [[nodiscard]] auto size() const noexcept -> std::size_t
method empty (line 74) | [[nodiscard]] auto empty() const noexcept -> bool
class const_iterator (line 80) | class const_iterator
method const_iterator (line 86) | explicit const_iterator( const row& r ) noexcept
method const_iterator (line 97) | const_iterator() = default;
method swap (line 152) | void swap( const_iterator& lhs, const_iterator& rhs ) noexcept
method cbegin (line 198) | [[nodiscard]] auto cbegin() const noexcept
method cend (line 203) | [[nodiscard]] auto cend() const noexcept
method as (line 219) | [[nodiscard]] auto as() const -> T
method optional (line 234) | [[nodiscard]] auto optional() const -> std::optional< T >
method pair (line 249) | [[nodiscard]] auto pair() const
method tuple (line 255) | [[nodiscard]] auto tuple() const
method as_container (line 262) | [[nodiscard]] auto as_container() const -> T
method vector (line 277) | [[nodiscard]] auto vector() const
method list (line 284) | [[nodiscard]] auto list() const
method set (line 291) | [[nodiscard]] auto set() const
method multiset (line 298) | [[nodiscard]] auto multiset() const
method unordered_set (line 305) | [[nodiscard]] auto unordered_set() const
method unordered_multiset (line 312) | [[nodiscard]] auto unordered_multiset() const
method map (line 319) | [[nodiscard]] auto map() const
method multimap (line 326) | [[nodiscard]] auto multimap() const
method unordered_map (line 333) | [[nodiscard]] auto unordered_map() const
method unordered_multimap (line 340) | [[nodiscard]] auto unordered_multimap() const
method underlying_raw_ptr (line 345) | [[nodiscard]] auto underlying_raw_ptr() noexcept -> PGresult*
method underlying_raw_ptr (line 350) | [[nodiscard]] auto underlying_raw_ptr() const noexcept -> const PGre...
FILE: include/tao/pq/result_status.hpp
type tao::pq (line 15) | namespace tao::pq
type result_status (line 17) | enum class result_status : std::uint8_t
function taopq_format_as (line 35) | [[nodiscard]] constexpr auto taopq_format_as( const result_status rs )...
FILE: include/tao/pq/result_traits.hpp
type tao::pq (line 19) | namespace tao::pq
type result_traits (line 22) | struct result_traits
class row (line 36) | class row
type result_traits< const char* > (line 47) | struct result_traits< const char* >
method from (line 49) | [[nodiscard]] static auto from( const char* value )
type result_traits< std::string_view > (line 56) | struct result_traits< std::string_view >
method from (line 58) | [[nodiscard]] static auto from( const char* value ) -> std::string_view
type result_traits< bool > (line 65) | struct result_traits< bool >
type result_traits< char > (line 71) | struct result_traits< char >
type result_traits< signed char > (line 77) | struct result_traits< signed char >
type result_traits< unsigned char > (line 83) | struct result_traits< unsigned char >
type result_traits< short > (line 89) | struct result_traits< short >
type result_traits< unsigned short > (line 95) | struct result_traits< unsigned short >
type result_traits< int > (line 101) | struct result_traits< int >
type result_traits< unsigned > (line 107) | struct result_traits< unsigned >
type result_traits< long > (line 113) | struct result_traits< long >
type result_traits< unsigned long > (line 119) | struct result_traits< unsigned long >
type result_traits< long long > (line 125) | struct result_traits< long long >
type result_traits< unsigned long long > (line 131) | struct result_traits< unsigned long long >
type result_traits< float > (line 137) | struct result_traits< float >
type result_traits< double > (line 143) | struct result_traits< double >
type result_traits< long double > (line 149) | struct result_traits< long double >
type result_traits< std::string > (line 155) | struct result_traits< std::string >
method from (line 157) | [[nodiscard]] static auto from( const char* value ) -> std::string
type result_traits< binary > (line 164) | struct result_traits< binary >
type internal (line 169) | namespace internal
type from_taopq (line 172) | struct from_taopq
type result_traits< T > (line 201) | struct result_traits< T >
type result_traits< T > (line 207) | struct result_traits< T >
type from_taopq< T, R, R( As... ) > (line 175) | struct from_taopq< T, R, R( As... ) >
method from (line 180) | [[nodiscard]] static auto from( const Row& row, std::index_sequence< N...
method from (line 186) | [[nodiscard]] static auto from( const Row& row ) -> R
type from_taopq< T, R, R( As... ) noexcept > (line 193) | struct from_taopq< T, R, R( As... ) noexcept >
FILE: include/tao/pq/result_traits_aggregate.hpp
type tao::pq (line 18) | namespace tao::pq
type internal (line 20) | namespace internal
type decay_tuple (line 23) | struct decay_tuple
type aggregate_result (line 32) | struct aggregate_result
type result_traits< T > (line 56) | struct result_traits< T >
type decay_tuple< std::tuple< Ts... > > (line 26) | struct decay_tuple< std::tuple< Ts... > >
type aggregate_result< T, std::tuple< Ts... > > (line 35) | struct aggregate_result< T, std::tuple< Ts... > >
method from (line 40) | [[nodiscard]] static auto from( const Row& row, std::index_sequence< N...
method from (line 46) | [[nodiscard]] static auto from( const Row& row )
FILE: include/tao/pq/result_traits_array.hpp
type tao::pq (line 14) | namespace tao::pq
type internal (line 16) | namespace internal
function parse (line 25) | [[nodiscard]] auto parse( const char*& value ) -> T
function parse (line 46) | [[nodiscard]] auto parse( const char*& value ) -> T
type result_traits< T > (line 83) | struct result_traits< T >
method from (line 85) | static auto from( const char* value ) -> T
FILE: include/tao/pq/result_traits_optional.hpp
type tao::pq::result_traits< std::optional< T > > (line 14) | struct tao::pq::result_traits< std::optional< T > >
method null (line 18) | [[nodiscard]] static auto null() noexcept -> std::optional< T >
method from (line 23) | [[nodiscard]] static auto from( const char* value ) -> std::optional< T >
method from (line 29) | [[nodiscard]] static auto from( const Row& row ) -> std::optional< T >
FILE: include/tao/pq/result_traits_pair.hpp
type tao::pq::result_traits< std::pair< T, U > > (line 15) | struct tao::pq::result_traits< std::pair< T, U > >
method from (line 23) | [[nodiscard]] static auto from( const Row& row )
FILE: include/tao/pq/result_traits_tuple.hpp
type tao::pq::result_traits< std::tuple<> > (line 17) | struct tao::pq::result_traits< std::tuple<> >
type tao::pq::result_traits< std::tuple< T > > (line 23) | struct tao::pq::result_traits< std::tuple< T > >
method null (line 29) | [[nodiscard]] static auto null()
method from (line 35) | [[nodiscard]] static auto from( const char* value )
type tao::pq::result_traits< std::tuple< Ts... > > (line 43) | struct tao::pq::result_traits< std::tuple< Ts... > >
method from (line 48) | [[nodiscard]] static auto from( const Row& row, std::index_sequence< N...
method from (line 54) | [[nodiscard]] static auto from( const Row& row )
FILE: include/tao/pq/row.hpp
type tao::pq (line 24) | namespace tao::pq
class result (line 26) | class result
class row (line 28) | class row
method row (line 39) | row() = default;
method row (line 41) | row( const result& in_result, const std::size_t in_row, const std::s...
method columns (line 53) | [[nodiscard]] auto columns() const noexcept -> std::size_t
class const_iterator (line 62) | class const_iterator
method const_iterator (line 68) | explicit const_iterator( const field& f ) noexcept
method const_iterator (line 79) | const_iterator() = default;
method swap (line 134) | void swap( const_iterator& lhs, const_iterator& rhs ) noexcept
method cbegin (line 180) | [[nodiscard]] auto cbegin() const noexcept
method cend (line 185) | [[nodiscard]] auto cend() const noexcept
method get (line 194) | [[nodiscard]] auto get( const std::size_t column ) const -> T
method get (line 205) | [[nodiscard]] auto get( const std::size_t column ) const -> T
method optional (line 211) | [[nodiscard]] auto optional( const std::size_t column ) const
method as (line 217) | [[nodiscard]] auto as() const -> T
method optional (line 233) | [[nodiscard]] auto optional() const
method pair (line 239) | [[nodiscard]] auto pair() const
method tuple (line 245) | [[nodiscard]] auto tuple() const
method at (line 257) | [[nodiscard]] auto at( const internal::zsv in_name ) const -> field
method swap (line 268) | void swap( row& lhs, row& rhs ) noexcept
FILE: include/tao/pq/table_field.hpp
type tao::pq (line 15) | namespace tao::pq
class table_row (line 17) | class table_row
class table_field (line 19) | class table_field
method table_field (line 27) | table_field() = default;
method table_field (line 29) | table_field( const table_row& row, const std::size_t column ) noexcept
method optional (line 46) | [[nodiscard]] auto optional() const
method swap (line 56) | void swap( table_field& lhs, table_field& rhs ) noexcept
FILE: include/tao/pq/table_reader.hpp
type tao::pq (line 27) | namespace tao::pq
class table_reader (line 29) | class table_reader final
method table_reader (line 42) | table_reader( const std::shared_ptr< transaction >& transaction, con...
method table_reader (line 54) | table_reader( const table_reader& ) = delete;
method table_reader (line 55) | table_reader( table_reader&& ) = delete;
method columns (line 59) | [[nodiscard]] auto columns() const noexcept -> std::size_t
method get_row (line 69) | [[nodiscard]] auto get_row() -> bool
method has_data (line 75) | [[nodiscard]] auto has_data() const noexcept -> bool
method raw_data (line 80) | [[nodiscard]] auto raw_data() const noexcept -> const std::vector< c...
method row (line 85) | [[nodiscard]] auto row() noexcept -> table_row
class const_iterator (line 92) | class const_iterator
method const_iterator (line 98) | const_iterator( const table_row& r ) noexcept
method swap (line 126) | void swap( const_iterator& lhs, const_iterator& rhs ) noexcept
method cbegin (line 141) | [[nodiscard]] auto cbegin()
method cend (line 146) | [[nodiscard]] auto cend() noexcept
method as_container (line 153) | [[nodiscard]] auto as_container() -> T
method vector (line 164) | [[nodiscard]] auto vector()
method list (line 171) | [[nodiscard]] auto list()
method set (line 178) | [[nodiscard]] auto set()
method multiset (line 185) | [[nodiscard]] auto multiset()
method unordered_set (line 192) | [[nodiscard]] auto unordered_set()
method unordered_multiset (line 199) | [[nodiscard]] auto unordered_multiset()
method map (line 206) | [[nodiscard]] auto map()
method multimap (line 213) | [[nodiscard]] auto multimap()
method unordered_map (line 220) | [[nodiscard]] auto unordered_map()
method unordered_multimap (line 227) | [[nodiscard]] auto unordered_multimap()
FILE: include/tao/pq/table_row.hpp
type tao::pq (line 21) | namespace tao::pq
class table_reader (line 23) | class table_reader
class table_row (line 25) | class table_row
method table_row (line 35) | table_row( table_reader& in_reader, const std::size_t in_offset, con...
method columns (line 46) | [[nodiscard]] auto columns() const noexcept -> std::size_t
class const_iterator (line 52) | class const_iterator
method const_iterator (line 58) | explicit const_iterator( const table_field& f ) noexcept
method const_iterator (line 69) | const_iterator() = default;
method swap (line 124) | void swap( const_iterator& lhs, const_iterator& rhs ) noexcept
method cbegin (line 170) | [[nodiscard]] auto cbegin() const noexcept
method cend (line 175) | [[nodiscard]] auto cend() const noexcept
method get (line 184) | [[nodiscard]] auto get( const std::size_t column ) const -> T
method get (line 199) | [[nodiscard]] auto get( const std::size_t column ) const -> T
method optional (line 205) | [[nodiscard]] auto optional( const std::size_t column ) const
method as (line 211) | [[nodiscard]] auto as() const -> T
method optional (line 220) | [[nodiscard]] auto optional() const
method pair (line 226) | [[nodiscard]] auto pair() const
method tuple (line 232) | [[nodiscard]] auto tuple() const
method swap (line 244) | void swap( table_row& lhs, table_row& rhs ) noexcept
FILE: include/tao/pq/table_writer.hpp
type tao::pq (line 24) | namespace tao::pq
class table_writer (line 26) | class table_writer final
method insert_indexed (line 35) | void insert_indexed( std::index_sequence< Os... > /*unused*/,
method insert_traits (line 46) | void insert_traits( const Ts&... ts )
method insert_indexed (line 55) | void insert_indexed( std::index_sequence< Os... > /*unused*/,
method insert_traits (line 66) | void insert_traits( const Ts&... ts )
method table_writer (line 78) | table_writer( const std::shared_ptr< transaction >& transaction, con...
method table_writer (line 88) | table_writer( const table_writer& ) = delete;
method table_writer (line 89) | table_writer( table_writer&& ) = delete;
method insert (line 97) | void insert( As&&... as )
FILE: include/tao/pq/transaction.hpp
type tao::pq (line 18) | namespace tao::pq
class pipeline (line 20) | class pipeline
class transaction (line 22) | class transaction
method execute (line 42) | auto execute( const internal::zsv statement, As&&... as )
type internal (line 53) | namespace internal
class subtransaction_base (line 55) | class subtransaction_base
method subtransaction_base (line 62) | explicit subtransaction_base( const std::shared_ptr< pq::connectio...
method v_is_direct (line 76) | [[nodiscard]] auto v_is_direct() const noexcept -> bool final
method v_reset (line 81) | void v_reset() noexcept final
method subtransaction_base (line 88) | subtransaction_base( const subtransaction_base& ) = delete;
method subtransaction_base (line 89) | subtransaction_base( subtransaction_base&& ) = delete;
class transaction_guard (line 95) | class transaction_guard final
method transaction_guard (line 99) | explicit transaction_guard( const std::shared_ptr< pq::connection ...
method v_commit (line 105) | void v_commit() override {}
method v_rollback (line 106) | void v_rollback() override {}
FILE: include/tao/pq/transaction_base.hpp
type tao::pq (line 25) | namespace tao::pq
class connection (line 27) | class connection
class table_reader (line 28) | class table_reader
class table_writer (line 29) | class table_writer
class transaction_base (line 31) | class transaction_base
method transaction_base (line 45) | transaction_base( const transaction_base& ) = delete;
method transaction_base (line 46) | transaction_base( transaction_base&& ) = delete;
method send_indexed (line 64) | void send_indexed( const char* statement,
method send_traits (line 77) | void send_traits( const char* statement, const Ts&... ts )
method send_indexed (line 86) | void send_indexed( const char* statement,
method send_traits (line 99) | void send_traits( const char* statement, const Ts&... ts )
method connection (line 108) | [[nodiscard]] auto connection() const noexcept -> const std::shared_...
method send (line 113) | void send( const internal::zsv statement )
method send (line 119) | void send( const internal::zsv statement, As&&... as )
method send (line 126) | void send( const internal::zsv statement, As&&... as )
method send (line 133) | void send( const internal::zsv statement, A&& p )
FILE: include/tao/pq/transaction_status.hpp
type tao::pq (line 15) | namespace tao::pq
type transaction_status (line 17) | enum class transaction_status : std::uint8_t
function taopq_format_as (line 26) | [[nodiscard]] constexpr auto taopq_format_as( const transaction_status...
FILE: src/lib/pq/connection.cpp
type tao::pq (line 34) | namespace tao::pq
type internal (line 36) | namespace internal
class transaction_base (line 38) | class transaction_base
method transaction_base (line 42) | explicit transaction_base( const std::shared_ptr< pq::connection >...
method v_reset (line 58) | void v_reset() noexcept final
method transaction_base (line 65) | transaction_base( const transaction_base& ) = delete;
method transaction_base (line 66) | transaction_base( transaction_base&& ) = delete;
class autocommit_transaction (line 71) | class autocommit_transaction final
method autocommit_transaction (line 75) | explicit autocommit_transaction( const std::shared_ptr< pq::connec...
method v_is_direct (line 80) | [[nodiscard]] auto v_is_direct() const noexcept -> bool override
method v_commit (line 85) | void v_commit() override
method v_rollback (line 88) | void v_rollback() override
function isolation_level_extension (line 94) | [[nodiscard]] inline auto isolation_level_extension( const isolation...
function access_mode_extension (line 111) | [[nodiscard]] inline auto access_mode_extension( const access_mode a...
class top_level_transaction (line 126) | class top_level_transaction final
method top_level_transaction (line 130) | top_level_transaction( const std::shared_ptr< pq::connection >& co...
method top_level_transaction (line 143) | top_level_transaction( const top_level_transaction& ) = delete;
method top_level_transaction (line 144) | top_level_transaction( top_level_transaction&& ) = delete;
method v_is_direct (line 149) | [[nodiscard]] auto v_is_direct() const noexcept -> bool override
method v_commit (line 154) | void v_commit() override
method v_rollback (line 159) | void v_rollback() override
function is_identifier (line 167) | [[nodiscard]] constexpr auto is_identifier( const std::string_view v...
FILE: src/lib/pq/connection_pool.cpp
type tao::pq (line 13) | namespace tao::pq
FILE: src/lib/pq/exception.cpp
type tao::pq (line 12) | namespace tao::pq
type internal (line 23) | namespace internal
function throw_sqlstate (line 25) | void throw_sqlstate( PGresult* pgresult )
function throw_sqlstate (line 35) | void throw_sqlstate( const char* error_message, const std::string_vi...
FILE: src/lib/pq/field.cpp
type tao::pq (line 12) | namespace tao::pq
FILE: src/lib/pq/internal/demangle.cpp
type tao::pq::internal (line 15) | namespace tao::pq::internal
function demangle (line 17) | auto demangle( const char* const symbol ) -> std::string
FILE: src/lib/pq/internal/poll.cpp
type tao::pq::internal (line 23) | namespace tao::pq::internal
function errno_result_to_string (line 28) | [[nodiscard, maybe_unused]] auto errno_result_to_string( const int e, ...
function errno_result_to_string (line 36) | [[nodiscard, maybe_unused]] auto errno_result_to_string( const int /*u...
function errno_to_string (line 41) | [[nodiscard]] auto errno_to_string( const int e ) -> std::string
function poll (line 58) | auto poll( const int socket, const bool wait_for_write, const int time...
FILE: src/lib/pq/internal/strtox.cpp
type tao::pq::internal (line 15) | namespace tao::pq::internal
function failure_message (line 29) | [[nodiscard]] auto failure_message( const char* input ) -> std::string
function str_to_floating_point (line 56) | [[nodiscard]] auto str_to_floating_point( const char* input ) -> T
function strtof (line 87) | [[nodiscard]] auto strtof( const char* input ) -> float
function strtod (line 92) | [[nodiscard]] auto strtod( const char* input ) -> double
function strtold (line 97) | [[nodiscard]] auto strtold( const char* input ) -> long double
FILE: src/lib/pq/large_object.cpp
type tao::pq (line 27) | namespace tao::pq
function to_mode (line 31) | [[nodiscard]] constexpr auto to_mode( const std::ios_base::openmode m ...
FILE: src/lib/pq/parameter_traits.cpp
type tao::pq::internal (line 10) | namespace tao::pq::internal
function array_append (line 12) | void array_append( std::string& buffer, std::string_view data )
function table_writer_append (line 40) | void table_writer_append( std::string& buffer, std::string_view data )
FILE: src/lib/pq/pipeline.cpp
type tao::pq (line 11) | namespace tao::pq
FILE: src/lib/pq/result.cpp
type tao::pq (line 20) | namespace tao::pq
FILE: src/lib/pq/result_traits.cpp
type tao::pq (line 18) | namespace tao::pq
function unhex (line 22) | [[nodiscard]] auto unhex( const char c ) -> int
function unescape_bytea (line 33) | [[nodiscard]] auto unescape_bytea( const char* value ) -> binary
FILE: src/lib/pq/result_traits_array.cpp
type tao::pq::internal (line 13) | namespace tao::pq::internal
function parse_quoted (line 15) | auto parse_quoted( const char*& value ) -> std::string
function parse_unquoted (line 38) | auto parse_unquoted( const char*& value ) -> std::string
FILE: src/lib/pq/row.cpp
type tao::pq (line 16) | namespace tao::pq
FILE: src/lib/pq/table_field.cpp
type tao::pq (line 11) | namespace tao::pq
FILE: src/lib/pq/table_reader.cpp
type tao::pq (line 21) | namespace tao::pq
FILE: src/lib/pq/table_row.cpp
type tao::pq (line 13) | namespace tao::pq
FILE: src/lib/pq/table_writer.cpp
type tao::pq (line 20) | namespace tao::pq
FILE: src/lib/pq/transaction.cpp
type tao::pq (line 18) | namespace tao::pq
type internal (line 20) | namespace internal
class top_level_subtransaction (line 22) | class top_level_subtransaction final
method top_level_subtransaction (line 26) | explicit top_level_subtransaction( const std::shared_ptr< pq::conn...
method top_level_subtransaction (line 39) | top_level_subtransaction( const top_level_subtransaction& ) = delete;
method top_level_subtransaction (line 40) | top_level_subtransaction( top_level_subtransaction&& ) = delete;
method v_commit (line 45) | void v_commit() override
method v_rollback (line 50) | void v_rollback() override
class nested_subtransaction (line 56) | class nested_subtransaction final
method nested_subtransaction (line 60) | explicit nested_subtransaction( const std::shared_ptr< pq::connect...
method nested_subtransaction (line 75) | nested_subtransaction( const nested_subtransaction& ) = delete;
method nested_subtransaction (line 76) | nested_subtransaction( nested_subtransaction&& ) = delete;
method v_commit (line 81) | void v_commit() override
method v_rollback (line 88) | void v_rollback() override
FILE: src/lib/pq/transaction_base.cpp
type tao::pq (line 19) | namespace tao::pq
FILE: test/integration/aggregate.cpp
type example (line 14) | namespace example
type user (line 16) | struct user
function run (line 30) | void run()
function main (line 55) | auto main() -> int // NOLINT(bugprone-exception-escape)
FILE: test/integration/array.cpp
function run (line 22) | void run()
function main (line 153) | auto main() -> int // NOLINT(bugprone-exception-escape)
FILE: test/integration/basic_datatypes.cpp
function prepare_datatype (line 23) | auto prepare_datatype( const std::string& datatype ) -> bool
function check_null (line 35) | void check_null( const std::string& datatype )
function check (line 49) | void check( const std::string& datatype, const T& value )
function check (line 77) | auto check( const std::string& datatype )
function check (line 92) | auto check( const std::string& datatype )
function check_bytea (line 102) | void check_bytea( const auto& t )
function run (line 110) | void run()
function main (line 389) | auto main() -> int
FILE: test/integration/chunk_mode.cpp
function main (line 16) | auto main() -> int
function run (line 25) | void run()
function main (line 99) | auto main() -> int // NOLINT(bugprone-exception-escape)
FILE: test/integration/connection.cpp
function my_poll (line 20) | auto my_poll( const int /*unused*/, const bool /*unused*/, const int /*u...
function run (line 26) | void run()
function main (line 163) | auto main() -> int // NOLINT(bugprone-exception-escape)
FILE: test/integration/connection_pool.cpp
class limited_connection_pool (line 21) | class limited_connection_pool
type guard (line 24) | struct guard
method guard (line 28) | explicit guard( std::atomic< std::size_t >& counter ) noexcept
method guard (line 34) | guard( const guard& ) = delete;
method guard (line 35) | guard( guard&& ) = delete;
method v_create (line 49) | [[nodiscard]] auto v_create() const -> std::unique_ptr< tao::pq::conne...
function my_poll (line 60) | auto my_poll( const int /*unused*/, const bool /*unused*/, const int /*u...
function run (line 66) | void run()
function main (line 151) | auto main() -> int // NOLINT(bugprone-exception-escape)
FILE: test/integration/example.cpp
function run (line 16) | void run()
function main (line 56) | auto main() -> int
FILE: test/integration/exception.cpp
function run (line 15) | void run()
function main (line 36) | auto main() -> int // NOLINT(bugprone-exception-escape)
FILE: test/integration/large_object.cpp
function test (line 22) | void test( const std::shared_ptr< tao::pq::connection >& connection, con...
function run (line 36) | void run()
function main (line 139) | auto main() -> int
FILE: test/integration/log.cpp
function to_millis (line 18) | [[nodiscard]] auto to_millis( std::chrono::steady_clock::time_point end ...
function run (line 23) | void run()
function main (line 136) | auto main() -> int
FILE: test/integration/notifications.cpp
function handle_notification (line 24) | void handle_notification( const tao::pq::notification& n )
function handle_foo_notification (line 32) | void handle_foo_notification( const char* payload )
function run (line 38) | void run()
function main (line 82) | auto main() -> int // NOLINT(bugprone-exception-escape)
FILE: test/integration/parameter.cpp
function run (line 16) | void run()
function main (line 93) | auto main() -> int // NOLINT(bugprone-exception-escape)
FILE: test/integration/password.cpp
function run (line 17) | void run()
function main (line 36) | auto main() -> int // NOLINT(bugprone-exception-escape)
FILE: test/integration/pipeline_mode.cpp
function run (line 16) | void run()
function main (line 175) | auto main() -> int // NOLINT(bugprone-exception-escape)
FILE: test/integration/result.cpp
function run (line 20) | void run() // NOLINT(readability-function-size)
function main (line 183) | auto main() -> int // NOLINT(bugprone-exception-escape)
FILE: test/integration/row.cpp
function run (line 19) | void run()
function main (line 104) | auto main() -> int // NOLINT(bugprone-exception-escape)
FILE: test/integration/single_row_mode.cpp
function run (line 16) | void run()
function main (line 57) | auto main() -> int // NOLINT(bugprone-exception-escape)
FILE: test/integration/table_reader.cpp
function run (line 19) | void run()
function main (line 121) | auto main() -> int // NOLINT(bugprone-exception-escape)
FILE: test/integration/table_writer.cpp
function run (line 18) | void run()
function main (line 96) | auto main() -> int // NOLINT(bugprone-exception-escape)
FILE: test/integration/traits.cpp
type example (line 15) | namespace example
type user (line 17) | struct user
method user (line 21) | explicit user( const int i ) noexcept
method to_taopq (line 25) | [[nodiscard]] auto to_taopq() const noexcept
method user (line 31) | user( const int in_a, const int in_b, const int in_c, const int in_d...
method from_taopq (line 36) | [[nodiscard]] static auto from_taopq( const int in_a, const int in_b...
type user2 (line 42) | struct user2
method user2 (line 46) | explicit user2( int i ) noexcept
method user2 (line 50) | user2( const int in_a, const int in_b, const int in_c, const int in_...
type user3 (line 55) | struct user3
method user3 (line 59) | explicit user3( int i ) noexcept
method user3 (line 63) | user3( const int in_a, const int in_b, const int in_c, const int in_...
function to_taopq (line 68) | [[nodiscard]] auto to_taopq( const user3& v ) noexcept // NOLINT(misc...
type tao::pq::bind< example::user2 > (line 76) | struct tao::pq::bind< example::user2 >
method to_taopq (line 78) | [[nodiscard]] static auto to_taopq( const example::user2& v ) noexcept
method from_taopq (line 83) | [[nodiscard]] static auto from_taopq( const int a, const int b, const ...
function run (line 91) | void run()
function main (line 169) | auto main() -> int //NOLINT(bugprone-exception-escape)
FILE: test/integration/transaction.cpp
function check_nested (line 18) | void check_nested( const std::shared_ptr< Connection >& connection, cons...
function run (line 56) | void run()
function main (line 129) | auto main() -> int // NOLINT(bugprone-exception-escape)
FILE: test/unit/getenv.cpp
function run (line 13) | void run()
function main (line 25) | auto main() -> int
FILE: test/unit/parameter_type.cpp
type example (line 87) | namespace example
type user (line 89) | struct user
type user2 (line 96) | struct user2
function main (line 111) | auto main() -> int
FILE: test/unit/resize_uninitialized.cpp
function test (line 17) | void test( std::string& s, const std::size_t size )
function run (line 24) | void run()
function main (line 70) | auto main() -> int
FILE: test/unit/result_type.cpp
type example (line 85) | namespace example
type user (line 87) | struct user
type user2 (line 94) | struct user2
function main (line 109) | auto main() -> int
FILE: test/unit/strtox.cpp
function main (line 6) | auto main() -> int {}
function reject_floating_point (line 24) | void reject_floating_point( const char* input )
function run (line 55) | void run()
function main (line 127) | auto main() -> int // NOLINT(bugprone-exception-escape)
FILE: test/utils/compare.hpp
type tao::pq::internal (line 12) | namespace tao::pq::internal
function compare (line 15) | [[nodiscard]] auto compare( const T& lhs, const U& rhs ) noexcept -> bool
FILE: test/utils/getenv.hpp
type tao::pq::internal (line 19) | namespace tao::pq::internal
function getenv (line 23) | [[nodiscard]] inline auto getenv( const std::string& name ) -> std::st...
function getenv (line 34) | [[nodiscard]] inline auto getenv( const std::string& name, const std::...
function getenv (line 47) | [[nodiscard]] inline auto getenv( const std::string& name ) -> std::st...
function getenv (line 53) | [[nodiscard]] inline auto getenv( const std::string& name, const std::...
Condensed preview — 146 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (632K chars).
[
{
"path": ".clang-format",
"chars": 2682,
"preview": "# The Art of C++\n# https://github.com/taocpp\n\n# Copyright (c) 2016-2026 Dr. Colin Hirsch and Daniel Frey\n# Distributed u"
},
{
"path": ".clang-tidy",
"chars": 1644,
"preview": "# The Art of C++\n# https://github.com/taocpp\n\n# Copyright (c) 2016-2026 Dr. Colin Hirsch and Daniel Frey\n# Distributed u"
},
{
"path": ".github/conan/conanfile.py",
"chars": 1006,
"preview": "from conan import ConanFile\nfrom conan.tools.cmake import CMakeDeps, CMakeToolchain, cmake_layout\n\nclass TaopqRequiremen"
},
{
"path": ".github/conan/profiles/clangcl",
"chars": 586,
"preview": "[settings]\nos=Windows\narch=x86_64\nbuild_type=Release\ncompiler=clang\ncompiler.version=19\ncompiler.cppstd=20\ncompiler.runt"
},
{
"path": ".github/conan/profiles/msvc",
"chars": 255,
"preview": " [settings]\narch=x86_64\nbuild_type=Release\ncompiler=msvc\ncompiler.cppstd=20\ncompiler.runtime=dynamic\ncompiler.runtime_ty"
},
{
"path": ".github/workflows/clang-analyze.yml",
"chars": 572,
"preview": "name: clang-analyze\n\non:\n push:\n paths-ignore:\n - 'README.md'\n - 'doc/**'\n pull_request:\n paths-ignore"
},
{
"path": ".github/workflows/clang-format.yml",
"chars": 344,
"preview": "name: clang-format\n\non:\n push:\n paths-ignore:\n - 'README.md'\n - 'doc/**'\n pull_request:\n paths-ignore:"
},
{
"path": ".github/workflows/clang-tidy.yml",
"chars": 663,
"preview": "name: clang-tidy\n\non:\n push:\n paths-ignore:\n - 'README.md'\n - 'doc/**'\n pull_request:\n paths-ignore:\n "
},
{
"path": ".github/workflows/code-coverage.yml",
"chars": 1427,
"preview": "name: code-coverage\n\non:\n push:\n paths-ignore:\n - 'README.md'\n - 'doc/**'\n pull_request:\n paths-ignore"
},
{
"path": ".github/workflows/linux.yml",
"chars": 5355,
"preview": "name: Linux\n\non:\n push:\n paths-ignore:\n - 'README.md'\n - 'doc/**'\n pull_request:\n paths-ignore:\n "
},
{
"path": ".github/workflows/macos.yml",
"chars": 1345,
"preview": "name: macOS\n\non:\n push:\n paths-ignore:\n - 'README.md'\n - 'doc/**'\n pull_request:\n paths-ignore:\n "
},
{
"path": ".github/workflows/sanitizer.yml",
"chars": 1374,
"preview": "name: Sanitizer\n\non:\n push:\n paths-ignore:\n - 'README.md'\n - 'doc/**'\n pull_request:\n paths-ignore:\n "
},
{
"path": ".github/workflows/windows.yml",
"chars": 1688,
"preview": "name: Windows\n\non:\n push:\n paths-ignore:\n - 'README.md'\n - 'doc/**'\n pull_request:\n paths-ignore:\n "
},
{
"path": ".gitignore",
"chars": 19,
"preview": "*~\nbuild\ndummy.txt\n"
},
{
"path": "CMakeLists.txt",
"chars": 7565,
"preview": "cmake_minimum_required(VERSION 3.15)\n\n# Read version from version.hpp\nfile(READ \"${CMAKE_CURRENT_SOURCE_DIR}/include/tao"
},
{
"path": "CMakePresets.json",
"chars": 8678,
"preview": "{\n \"version\": 6,\n \"cmakeMinimumRequired\": {\n \"major\": 3,\n \"minor\": 21,\n \"patch\": 0\n },\n \"configurePresets\":"
},
{
"path": "LICENSE_1_0.txt",
"chars": 1338,
"preview": "Boost Software License - Version 1.0 - August 17th, 2003\n\nPermission is hereby granted, free of charge, to any person or"
},
{
"path": "Makefile",
"chars": 2708,
"preview": "# The Art of C++\n# https://github.com/taocpp\n\n# Copyright (c) 2016-2026 Daniel Frey\n# Distributed under the Boost Softwa"
},
{
"path": "README.md",
"chars": 5891,
"preview": "# Welcome to taoPQ\n\n[](https://github.com/taoc"
},
{
"path": "doc/Aggregate-Support.md",
"chars": 3442,
"preview": "# Aggregate Support\n\ntaoPQ allows the direct use of \"simple\" aggregates as parameters and result types.\n\n## Requirements"
},
{
"path": "doc/Binary-Data.md",
"chars": 3258,
"preview": "# Binary Data\n\nPostgreSQL stores binary data either as a field with the [`BYTEA`➚](https://www.postgresql.org/docs/curre"
},
{
"path": "doc/Bulk-Transfer.md",
"chars": 6039,
"preview": "# Bulk Transfer\n\n**TODO**\n\n## Synopsis\n\nDon't be intimidated by the size of the API, as you can see several methods are "
},
{
"path": "doc/Connection-Pool.md",
"chars": 7137,
"preview": "# Connection Pool\n\nOpening a new connection to the database server typically consists of several time-consuming steps.\nA"
},
{
"path": "doc/Connection.md",
"chars": 17134,
"preview": "# Connection\n\nAll communication with a database server is handled through a connection, represented by the `tao::pq::con"
},
{
"path": "doc/Error-Handling.md",
"chars": 3889,
"preview": "# Error Handling\n\n## SQL errors\n\nWhen an SQL statement is [executed](Statement.md) and the execution fails, an exception"
},
{
"path": "doc/Getting-Started.md",
"chars": 5353,
"preview": "# Getting Started\n\nBefore we start with taoPQ, we'd like to point you to the excellent [PostgreSQL documentation➚](https"
},
{
"path": "doc/Installation.md",
"chars": 2190,
"preview": "# Installation\n\n## Using CMake\n\nSince CMake 3.11, the feature [FetchContent➚](https://cmake.org/cmake/help/latest/module"
},
{
"path": "doc/Large-Object.md",
"chars": 9296,
"preview": "# Large Object\n\nPostgreSQL has a [large object➚](https://www.postgresql.org/docs/current/largeobjects.html) facility, wh"
},
{
"path": "doc/Parameter-Type-Conversion.md",
"chars": 5522,
"preview": "# Parameter Type Conversion\n\nWhen [executing statements](Statement.md), you can pass any number of parameters after the "
},
{
"path": "doc/Performance.md",
"chars": 330,
"preview": "# Performance\n\n**TODO**\n\n---\n\nThis document is part of [taoPQ](https://github.com/taocpp/taopq).\n\nCopyright (c) 2021-202"
},
{
"path": "doc/Requirements.md",
"chars": 2202,
"preview": "# Requirements\n\n## Operating System Support\n\n* We support:\n * [Windows➚](https://en.wikipedia.org/wiki/Microsoft_Window"
},
{
"path": "doc/Result-Type-Conversion.md",
"chars": 4920,
"preview": "# Result Type Conversion\n\nDepending on what type of [statement](Statement.md) was executed, you receive a [result](Resul"
},
{
"path": "doc/Result.md",
"chars": 14972,
"preview": "# Result\n\nWhen [executing statements](Statement.md) you receive a result object.\nA result comes in two flavours, dependi"
},
{
"path": "doc/Statement.md",
"chars": 7035,
"preview": "# Statement\n\n:warning: Before showing you how to execute statements with taoPQ, we'd like to take a moment to talk about"
},
{
"path": "doc/TOC.md",
"chars": 7212,
"preview": "# Table of Content\n\n* [Requirements](Requirements.md)\n * [Operating System Support](Requirements.md#operator-system-sup"
},
{
"path": "doc/Transaction.md",
"chars": 7297,
"preview": "# Transaction\n\nBefore we continue with our own documentation, we'd like to once again point you to the excellent [Postgr"
},
{
"path": "example/CMakeLists.txt",
"chars": 440,
"preview": "cmake_minimum_required(VERSION 3.15)\n\nadd_subdirectory(get_version)\n\nset(EXAMPLE_TARGETS\n taopq_example_get_version\n)\n\n"
},
{
"path": "example/get_version/CMakeLists.txt",
"chars": 248,
"preview": "cmake_minimum_required(VERSION 3.15)\nproject(taopq_example_get_version CXX)\n\nadd_executable(${PROJECT_NAME} main.cpp)\nta"
},
{
"path": "example/get_version/main.cpp",
"chars": 880,
"preview": "#include <cstdlib>\n#include <iostream>\n#include <string>\n#include <vector>\n\n#include <tao/pq.hpp>\n\nstatic std::string ge"
},
{
"path": "include/tao/pq/access_mode.hpp",
"chars": 955,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/binary.hpp",
"chars": 1248,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/bind.hpp",
"chars": 357,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/connection.hpp",
"chars": 8830,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/connection_pool.hpp",
"chars": 2682,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/connection_status.hpp",
"chars": 887,
"preview": "// Copyright (c) 2022-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/exception.hpp",
"chars": 37608,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/field.hpp",
"chars": 1608,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/internal/aggregate.hpp",
"chars": 4880,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/internal/demangle.hpp",
"chars": 722,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/internal/exclusive_scan.hpp",
"chars": 955,
"preview": "// Copyright (c) 2019-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/internal/format_as.hpp",
"chars": 902,
"preview": "// Copyright (c) 2024-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/internal/from_chars.hpp",
"chars": 1378,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/internal/gen.hpp",
"chars": 1461,
"preview": "// Copyright (c) 2019-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/internal/parameter_traits_helper.hpp",
"chars": 2757,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/internal/poll.hpp",
"chars": 500,
"preview": "// Copyright (c) 2023-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/internal/pool.hpp",
"chars": 4609,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/internal/resize_uninitialized.hpp",
"chars": 6541,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/internal/strtox.hpp",
"chars": 547,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/internal/unreachable.hpp",
"chars": 480,
"preview": "// Copyright (c) 2020-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/internal/zsv.hpp",
"chars": 891,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/is_aggregate.hpp",
"chars": 593,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/is_array.hpp",
"chars": 2217,
"preview": "// Copyright (c) 2024-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/isolation_level.hpp",
"chars": 1239,
"preview": "// Copyright (c) 2020-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/large_object.hpp",
"chars": 2895,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/log.hpp",
"chars": 4305,
"preview": "// Copyright (c) 2024-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/notification.hpp",
"chars": 1211,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/null.hpp",
"chars": 443,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/oid.hpp",
"chars": 498,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/parameter.hpp",
"chars": 6183,
"preview": "// Copyright (c) 2023-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/parameter_traits.hpp",
"chars": 13999,
"preview": "// Copyright (c) 2020-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/parameter_traits_aggregate.hpp",
"chars": 1567,
"preview": "// Copyright (c) 2020-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/parameter_traits_array.hpp",
"chars": 2542,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/parameter_traits_optional.hpp",
"chars": 2378,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/parameter_traits_pair.hpp",
"chars": 2774,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/parameter_traits_tuple.hpp",
"chars": 3040,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/pipeline.hpp",
"chars": 1464,
"preview": "// Copyright (c) 2024-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/pipeline_status.hpp",
"chars": 985,
"preview": "// Copyright (c) 2024-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/poll.hpp",
"chars": 1052,
"preview": "// Copyright (c) 2023-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/result.hpp",
"chars": 10172,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/result_status.hpp",
"chars": 2179,
"preview": "// Copyright (c) 2024-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/result_traits.hpp",
"chars": 5503,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/result_traits_aggregate.hpp",
"chars": 1846,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/result_traits_array.hpp",
"chars": 2917,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/result_traits_optional.hpp",
"chars": 1087,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/result_traits_pair.hpp",
"chars": 855,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/result_traits_tuple.hpp",
"chars": 1724,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/row.hpp",
"chars": 8172,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/table_field.hpp",
"chars": 1608,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/table_reader.hpp",
"chars": 6676,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/table_row.hpp",
"chars": 7530,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/table_writer.hpp",
"chars": 3430,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/transaction.hpp",
"chars": 3102,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/transaction_base.hpp",
"chars": 5490,
"preview": "// Copyright (c) 2024-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/transaction_status.hpp",
"chars": 1243,
"preview": "// Copyright (c) 2022-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq/version.hpp",
"chars": 403,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "include/tao/pq.hpp",
"chars": 1337,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "src/lib/pq/connection.cpp",
"chars": 23295,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "src/lib/pq/connection_pool.cpp",
"chars": 1137,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "src/lib/pq/exception.cpp",
"chars": 41768,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "src/lib/pq/field.cpp",
"chars": 731,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "src/lib/pq/internal/demangle.cpp",
"chars": 748,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "src/lib/pq/internal/poll.cpp",
"chars": 3617,
"preview": "// Copyright (c) 2023-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "src/lib/pq/internal/strtox.cpp",
"chars": 3232,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "src/lib/pq/large_object.cpp",
"chars": 6780,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "src/lib/pq/parameter_traits.cpp",
"chars": 1638,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "src/lib/pq/pipeline.cpp",
"chars": 1112,
"preview": "// Copyright (c) 2024-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "src/lib/pq/result.cpp",
"chars": 4192,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "src/lib/pq/result_traits.cpp",
"chars": 4404,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "src/lib/pq/result_traits_array.cpp",
"chars": 1346,
"preview": "// Copyright (c) 2024-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "src/lib/pq/row.cpp",
"chars": 2753,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "src/lib/pq/table_field.cpp",
"chars": 651,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "src/lib/pq/table_reader.cpp",
"chars": 4975,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "src/lib/pq/table_row.cpp",
"chars": 1837,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "src/lib/pq/table_writer.cpp",
"chars": 2362,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "src/lib/pq/transaction.cpp",
"chars": 4365,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "src/lib/pq/transaction_base.cpp",
"chars": 3853,
"preview": "// Copyright (c) 2024-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "test/CMakeLists.txt",
"chars": 1816,
"preview": "cmake_minimum_required(VERSION 3.15)\n\noption(BUILD_INTEGRATION_TESTS \"Build integration tests that require a live Postgr"
},
{
"path": "test/integration/aggregate.cpp",
"chars": 1836,
"preview": "// Copyright (c) 2020-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "test/integration/array.cpp",
"chars": 6989,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "test/integration/basic_datatypes.cpp",
"chars": 16030,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "test/integration/chunk_mode.cpp",
"chars": 3164,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "test/integration/connection.cpp",
"chars": 6945,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "test/integration/connection_pool.cpp",
"chars": 5369,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "test/integration/example.cpp",
"chars": 1998,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "test/integration/exception.cpp",
"chars": 1629,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "test/integration/large_object.cpp",
"chars": 5564,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "test/integration/log.cpp",
"chars": 6708,
"preview": "// Copyright (c) 2024-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "test/integration/notifications.cpp",
"chars": 2772,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "test/integration/parameter.cpp",
"chars": 2989,
"preview": "// Copyright (c) 2023-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "test/integration/password.cpp",
"chars": 1458,
"preview": "// Copyright (c) 2024-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "test/integration/pipeline_mode.cpp",
"chars": 5834,
"preview": "// Copyright (c) 2024-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "test/integration/result.cpp",
"chars": 10413,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "test/integration/row.cpp",
"chars": 4320,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "test/integration/single_row_mode.cpp",
"chars": 2234,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "test/integration/table_reader.cpp",
"chars": 6100,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "test/integration/table_writer.cpp",
"chars": 4708,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "test/integration/traits.cpp",
"chars": 6654,
"preview": "// Copyright (c) 2020-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "test/integration/transaction.cpp",
"chars": 7234,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "test/unit/getenv.cpp",
"chars": 1052,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "test/unit/parameter_type.cpp",
"chars": 4222,
"preview": "// Copyright (c) 2023-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "test/unit/resize_uninitialized.cpp",
"chars": 2375,
"preview": "// Copyright (c) 2021-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "test/unit/result_type.cpp",
"chars": 4010,
"preview": "// Copyright (c) 2023-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "test/unit/strtox.cpp",
"chars": 6112,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "test/utils/compare.hpp",
"chars": 801,
"preview": "// Copyright (c) 2024-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "test/utils/getenv.hpp",
"chars": 1976,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
},
{
"path": "test/utils/macros.hpp",
"chars": 3222,
"preview": "// Copyright (c) 2016-2026 Daniel Frey and Dr. Colin Hirsch\n// Distributed under the Boost Software License, Version 1.0"
}
]
About this extraction
This page contains the full source code of the taocpp/taopq GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 146 files (586.6 KB), approximately 153.0k tokens, and a symbol index with 1002 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.