Skip to content

About

Asynchronous PostgreSQL component for open.mp (C++20/libpq) with connection pooling, prepared statements, typed parameters, SQL sections, batch execution, transactions, streaming, Pawn callbacks, and configurable logging.

Topics

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

omp-postgresql

Introduction · Installation · Quick Start · Documentation · Building and Testing · License

Introduction

omp-postgresql is a C++20 component that brings PostgreSQL to open.mp through libpq and an asynchronous, parameterized Pawn API. Database work runs on background workers; callbacks deliver connection changes and results on server ticks.

  • Service-profile connections, FIFO lanes, timeouts, cancellation and progressive reconnection.
  • Typed parameters, immutable snapshots, bounded batches and SQL files with named sections.
  • Transactions, savepoints, explicit per-operation results and bounded streaming with backpressure.
  • NULL, RETURNING, SQLSTATE, column metadata, exact numeric/temporal text, BYTEA and typed arrays.
  • VM-generation ownership, custom completion callbacks and configurable bounded diagnostics.

There is no ORM, query builder, password hashing, application cache or synchronous Pawn query API. Uncertain writes are never replayed automatically. Pipeline mode is benchmarked separately; the execution engine does not use it. See the execution guide for API guarantees.

Development status: stable v0.1.0 remains blocked. Source preparation and version metadata do not establish stable readiness or authorize publication. Use development artifacts only for testing and evaluation; review the release gates and validated platforms and known limitations.

Installation

  1. Choose a matching package from the releases page or a development CI artifact, and verify its exact source identity and SHA-256.
  2. Copy PostgreSQL.dll or PostgreSQL.so into components/, and omp_postgresql.inc into your Pawn compiler's include directory. Keep the include and binary from the same distribution.
  3. Install the runtime dependencies and configure the service profile below. Keep the open.mp Pawn component enabled; do not register this as a legacy SA-MP plugin.

Follow the installation guide for package verification, runtime placement and a first server test. Published RC packages retain their original filenames; the names above apply to the current source. Validated server distributions target open.mp 1.5.8.3079 x86 on Windows and Linux (dynssl). Match every dependency's architecture and ABI: an x64 DLL cannot load into an x86 server, and x64 engine tests do not establish x64 server compatibility.

When migrating from RC.1/RC.2, replace #include <omp-postgresql> with #include <omp_postgresql> and recompile. Stop the server before replacing the old binary; keep only one copy of the component. Public Pawn signatures, UID and the internal omp-postgresql identity remain unchanged. See the migration instructions.

Keep passwords out of Pawn and version control. Use PGPASSFILE/.pgpass with Unix permissions 0600 (restricted service-account ACLs on Windows), certificate authentication or another libpq-managed mechanism. For remote services, use sslmode=verify-full, a trusted CA and a hostname matching the certificate; require encrypts without the same identity guarantee. Client certificates use sslcert/sslkey and suitable PostgreSQL authentication rules. See secure configuration, libpq SSL and service profiles.

Quick Start

pg_connect("game") uses the PostgreSQL service profile named game. Configure its connection details and PGSERVICEFILE before starting the server, following Install and configure and the example profile. The request is asynchronous: a valid handle means local acceptance; wait for OnPgConnection to report PG_CONNECTED before using the connection.

1. Declare the connection handle

Include open.mp and omp-postgresql, then initialize the connection handle as invalid.

#include <open.mp>
#include <omp_postgresql>

new g_Database = PG_INVALID;

2. Request a connection

OnGameModeInit requests a connection using the game service profile. A valid handle confirms only that the request was accepted locally; it does not mean the database is ready.

public OnGameModeInit() {
	g_Database = pg_connect("game");

	if (g_Database == PG_INVALID) {
		new error[256];

		pg_last_error(error);
		printf("[PostgreSQL] Connection request rejected: %s", error);
	}

	return 1;
}

3. Handle connection events

OnPgConnection reports when PostgreSQL is ready. On a connection failure, inspect the diagnostic message for lane 0 and close the failed connection. A disconnection also invalidates the stored handle.

public OnPgConnection(connection, connection_state) {
	if (connection != g_Database) return 1;

	switch (connection_state) {
		case PG_CONNECTED: {
			print("[PostgreSQL] Connected successfully.");
		}

		case PG_CONNECTION_FAILED: {
			new error[256];

			if (pg_connection_message(connection, 0, error) && error[0]) {
				printf("[PostgreSQL] Connection failed: %s", error);
			} else {
				print("[PostgreSQL] Connection failed.");
			}

			pg_connection_close(connection);
			g_Database = PG_INVALID;
		}

		case PG_DISCONNECTED: {
			g_Database = PG_INVALID;
		}
	}

	return 1;
}

4. Close the connection on shutdown

OnGameModeExit closes an existing connection when the gamemode unloads.

public OnGameModeExit() {
	if (g_Database != PG_INVALID) {
		pg_connection_close(g_Database);
		g_Database = PG_INVALID;
	}

	return 1;
}

