From 460a97c0fc08f312b182cd1c1cc36138ef969e9d Mon Sep 17 00:00:00 2001 From: Chemaclass Date: Wed, 3 Jun 2026 07:21:57 +0200 Subject: [PATCH] feat(pdo): add next-rowset statement wrapper Related to #17 --- CHANGELOG.md | 1 + README.md | 1 + src/pdo/statement.phel | 6 +++++- tests/pdo_test.phel | 10 ++++++++++ 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62a416a..e5e0bc8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `pdo/set-fetch-mode` - wrap `PDOStatement::setFetchMode`; sets the statement's default fetch mode, with mode-specific extra args ([#13]). - `pdo/column-meta` - wrap `PDOStatement::getColumnMeta`; returns a 0-indexed column's metadata as a map, or `nil` when unavailable ([#15]). - `pdo/statement-seq` - expose a statement's rows as a lazy seq of maps (the Phel-idiomatic take on `PDOStatement::getIterator`), so callers can `map`/`reduce`/`take` without materialising the whole result set ([#16]). +- `pdo/next-rowset` - wrap `PDOStatement::nextRowset`; advances a multi-rowset statement (e.g. stored procedures on MySQL/Postgres) ([#17]). ### Changed diff --git a/README.md b/README.md index a1b34ee..b7e15a4 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,7 @@ Returned by `pdo/query` and `pdo/prepare`. | `column-meta` | `(column-meta stmt column)` | Metadata map for a 0-indexed column, or `nil` if unavailable. | | `close-cursor` | `(close-cursor stmt)` | Free the cursor so the statement can be re-executed. Returns the statement. | | `set-fetch-mode` | `(set-fetch-mode stmt mode & args)` | Set the statement's default fetch mode (extra args match the mode). Returns the statement. | +| `next-rowset` | `(next-rowset stmt)` | Advance to the next rowset of a multi-rowset statement; `false` when none remain. | | `debug-dump-params` | `(debug-dump-params stmt)` | Dump prepared statement info as a string. | > [!NOTE] diff --git a/src/pdo/statement.phel b/src/pdo/statement.phel index 4b2dabc..f11166b 100644 --- a/src/pdo/statement.phel +++ b/src/pdo/statement.phel @@ -50,6 +50,11 @@ (php/-> (stmt :stmt) (closeCursor)) stmt) +(defn ^bool next-rowset + "Advances to the next rowset of a multi-rowset statement; false when none remain" + [stmt] + (php/-> (stmt :stmt) (nextRowset))) + (defn set-fetch-mode "Sets the default fetch mode for the statement. Extra args match the mode (e.g. column index for FETCH_COLUMN, class name + ctor args for FETCH_CLASS)" @@ -101,4 +106,3 @@ ;; Not implemented yet: ;; ;; PDOStatement::bindColumn — Bind a column to a PHP variable -;; PDOStatement::nextRowset — Advances to the next rowset in a multi-rowset statement handle diff --git a/tests/pdo_test.phel b/tests/pdo_test.phel index 80deacd..22e279b 100644 --- a/tests/pdo_test.phel +++ b/tests/pdo_test.phel @@ -219,6 +219,16 @@ stmt (pdo/execute stmt)] (is (= [1 "phel"] (php->phel (php/-> (stmt :stmt) (fetch))))))) +(deftest next-rowset-rejected-on-sqlite + (seed-t1 *conn*) + ;; SQLite has no multi-rowset support; depending on the driver build this is + ;; either a false return or a PDOException - both prove the call reached nextRowset. + (let [stmt (pdo/query *conn* "select * from t1") + outcome (try + (pdo/next-rowset stmt) + (catch \PDOException _e :unsupported))] + (is (or (= false outcome) (= :unsupported outcome))))) + (deftest set-attribute-dispatches-to-statement (seed-t1 *conn*) ;; SQLite rejects statement attributes; depending on the driver build this is