Commit Graph
11 Commits
Author SHA1 Message Date
dsql 71993fea1b docs: add __aenter__/__aexit__ one-liner docstrings for twin parity with redis
Signed-off-by: disqualifier <dev@disqualifier.me>
2026-07-06 02:55:58 -04:00
dsql e4c61cf6c3 fix: log-and-reraise create_pool failures; lock close() against a racing connect()
connect() built the pool with `await asyncpg.create_pool(...)` outside the
try that wraps SELECT-1 validation - with the default min_size=1 the pool
connects eagerly, so a bad host/auth propagated with no log.exception line,
breaking the documented "every method logs then re-raises" contract.
create_pool() now sits inside the same try/log/re-raise as validation, and
either failure point tears down a partially-built pool before re-raising.

close() didn't take _connect_lock while connect() did, so a close() racing
an in-flight connect() would see _pool is None and no-op as success while
connect() went on to install a live pool - a shutdown handler racing a
reconnect could "close" the instance while real connections stayed open.
close() now takes the same lock via a shared _close_locked() helper.

Signed-off-by: disqualifier <dev@disqualifier.me>
2026-07-03 19:11:52 -04:00
dsql d619d4ca55 refactor: derive __version__ from package metadata (single source)
Signed-off-by: disqualifier <dev@disqualifier.me>
2026-07-03 17:00:59 -04:00
dsql f07a8da5a4 docs: compress prose/module docstrings, em-dash->hyphen (de-bloat wave 1)
Signed-off-by: disqualifier <dev@disqualifier.me>
2026-07-03 00:16:11 -04:00
dsql f90c18ed64 fix: close() nulls pool + connect() lock guards against concurrent races (psql-7, psql-8)
- close() sets self._pool = None (in a finally, even on driver-error close) so a closed
  instance reports not-connected instead of masquerading as still-connected against a
  dead pool (the pool property now raises RuntimeError post-close as intended).
- connect() is now guarded by an internal asyncio.Lock: concurrent connect() calls
  serialize instead of each racing to build + orphan its own live pool. Twin fix with
  mysql at the same Layer-1 signature level.
- docstrings tightened (module header lifecycle/dsn notes, __init__ dsn note) with zero
  behavior change; re-verified against a real embedded postgres.

verified against pixeltable-pgserver (test-only): 8 concurrent connect() calls now leave
0 orphaned pools + exactly 1 live pool (old: 7 orphaned, 8 live simultaneously); close()
now flips the connected-check to False (old: stayed True against a dead pool). full
layer-1/layer-2/transaction/concurrency regression suite still green. fresh-venv install
confirms runtime purity (asyncpg only, no pixeltable-pgserver). bump v0.1.4 -> v0.1.5

Signed-off-by: disqualifier <dev@disqualifier.me>
2026-07-02 23:25:52 -04:00
dsql 1ae280e5c3 fix: host/port defaults no longer shadow a dsn's embedded host/port (psql-5)
Signed-off-by: disqualifier <dev@disqualifier.me>
2026-07-02 17:30:10 -04:00
dsql c3205f0614 fix: _where() renders None conditions as IS NULL instead of = NULL
col = $n bound to NULL never matches in sql, so get/get_one/exists/delete
silently missed every row filtered on a None value despite insert() writing
NULL fine. Kept in lockstep with the mysql lib's identical fix.

Signed-off-by: disqualifier <dev@disqualifier.me>
2026-07-02 16:44:27 -04:00
dsql 4e75a800f1 fix: connect() never orphans a pool (psql-3)
connect() now closes an existing pool before re-connecting (no orphan on double-connect),
and tears down the freshly-built pool if the SELECT-1 validation fails before re-raising
(no leaked pool on a failed connect). verified vs embedded postgres. bump v0.1.1 -> v0.1.2

Signed-off-by: disqualifier <dev@disqualifier.me>
2026-07-01 00:28:27 -04:00
dsql 426fad10ed fix: transaction() releases the pooled connection when start() fails (psql-1)
_Transaction.__aenter__ acquired a connection then called tx.start(); if start() raised
(stale pooled conn after failover/idle-timeout — a fail-loud path), __aexit__ never ran so
the connection leaked, draining the pool until transaction() deadlocked on acquire(). now
release-on-failure. verified: 6 forced start-failures (2x pool) no longer exhaust the pool.
bump v0.1.0 -> v0.1.1

Signed-off-by: disqualifier <dev@disqualifier.me>
2026-06-30 21:04:43 -04:00
dsql f12295ce6a add package: pyproject + src (layer-1 verbs + raw layer-2, fail-loud, plain-dict rows)
Signed-off-by: disqualifier <dev@disqualifier.me>
2026-06-30 05:48:00 -04:00
dsql cc3d6bb585 init: async postgres wrapper over asyncpg (two-layer API, class PsqlDB)
Signed-off-by: disqualifier <dev@disqualifier.me>
2026-06-30 05:48:00 -04:00