The default is one lane (lane 0). PG_CONNECTED means every configured lane is ready, not that future operations are guaranteed to succeed; pg_connection_ready reports connected physical sessions. Additional lanes are an explicit concurrency decision described in the execution guide. Callbacks must return promptly without sleep; callback continuations are unsupported. Connection diagnostics can contain sensitive information: keep test output private and redact or restrict production logs as explained in security and error inspection.

Documentation

Topic Guides
Start here Installation, Getting started, Examples and learning path
Choose and use the API Quick reference, Execution guide, Native reference, Callbacks, Types
Build gameplay features Accounts and player sessions, Saving, Transactions, SQL file sections
Operate safely Troubleshooting, Debugging and logging, Security and concurrency
Understand and contribute Architecture, Windows builds, Linux builds, Language policy
Review evidence and limits Validation, Performance, Pawn logging qualification, Independent audit
Package and release Packaging, Readiness, Pre-soak checklist, Release procedure, Release notes

Prefer custom completion callbacks for new application code; OnPgComplete(job, context) remains supported. Pre-RC.1 code using the removed pg_prepare_section must migrate to pg_prepare_file(..., section) and recompile; see cleanup and migration and the bounded API audit. Include and component versions must match.

Building and Testing

Requirements: CMake 3.24+, a C++20 compiler, Git and libpq 17+ with TLS and thread support. FetchContent obtains the SDK and Pawn headers at pinned commits; Boost and pawn-natives are not required. Build all dependencies for the server's architecture and ABI. Linux x86 needs a multilib toolchain and 32-bit libpq; Windows MSVC/MinGW builds need compatible import libraries. Follow the Windows or Linux guide for details.

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DPostgreSQL_ROOT=/path/to/postgresql
cmake --build build --parallel
ctest --test-dir build --output-on-failure
cmake --install build --prefix /path/to/server

PostgreSQL_ROOT contains the include/lib directories. PG_BUILD_COMPONENT=OFF builds only the engine and tests. PG_PAWN_INCLUDE_DIR overrides the install destination, qawno/include. Use PG_SANITIZE=ON for ASan/UBSan on supported toolchains, or a separate Linux x64 build with PG_THREAD_SANITIZE=ON. See qualification controls for stress reproduction and limits.

Compile Pawn with the official open.mp 3.10.11 compiler, 32-bit cells, official includes and warnings treated as errors (-E). CI compiles all thirteen public examples and the classified Markdown examples, including from extracted x86 packages. Start with smoke.pwn and expect PG SMOKE PASS in a disposable server; the example catalogue describes the broader learning and validation paths. Eleven public examples run unattended. The interactive account example requires an optional external hashing provider and denies authentication by default. The bounded real-client qualification excludes rendered clients, the official-client encrypted connection path, untested providers/environments and the 24-hour campaign.

For a temporary, loopback-only TLS database and CTest (put initdb, pg_ctl, psql, openssl and ctest on PATH; use a non-root Unix account):

python tests/run_postgres.py --build build

The runner shuts down its temporary instance even on failure and leaves the directory for inspection; it does not use an existing database. CTest skips integration with exit code 77 when OMP_PG_TEST_SERVICE is unset; a skip is not a successful integration run. See validation for lifecycle, stalled-connection, native-boundary and stress coverage. Use the existing benchmark procedure and Pawn workload evidence with their recorded source identities: local samples are not performance guarantees, do not isolate component tick cost and do not establish superiority over other components. Direct libpq/engine probes do not measure Pawn ticks.

Keep comments, diagnostics, examples and documentation in natural technical English. Follow .editorconfig and .clang-format; C++/Pawn use tabs displayed as four columns. Pawn formatting is manual and compiler-checked. Run checks appropriate to the change; documentation checks are:

python scripts/check_docs.py
python scripts/check_english.py
python scripts/compile_examples.py --compiler /path/to/pawncc --include pawn --include /path/to/omp-stdlib --include /path/to/pawn/include --output build --docs

For code changes, format C++ with clang-format, check Python/CMake with python -m black --check tests and python -m cmakelang.format --check CMakeLists.txt, and run the relevant unit, integration and server checks before publishing.

Release status and publication

Stable v0.1.0 remains blocked. Required corrections need owner-approved integration and successful CI on the exact final master commit, followed by a freeze and isolated-host preflight including 100,000 semantic fuzz cases before the final 24-hour campaign. The campaign and tag/publication each require separate owner authorization. Later source or deployment changes require impact review, affected checks and a new freeze/final campaign; see readiness and the release procedure.

CI produces Windows/Linux x86 ZIPs and SHA-256 after fresh-server tests of extracted packages. These are qualification artifacts; building them does not publish a release. The existing v0.1.0-rc.1 and v0.1.0-rc.2 retain their original tags, assets, checksums, release notes and historical evidence.

License

Original project code is licensed under MIT. Dependencies, the SDK and Pawn retain their licenses and notices; no reference plugin is linked or copied. Retain the installed notices in share/omp-postgresql and the packaged dependency licenses. See NOTICE.md and DEPENDENCIES.md for attribution and runtime requirements.

About

Asynchronous PostgreSQL component for open.mp (C++20/libpq) with connection pooling, prepared statements, typed parameters, SQL sections, batch execution, transactions, streaming, Pawn callbacks, and configurable logging.

Topics

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Contributors

Languages