Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 33 additions & 33 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,61 +21,61 @@ jobs:

- name: Start PostgreSQL ${{ matrix.pg_version }}
run: |
docker run -d --name pgque-test \
-e POSTGRES_PASSWORD=pgque_test \
-e POSTGRES_DB=pgque_test \
docker run -d --name logres-test \
-e POSTGRES_PASSWORD=logres_test \
-e POSTGRES_DB=logres_test \
-p 5432:5432 \
postgres:${{ matrix.pg_version }}

# Wait for PG to be ready
for i in $(seq 1 30); do
docker exec pgque-test pg_isready -U postgres && break
docker exec logres-test pg_isready -U postgres && break
sleep 1
done || { echo "PG not ready after 30 seconds"; exit 1; }

- name: Build pgque
- name: Build logres
run: bash build/transform.sh

- name: Install pgque
- name: Install logres
run: |
PGPASSWORD=pgque_test psql -h localhost -U postgres -d pgque_test \
-v ON_ERROR_STOP=1 -f sql/pgque.sql
PGPASSWORD=logres_test psql -h localhost -U postgres -d logres_test \
-v ON_ERROR_STOP=1 -f sql/logres.sql

- name: Run regression tests
run: |
PGPASSWORD=pgque_test psql -h localhost -U postgres -d pgque_test \
PGPASSWORD=logres_test psql -h localhost -U postgres -d logres_test \
-v ON_ERROR_STOP=1 -f tests/run_all.sql

- name: Run acceptance tests
run: |
PGPASSWORD=pgque_test psql -h localhost -U postgres -d pgque_test \
PGPASSWORD=logres_test psql -h localhost -U postgres -d logres_test \
-v ON_ERROR_STOP=1 -f tests/acceptance/run_acceptance.sql

- name: Test install idempotency
run: |
# Re-run install -- should produce no errors
PGPASSWORD=pgque_test psql -h localhost -U postgres -d pgque_test \
-v ON_ERROR_STOP=1 -f sql/pgque.sql
PGPASSWORD=logres_test psql -h localhost -U postgres -d logres_test \
-v ON_ERROR_STOP=1 -f sql/logres.sql
# Verify everything still works
PGPASSWORD=pgque_test psql -h localhost -U postgres -d pgque_test \
PGPASSWORD=logres_test psql -h localhost -U postgres -d logres_test \
-v ON_ERROR_STOP=1 -f tests/test_install_idempotency.sql

- name: Test uninstall
run: |
PGPASSWORD=pgque_test psql -h localhost -U postgres -d pgque_test \
-v ON_ERROR_STOP=1 -f sql/pgque_uninstall.sql
PGPASSWORD=logres_test psql -h localhost -U postgres -d logres_test \
-v ON_ERROR_STOP=1 -f sql/logres_uninstall.sql
# Verify schema is gone
result=$(PGPASSWORD=pgque_test psql -h localhost -U postgres -d pgque_test \
-v ON_ERROR_STOP=1 -tAc "select count(*) from pg_namespace where nspname = 'pgque'")
result=$(PGPASSWORD=logres_test psql -h localhost -U postgres -d logres_test \
-v ON_ERROR_STOP=1 -tAc "select count(*) from pg_namespace where nspname = 'logres'")
if [ "$result" != "0" ]; then
echo "FAIL: pgque schema still exists after uninstall"
echo "FAIL: logres schema still exists after uninstall"
exit 1
fi
echo "PASS: pgque schema removed after uninstall"
echo "PASS: logres schema removed after uninstall"

- name: Cleanup
if: always()
run: docker rm -f pgque-test
run: docker rm -f logres-test

client-smoke:
runs-on: ubuntu-latest
Expand All @@ -86,28 +86,28 @@ jobs:

- name: Start PostgreSQL 18
run: |
docker run -d --name pgque-client-test \
-e POSTGRES_PASSWORD=pgque_test \
-e POSTGRES_DB=pgque_test \
docker run -d --name logres-client-test \
-e POSTGRES_PASSWORD=logres_test \
-e POSTGRES_DB=logres_test \
-p 5432:5432 \
postgres:18

