PHPackages                             hydrakit/database - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. hydrakit/database

ActiveLibrary[Database &amp; ORM](/categories/database)

hydrakit/database
=================

Database library for Hydra PHP framework

v0.2.0(yesterday)016↑25%2MITPHP &gt;=8.2

Since Jul 6Compare

[ Source](https://github.com/hydra-foundation/database)[ Packagist](https://packagist.org/packages/hydrakit/database)[ RSS](/packages/hydrakit-database/feed)WikiDiscussions Synced today

READMEChangelogDependencies (1)Versions (4)Used By (2)

Hydra Database
==============

[](#hydra-database)

A thin data-access seam over PDO and a raw-SQL migration runner. No ORM, no query builder, no fluent anything — repositories write their own SQL and pass bound parameters. This package ships the *mechanism*; the app owns its repositories, entities, and migration files.

The connection seam
-------------------

[](#the-connection-seam)

`Contracts\ConnectionInterface` is a prepared-statement-only surface: `select`, `selectOne`, `execute`, `lastInsertId`. Repositories depend on the interface, never on PDO, so the engine is swappable — the same move `Hydra\View\Contracts\ViewInterface` makes for templating.

```
use Hydra\Database\PdoConnection;

$db = new PdoConnection($pdo); // $pdo built by the app's service provider
$rows = $db->select('SELECT * FROM posts WHERE published = ?', [1]);
$one  = $db->selectOne('SELECT * FROM users WHERE email = ?', [$email]);
$n    = $db->execute('UPDATE users SET name = ? WHERE id = ?', [$name, $id]);
```

`PdoConnection` prepares every statement, so all values reach the driver as bound parameters — there is no string-built SQL path. The PDO handle itself is constructed by the app (with its chosen error mode, fetch mode, prepare settings), which keeps this class driver-agnostic and trivially testable against in-memory sqlite.

`lastInsertId()` returns a **string** — PDO's native surface — so UUID/string primary keys and 64-bit ids beyond `PHP_INT_MAX` on 32-bit builds pass through uncorrupted. If your schema uses integer PKs, cast at the call site, where that schema assumption actually lives:

```
$db->execute('INSERT INTO users (username) VALUES (?)', [$username]);
$id = (int) $db->lastInsertId(); // this table's PK is an integer — your call
```

Transactions
------------

[](#transactions)

`transaction(callable): mixed` runs the callable inside a transaction and returns its value. A clean return commits; any throwable rolls back and propagates unchanged, so callers never see a half-applied write:

```
$id = $db->transaction(function (ConnectionInterface $db) use ($input) {
    $db->execute('INSERT INTO orders (user_id) VALUES (?)', [$input->int('user_id')]);
    $orderId = $db->lastInsertId();
    $db->execute('INSERT INTO order_events (order_id, event) VALUES (?, ?)', [$orderId, 'created']);

    return $orderId;
});
```

Calls are re-entrant: a `transaction()` nested inside another joins the outer transaction rather than opening a second (PDO has no true nesting; this seam ships no savepoints). The outermost call owns begin/commit/rollback, and a throw anywhere inside rolls the whole thing back — so repositories that each wrap their own writes compose atomically.

One honest sharp edge: on MySQL/MariaDB, DDL statements (`CREATE`/`ALTER`/ `DROP`) trigger an implicit commit, so DDL inside `transaction()` is not rolled back — the same caveat the migration runner documents.

Migrations
----------

[](#migrations)

`MigrationRunner` applies plain `.sql` files in lexical order and records each in a `migrations` table, so re-runs are no-ops. Forward-only by design — there are no down migrations (rollback in production is mostly fiction; in dev you `fresh()` from scratch).

```
$runner = new MigrationRunner($pdo, __DIR__ . '/database/migrations', $driver);
$runner->run();     // apply pending, return applied filenames
$runner->status();  // [{filename, applied}, …]
$runner->fresh();   // drop everything, re-apply (destructive — guard it)
```

It takes the raw PDO rather than the connection seam on purpose: DDL is multi-statement and unparameterised, so it runs through `PDO::exec`, outside the prepared-only surface repositories use. The `$driver` argument switches the drop-all dialect (MariaDB `information_schema` vs sqlite `sqlite_master`), so `fresh()` stays exercisable under the sqlite test driver while production targets MariaDB.

> **Caveat:** MariaDB has no transactional DDL — a migration that fails halfway leaves partial state. Keep each migration to one logical change.

What's app-owned
----------------

[](#whats-app-owned)

The PDO construction, the migration `.sql` files, repositories and entities all live in the app. This package is only the connection seam and the runner — the two pieces that are identical across every app and were previously copied.

###  Health Score

39

—

LowBetter than 84% of packages

Maintenance100

Actively maintained with recent releases

Popularity8

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity38

Early-stage or recently created project

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1 days

Total

3

Last Release

1d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/a947272da0bf1d7d6326b4fbf6ddb8049977cbdbe333d0d1282dbb6f5927dfdf?d=identicon)[whleucka](/maintainers/whleucka)

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/hydrakit-database/health.svg)

```
[![Health](https://phpackages.com/badges/hydrakit-database/health.svg)](https://phpackages.com/packages/hydrakit-database)
```

###  Alternatives

[jdorn/sql-formatter

a PHP SQL highlighting library

3.9k117.2M118](/packages/jdorn-sql-formatter)[propel/propel1

Propel is an open-source Object-Relational Mapping (ORM) for PHP5.

8351.6M87](/packages/propel-propel1)[pgvector/pgvector

pgvector support for PHP

198741.5k13](/packages/pgvector-pgvector)[jfelder/oracledb

Oracle DB driver for Laravel

11518.4k](/packages/jfelder-oracledb)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
