Metadata-Version: 2.4
Name: csrd-repository
Version: 0.5.30
Summary: Base repository and database adapter abstractions
Project-URL: Repository, https://github.com/csrd-api/fastapi-common
Project-URL: Documentation, https://github.com/csrd-api/fastapi-common/tree/main/packages/repository
Project-URL: Changelog, https://github.com/csrd-api/fastapi-common/blob/main/CHANGELOG.md
License: MIT
Requires-Python: >=3.12
Requires-Dist: aiosqlite<1,>=0.21
Requires-Dist: csrd-models
Provides-Extra: sql
Requires-Dist: sqlalchemy<3,>=2.0; extra == 'sql'
Description-Content-Type: text/markdown

 # csrd-repository

Base repository and database adapter abstractions for FastAPI microservices.

**Package**: `csrd.repository` · **Import**: `from csrd.repository import BaseRepository, SQLiteAdapter`

## What's included

- `BaseRepository` — abstract repository with model parsing (requires an adapter)
- `ABCDatabaseAdapter` / `DBProtocol` — async database adapter abstraction with lifecycle and explicit transactions
- `SQLiteAdapter` — async SQLite implementation via aiosqlite (persistent connection, atomic upsert)
- `ExecuteResult` — immutable snapshot of query metadata (replaces raw cursor return)
- Optional `sqlalchemy` integration for query building (`pip install csrd-repository[sql]`)

## Installation

```bash
uv pip install "csrd-repository @ git+ssh://git@github.com/csrd-api/fastapi-common.git#subdirectory=packages/repository"
```

## Dependencies

- `csrd-models` (Tier 2)

## Transactions

All adapters expose an explicit unit-of-work context:

```python
async with adapter.transaction() as tx:
    users = user_repository.with_adapter(tx)
    credentials = credential_repository.with_adapter(tx)
    user = await users.insert("users", user_values)
    await credentials.insert("credentials", {"user_id": user["id"], **credential_values})
```

The yielded adapter uses one physical connection. Normal exit commits;
exceptions and cancellation roll back. Nested `transaction()` calls are
rejected with `RuntimeError`, and a transaction-bound adapter raises
`RuntimeError` if reused after context exit.

Locking remains database-specific: PostgreSQL and MariaDB support their native
row-lock syntax (for example `SELECT ... FOR UPDATE`); SQLite serializes
operations on its single connection and does not support `FOR UPDATE`.
