v0.3.0 — types and data
Every LadybugDB type this client can read now has a PHP shape, and there is a bulk path that does not plan a query per row.
Supports liblbug 0.19.x.
Paths are typed
RECURSIVE_REL used to arrive as liblbug's own text. It turns out to be a STRUCT of two lists, and liblbug's struct accessors do read it — so the members are the same Node and Rel objects every other query produces:
$path = $connection->query('MATCH p = (a:Person)-[:Knows*1..3]->(b:Person) RETURN p')->fetchOne();
$path->nodes; // list<Node>, in traversal order
$path->rels; // list<Rel>
$path->length(); // hops
$path->start(); $path->end();Deliberately neither iterable nor countable: both would have to choose between nodes and relationships, and each reading is defensible.
Bulk loading
$connection->copyInto('Person', [
['name' => 'Ada', 'age' => 36],
['name' => 'Alan', 'age' => 41],
]); // → 2
$connection->copyInto('Knows', [['Ada', 'Alan', 2001]]); // REL: from, to, then propertiesRows spool to a temporary CSV and go through liblbug's COPY FROM. Associative or positional, any iterable — a generator is never materialised. Table and column names are validated rather than escaped, because a Cypher identifier has no quoting form that makes arbitrary input safe.
An empty string is refused. liblbug reads an empty CSV field as NULL and offers no sentinel to separate them, so copying '' would silently store NULL. Pass null, or insert that row with CREATE.
Extensions
json, fts and vector work through plain query() — INSTALL and LOAD are Cypher. Two things needed fixing:
DataType::Jsonmaps type id 60, which lbug.h does not declare (the core header stops atUUID = 59). Reading aJSONcolumn used to throw "liblbug is newer than this client", andcolumnTypes()threw a rawValueError.- An unrecognised type id now degrades to
DataType::Unknownplus liblbug's rendering. Extensions can introduce types at any time, and one unmapped column should not fail the query.
Vector search works end to end. Embedding columns are FLOAT[n] — an ARRAY — so they arrive as text; cast(col AS FLOAT[]) gives floats.
A Linux test environment
make docker-test runs the whole suite, both connectors, on Linux (DOCKER_PHP=8.4 picks a version). It caught an overstatement in the previous release notes within minutes of existing.
Documented liblbug limitations
ARRAYandUNIONarrive as liblbug's own text: its list and struct accessors reject both types. The values are intact — cast to aLISTin Cypher for structure.INSTALLsegfaults on GitHub Actions' Linux runners. Not on Debian containers, either architecture, including on a crashing runner; not under gdb; and every network failure gives a clean exception. A core dump places it inside liblbug's own C++ runtime.
Full notes in CHANGELOG.md.