Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `pdo/close-cursor` - wrap `PDOStatement::closeCursor`; frees the cursor so the statement can be re-executed ([#9]).
- `pdo/fetch-object` - wrap `PDOStatement::fetchObject`; returns the next row as an object (`stdClass` or a named class), or `nil` when exhausted ([#11]).

### Changed

- `pdo/get-attribute` / `pdo/set-attribute` now dispatch on the handle: pass a connection (as before) or a statement to reach `PDOStatement::getAttribute` / `setAttribute` ([#12]).

## [0.1.0] - 2026-05-13

### Changed
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ All functions live in the `phel.pdo` namespace.
| `last-insert-id` | `(last-insert-id conn)` | ID of the last inserted row. |
| `begin` / `commit` / `rollback` | `(begin conn)` … | Transaction control. |
| `in-transaction` | `(in-transaction conn)` | `true` if a transaction is active. |
| `get-attribute` / `set-attribute` | `(get-attribute conn attr)` / `(set-attribute conn attr value)` | PDO attribute access. |
| `get-attribute` / `set-attribute` | `(get-attribute handle attr)` / `(set-attribute handle attr value)` | PDO attribute access; `handle` is a connection or a statement. |
| `get-available-drivers` | `(get-available-drivers conn)` | Vector of installed PDO drivers. |
| `error-code` | `(error-code conn)` | SQLSTATE of the last operation. |
| `error-info` | `(error-info conn)` | `[sqlstate driver-code driver-message]`. |
Expand Down
19 changes: 13 additions & 6 deletions src/pdo.phel
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,22 @@

(defstruct connection [pdo])

(declare statement?)

(defn- attr-target
"The PDO handle behind a connection or statement struct."
[handle]
(if (statement? handle) (handle :stmt) (handle :pdo)))

(defn ^bool set-attribute
"Set an attribute"
[conn attribute value]
(php/-> (conn :pdo) (setAttribute attribute value)))
"Set an attribute on a connection or statement"
[handle attribute value]
(php/-> (attr-target handle) (setAttribute attribute value)))

(defn get-attribute
"Retrieve a database connection attribute"
[conn attribute]
(php/-> (conn :pdo) (getAttribute attribute)))
"Retrieve an attribute from a connection or statement"
[handle attribute]
(php/-> (attr-target handle) (getAttribute attribute)))

(defn connect
"Connect database and return connection object.
Expand Down
2 changes: 0 additions & 2 deletions src/pdo/statement.phel
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,7 @@
;; PDOStatement::bindColumn — Bind a column to a PHP variable
;; PDOStatement::errorCode — Fetch the SQLSTATE associated with the last operation on the statement handle
;; PDOStatement::errorInfo — Fetch extended error information associated with the last operation on the statement handle
;; PDOStatement::getAttribute — Retrieve a statement attribute
;; PDOStatement::getColumnMeta — Returns metadata for a column in a result set
;; PDOStatement::getIterator — Gets result set iterator
;; PDOStatement::nextRowset — Advances to the next rowset in a multi-rowset statement handle
;; PDOStatement::setAttribute — Set a statement attribute
;; PDOStatement::setFetchMode — Set the default fetch mode for this statement
22 changes: 22 additions & 0 deletions tests/pdo_test.phel
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,28 @@
stmt (pdo/execute stmt {:id 1})]
(is (= "phel" (pdo/fetch-column stmt)))))

(deftest set-attribute-dispatches-to-statement
(seed-t1 *conn*)
;; SQLite rejects statement attributes; depending on the driver build this is
;; either a false return or a PDOException - both prove the call reached the statement.
(let [stmt (pdo/prepare *conn* "select * from t1")
outcome (try
(pdo/set-attribute stmt \PDO/ATTR_CURSOR \PDO/CURSOR_FWDONLY)
(catch \PDOException _e :unsupported))]
(is (or (= false outcome) (= :unsupported outcome)))))

(deftest get-attribute-dispatches-to-statement
(seed-t1 *conn*)
(testing "connection branch still returns a value"
(is (= \PDO/ERRMODE_EXCEPTION (pdo/get-attribute *conn* \PDO/ATTR_ERRMODE))))
(testing "statement branch routes to the PDOStatement (SQLite reports unsupported)"
(let [stmt (pdo/prepare *conn* "select * from t1")
threw (try
(pdo/get-attribute stmt \PDO/ATTR_CURSOR)
false
(catch \PDOException _e true))]
(is (= true threw)))))

(deftest debug-dump-params-emits-sql-header
(seed-t1 *conn*)
(let [stmt (pdo/prepare *conn* "select * from t1 where name = :name")
Expand Down
Loading