PHPackages                             nusadb/nusadb - 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. nusadb/nusadb

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

nusadb/nusadb
=============

Pure-PHP client for NusaDB (Nusa Wire Protocol) with a PDO-style API

v0.1.0(1mo ago)02↓75%Apache-2.0PHPPHP &gt;=7.2CI passing

Since Jul 13Pushed 1mo agoCompare

[ Source](https://github.com/nusadb/php)[ Packagist](https://packagist.org/packages/nusadb/nusadb)[ Docs](https://github.com/nusadb/php)[ RSS](/packages/nusadb-nusadb/feed)WikiDiscussions master Synced 1w ago

READMEChangelog (1)DependenciesVersions (2)Used By (0)

nusadb — PHP driver for NusaDB
==============================

[](#nusadb--php-driver-for-nusadb)

A pure-PHP client (no extension to compile) that speaks the [Nusa Wire Protocol](../../docs/wire-protocol.md) (`PROTOCOL_VERSION 1.1`) directly over a socket, exposing a familiar **PDO-style** API. `Statement::getColumnMeta($i)`reports each column's NusaDB type under `native_type` (protocol 1.1). SCRAM-SHA-256 uses PHP's built-in `hash`/`hash_hmac`/`hash_pbkdf2`. Requires PHP 7.2+.

> A *real* PDO driver is a C extension; this package implements the same connection / statement shape in pure PHP over the Nusa protocol, so application code reads like PDO without needing a compiled extension.

Install
-------

[](#install)

Via Composer (PSR-4 autoloading):

```
composer require nusadb/nusadb
```

Or without Composer, include the bundled autoloader:

```
require '/path/to/drivers/php/autoload.php';
```

Usage
-----

[](#usage)

```
use NusaDB\Connection;
use NusaDB\Statement;

$conn = new Connection('nusadb:host=127.0.0.1;port=5678;dbname=nusadb', 'nusa-root', 'nusa-root');

$conn->exec('CREATE TABLE t (id INT NOT NULL, name TEXT)');

$ins = $conn->prepare('INSERT INTO t VALUES ($1, $2)');
$ins->execute([1, 'alice']);

$sel = $conn->prepare('SELECT id, name FROM t WHERE id = $1');
$sel->execute([1]);
foreach ($sel->fetchAll(Statement::FETCH_ASSOC) as $row) {
    echo $row['id'], ' ', $row['name'], "\n";
}

$conn->close();
```

### Value types

[](#value-types)

Each cell decodes to the natural PHP type for its protocol 1.1 type tag: `BOOL` → `bool`, `INT` → `int`, `FLOAT` → `float`, `JSON` → the decoded value, `ARRAY` → `array` (elements stay strings — the wire array tag carries no element type), `BYTEA` → a raw byte string. `NUMERIC`, `DATE`, `TIMESTAMP`, `TIME`, `UUID`, `INTERVAL`, and `TEXT` stay strings (the PDO convention — PHP has no lossless native type for them). A value that does not parse as its tag falls back to the raw string, so an unexpected wire form never raises.

### DSN &amp; parameters

[](#dsn--parameters)

DSN: `nusadb:host=127.0.0.1;port=5678;dbname=nusadb`. The user and password are the 2nd and 3rd constructor arguments. Placeholders are positional `$1`, `$2`, …; pass the bound values to `execute([...])` (1-based order). `null` is SQL `NULL`.

### Batch (bulk insert/update)

[](#batch-bulk-insertupdate)

`$conn->executeMany($sql, $paramSets)` runs one statement once per parameter set, reusing a single prepared statement, and returns an array of per-set affected-row counts. The wire protocol has no batch pipeline, so this is N round-trips, not one.

```
$counts = $conn->executeMany('INSERT INTO t VALUES ($1, $2)', [[1, 'a'], [2, 'b'], [3, 'c']]);
```

### Bulk load / export (`COPY`)

[](#bulk-load--export-copy)

For high-throughput load/export, `copyIn` / `copyOut` drive the `COPY` sub-protocol — one round-trip for the whole dataset. Move bytes in the server's text format (tab-delimited fields, `\N` for SQL `NULL`, one row per line); you write the `COPY` statement with any `WITH (...)` options.

```
// Bulk load from a string or a stream resource.
$loaded = $conn->copyIn('COPY t (id, name) FROM STDIN', "1\talice\n2\t\\N\n");

// Bulk export into a stream resource.
$sink = fopen('php://temp', 'r+');
$exported = $conn->copyOut('COPY t TO STDOUT', $sink);
```

A `COPY` the server refuses (bad SQL, an RLS-protected table) throws; the connection stays usable.

### Authentication

[](#authentication)

For a server started with `--auth-user USER:PASSWORD`, pass the password as the third constructor argument; the driver runs SCRAM-SHA-256 and verifies the server signature (mutual auth, `hash_equals`).

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

[](#transactions)

Statements autocommit unless wrapped in an explicit transaction. `beginTransaction()`, `commit()`, and `rollBack()` issue `BEGIN`, `COMMIT`, and `ROLLBACK` over the connection; `inTransaction()` reports whether one is open. Calling `commit()`/`rollBack()` with no active transaction, or a nested `beginTransaction()`, throws `NusaException` (PDO-style).

```
$conn = new NusaDB\Connection("nusadb:host=127.0.0.1;port=5678;dbname=nusadb");
$conn->beginTransaction();
$conn->exec("INSERT INTO t VALUES (1)");
$conn->commit(); // or $conn->rollBack();
```

Inside a transaction, `savepoint($name)` marks a point you can later undo to with `rollbackToSavepoint($name)` (the transaction stays open) or forget with `releaseSavepoint($name)`.

Notifications (LISTEN/NOTIFY)
-----------------------------

[](#notifications-listennotify)

`listen($channel)` subscribes the connection; a `notify($channel, $payload)` from any connection on the same database is then delivered asynchronously. `pollNotification($timeoutMillis)` waits for the next one (`0` polls without blocking), or `getNotifications()` drains those buffered during other queries:

```
$conn->listen('orders');
// ... elsewhere: $conn->notify('orders', '42');
$note = $conn->pollNotification(5000); // -> NusaDB\Notification, or null on timeout
echo $note->channel, ' ', $note->payload;
$conn->unlisten('orders');
```

License
-------

[](#license)

Apache-2.0.

###  Health Score

30

—

LowBetter than 61% of packages

Maintenance90

Actively maintained with recent releases

Popularity2

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity18

Early-stage or recently created project

 Bus Factor1

Top contributor holds 50% of commits — single point of failure

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

Unknown

Total

1

Last Release

49d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/3a6cedcf61a24381dcfa6611c6a6276049547bfa12c00f04f6b97af59c1daa65?d=identicon)[nusadb](/maintainers/nusadb)

---

Top Contributors

[![nusadb](https://avatars.githubusercontent.com/u/302580107?v=4)](https://github.com/nusadb "nusadb (3 commits)")[![rafi-latip](https://avatars.githubusercontent.com/u/172180445?v=4)](https://github.com/rafi-latip "rafi-latip (3 commits)")

---

Tags

databasesqlpdodrivernusadb

### Embed Badge

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

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

###  Alternatives

[doctrine/dbal

Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.

9.9k624.3M7.6k](/packages/doctrine-dbal)[paragonie/easydb

Easy-to-use database abstraction

743286.1k24](/packages/paragonie-easydb)[faapz/pdo

Just another PDO database library

322143.0k5](/packages/faapz-pdo)[ntanduy/cloudflare-d1-database

Cloudflare D1 database driver for Laravel — full Eloquent &amp; Query Builder support.

288.6k](/packages/ntanduy-cloudflare-d1-database)

PHPackages © 2026

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