for i in $(seq 1 30); do
docker exec pgque-client-test pg_isready -U postgres && break
docker exec logres-client-test pg_isready -U postgres && break
sleep 1
done || { echo "PG not ready after 30 seconds"; exit 1; }

- name: Build pgque
- name: Build logres
run: bash build/transform.sh

- name: Install pgque
- name: Install logres
run: |
PGPASSWORD=pgque_test psql -h localhost -U postgres -d pgque_test \
-v ON_ERROR_STOP=1 -f sql/pgque.sql
PGPASSWORD=pgque_test psql -h localhost -U postgres -d pgque_test \
-v ON_ERROR_STOP=1 -c "select pgque.create_queue('smoke_py'); select pgque.create_queue('smoke_go'); select pgque.create_queue('smoke_ts');"
PGPASSWORD=pgque_test psql -h localhost -U postgres -d pgque_test \
-v ON_ERROR_STOP=1 -c "select pgque.force_tick('smoke_py'); select pgque.force_tick('smoke_go'); select pgque.force_tick('smoke_ts'); select pgque.ticker();"
PGPASSWORD=logres_test psql -h localhost -U postgres -d logres_test \
-v ON_ERROR_STOP=1 -f sql/logres.sql
PGPASSWORD=logres_test psql -h localhost -U postgres -d logres_test \
-v ON_ERROR_STOP=1 -c "select logres.create_queue('smoke_py'); select logres.create_queue('smoke_go'); select logres.create_queue('smoke_ts');"
PGPASSWORD=logres_test psql -h localhost -U postgres -d logres_test \
-v ON_ERROR_STOP=1 -c "select logres.force_tick('smoke_py'); select logres.force_tick('smoke_go'); select logres.force_tick('smoke_ts'); select logres.ticker();"

- name: Python smoke
run: |
Expand All @@ -129,7 +129,7 @@ jobs:

- name: Cleanup client smoke DB
if: always()
run: docker rm -f pgque-client-test
run: docker rm -f logres-client-test

verify:
runs-on: ubuntu-latest
Expand Down
47 changes: 23 additions & 24 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
# CLAUDE.md -- PgQue
# CLAUDE.md -- logres

## Project

PgQue (pgque) -- PgQ Universal Edition. Zero-bloat PostgreSQL queue repackaged
from PgQ for managed database environments. Repo: NikolayS/pgque.
logres -- zero-bloat event log for Postgres, derived from PgQ (Skype). Runs on
any Postgres 14+ platform, managed providers included. Repo: NikolayS/logres.

## Naming Convention
## Naming convention

- `pgque` -- lowercase for schema, package names, CLI, repo, function prefixes
- `PgQue` -- capitalized form for prose, headings, README titles
- `logres` -- always lowercase (schema, package names, CLI, repo, prose, headings)
- Mirrors PostgreSQL ecosystem convention (pgmq, pg_cron, psycopg)

## Architecture

Two-layer design:

