ores.database
Table of Contents
2. Summary
ores.database is the shared PostgreSQL access layer used by every domain
service, built on libpq, the PostgreSQL C client.
- A
contextnames who a statement acts for: the tenant, the party and the parties it sees, the actor, and the service account. Copies of a context share onepq::poolof long-lived connections to pgbouncer, which runs in transaction pooling mode in front of PostgreSQL. The pool opens under an open policy that retries a database that refuses connections while it restarts. - Every call runs in one
pq::transaction, which sets the context's tenant, party, visible parties, actor and service as transaction-local settings, pipelined with its first statement. The row-level security policies and the audit columns read them, and they end with the transaction, so a pooled connection carries nothing from one caller to the next. - A
repository::unit_of_workleases one connection and holds one transaction; the context it hands out is bound to that transaction, so every call made with it joins the unit of work, which commits once or rolls back. A call on a unit of work that has committed is refused, and a commit after a failed statement rolls back and throws. - Generated repositories state their queries with
query_builderand run them through itsexecute_*helpers, binding and reading each column in the binary format, in its own C++ type. Hand-written SQL runs through the raw helpers ofrepository/bitemporal_operations.hpp, on the same pool and the same unit of work as the repositories. - A
health_monitorprobes the database, and apostgres_listener_serviceholds a direct connection to PostgreSQL for LISTEN/NOTIFY, which needs a session that transaction pooling does not give.
The data path sets out the design: pooled long-lived connections, a unit of work that hands repositories an open transaction, typed statements and classed errors.
The component owns no codegen entity models. It is hand-written
infrastructure, and every type it exposes stays below the audit, history and
eventing stacks it would otherwise have to link. The ores_database_info_tbl
table lives in the SQL technical space under projects/ores.sql.
context_factory::make_context refuses a database built from other SQL. The
build compiles in the schema fingerprint of projects/ores.sql; the context
factory reads the fingerprint the database recorded at recreate, logs both,
and throws schema_mismatch_exception when they differ. Service mains map
it to exit_code::schema_mismatch after printing its message.
3. Inputs
- PostgreSQL connection string from service configuration.
- Tenant and party identifiers set per request for row-level security.
4. Outputs
- Transactions on pooled libpq connections that act for a context's tenant and party.
- Bitemporal entity CRUD results with version-conflict detection.
5. Entry points
include/ores.database/domain/—database_options,context,transact.include/ores.database/repository/—unit_of_work, the raw-SQL helpers, mapper helpers.include/ores.database/query_builder/— the query builder and itsexecute_*helpers.include/ores.database/service/—health_monitor,postgres_listener_service,tenant_context,party_context.include/ores.database/config/—database_configurationparsing.include/ores.database/pq/— the libpq layer:pool,transact,transaction,statement, the binarycodecof each type, andstore_error.
6. Dependencies
- libpq, the PostgreSQL C client, for the
pqlayer. ores.logging— structured logging.
7. Entity modules
None. The component has no codegen entity models.
8. See also
- The data path — the design of this layer.
target_link_libraries(${lib_target_name}
PUBLIC
ores.logging.lib
ores.platform.lib
PRIVATE
ores.utility.lib)
target_link_libraries(${lib_target_name} PRIVATE ores.codec.pch)
target_link_libraries(${tests_target_name}
PRIVATE
${lib_target_name}
ores.testing.lib
ores.logging.lib
Catch2::Catch2
faker-cxx::faker-cxx
ores.openssl_cleanup
Threads::Threads)