- **pgque-core:** Productization of PgQ (rename, PG14+ modernization, pg_cron,
- **logres-core:** Productization of PgQ (rename, PG14+ modernization, pg_cron,
security hardening, single-file install). Mechanical transformation of ~4,028
lines of proven PL/pgSQL.
- **pgque-api:** Modern convenience layer (send/receive/ack/nack, DLQ, delayed
- **logres-api:** Modern convenience layer (send/receive/ack/nack, DLQ, delayed
delivery). New code (~1,500 lines) that must reduce cleanly to PgQ primitives.

See `blueprints/SPECx.md` for the full specification.
Expand All @@ -28,7 +27,7 @@ snapshot isolation, batch_event_sql algorithm, dual-filter optimization).
## Stack

- Pure SQL + PL/pgSQL (no extensions, no `.control` file)
- Anti-extension design: `\i pgque.sql` to install
- Anti-extension design: `\i logres.sql` to install
- Works on RDS, Aurora, Cloud SQL, AlloyDB, Supabase, Neon, Crunchy Bridge
- Optional pg_cron for automated ticker and maintenance
- PostgreSQL 14+ required (uses `pg_snapshot`, `xid8`)
Expand All @@ -41,9 +40,9 @@ Follow the shared rules at https://gitlab.com/postgres-ai/rules/-/tree/main/rule

- Lowercase SQL keywords: `select`, `create function`, not `SELECT`, `CREATE FUNCTION`
- `snake_case` for all identifiers
- Schema-qualify all internal references: `pgque.queue`, not just `queue`
- Schema-qualify all internal references: `logres.queue`, not just `queue`
- All `SECURITY DEFINER` functions MUST include
`SET search_path = pgque, pg_catalog`
`SET search_path = logres, pg_catalog`
- Use `xid8` for transaction ID columns, `pg_snapshot` for snapshot columns
- Use modern PG14+ function names: `pg_current_xact_id()` not `txid_current()`

Expand Down Expand Up @@ -74,17 +73,17 @@ set -Eeuo pipefail
## File Organization

```
pgque/
logres/
pgq/ -- git submodule (github.com/pgq/pgq, pinned tag)
build/
transform.sh -- mechanical rename + modernization script
blueprints/ -- specs, design docs, brainstorms
SPECx.md -- pgque specification (the main spec)
SPECx.md -- logres specification (the main spec)
SPEC.md -- PgQ internals reference (from pgq repo)
PHASES.md -- what ships in v0.1 vs experimental
sql/ -- source SQL files
pgque.sql -- single-file install (built from sources)
pgque-unpgque.sql
logres.sql -- single-file install (built from sources)
logres_uninstall.sql
tests/ -- regression tests (sql/ + expected/)
docs/ -- user-facing documentation (flat layout)
README.md -- index of the docs directory
Expand All @@ -93,12 +92,12 @@ pgque/
examples.md -- short patterns (fan-out, exactly-once, etc.)
benchmarks.md -- throughput numbers + methodology
pgq-concepts.md -- contributor glossary (batch, tick, rotation)
pgq-history.md -- short timeline from Skype to PgQue
pgq-history.md -- short timeline from Skype to logres
clients/ -- client libraries
python/ -- pgque-py
go/ -- pgque-go
typescript/ -- pgque-ts
cli/ -- pgque CLI (Go)
python/ -- logres-py
go/ -- logres-go
typescript/ -- logres-ts
cli/ -- logres CLI (Go)
```

## Key Design Rules
Expand All @@ -107,19 +106,19 @@ pgque/
2. **The PgQ engine is sacred.** Batch/tick/rotation/consumer tracking logic
is inherited from PgQ and must not be modified without deep understanding.
3. **Modern API functions must reduce cleanly to PgQ primitives.**
If `pgque.send()` cannot be explained as "calls `pgque.insert_event()` with
If `logres.send()` cannot be explained as "calls `logres.insert_event()` with
these args," it is too complex.
4. **No subtransactions in hot paths.** Avoid `BEGIN ... EXCEPTION WHEN ... END`
in ticker, event insertion, and trigger functions.
5. **Test against PG 14, 15, 16, 17, 18.** CI must cover all supported versions.
6. **Red/green TDD for all new code.** Write the failing test first, then
the implementation. Applies to pgque-api, observability, client libraries,
CLI. Does NOT apply to pgque-core repackaging (PgQ already has tests).
the implementation. Applies to logres-api, observability, client libraries,
CLI. Does NOT apply to logres-core repackaging (PgQ already has tests).
See SPECx.md section 13.2.

## Copyright

Copyright 2026 Nikolay Samokhvalov. Apache-2.0 license.

PgQue includes code derived from PgQ (ISC license, Marko Kreen / Skype Technologies OU).
logres includes code derived from PgQ (ISC license, Marko Kreen / Skype Technologies OU).
Always preserve the PgQ copyright notice in source headers.
2 changes: 1 addition & 1 deletion NOTICE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
PgQue -- PgQ Universal Edition
logres -- PgQ Universal Edition
Copyright 2026 Nikolay Samokhvalov

This product includes code derived from PgQ (https://github.com/pgq/pgq),
Expand Down
Loading
Loading