diff --git a/oci_statement.c b/oci_statement.c index 5f8f062..0522b38 100644 --- a/oci_statement.c +++ b/oci_statement.c @@ -797,6 +797,19 @@ static int oci_stmt_get_col(pdo_stmt_t *stmt, int colno, zval *result, enum pdo_ if (C->dtype == SQLT_BLOB || C->dtype == SQLT_CLOB) { if (C->data) { + OCILobLocator *new_lob; + boolean isTempLOB; + OCILobIsTemporary(S->H->env, S->err, (OCILobLocator*)C->data, &isTempLOB); + if (!isTempLOB && + OCIDescriptorAlloc(S->H->env, (dvoid**)&new_lob, OCI_DTYPE_LOB, 0, NULL) == OCI_SUCCESS) { + if (OCILobLocatorAssign(S->H->svc, S->err, (OCILobLocator*)C->data, &new_lob) == OCI_SUCCESS) { + php_stream *stream = oci_create_lob_stream(stmt, new_lob); + OCILobOpen(S->H->svc, S->err, new_lob, OCI_LOB_READONLY); + php_stream_to_zval(stream, result); + return 1; + } + OCIDescriptorFree(new_lob, OCI_DTYPE_LOB); + } php_stream *stream = oci_create_lob_stream(stmt, (OCILobLocator*)C->data); OCILobOpen(S->H->svc, S->err, (OCILobLocator*)C->data, OCI_LOB_READONLY); php_stream_to_zval(stream, result); diff --git a/tests/bug57702.phpt b/tests/bug57702.phpt index f2d9c3c..89e07c1 100644 --- a/tests/bug57702.phpt +++ b/tests/bug57702.phpt @@ -184,8 +184,8 @@ string(11) "row 2 col 1" string(11) "row 2 col 2" Fifth Query -string(11) "row 2 col 1" -string(11) "row 2 col 2" +string(11) "row 1 col 1" +string(11) "row 1 col 2" string(11) "row 2 col 1" string(11) "row 2 col 2" diff --git a/tests/pdo_oci_blob.phpt b/tests/pdo_oci_blob.phpt new file mode 100644 index 0000000..ca843c0 --- /dev/null +++ b/tests/pdo_oci_blob.phpt @@ -0,0 +1,96 @@ +--TEST-- +PDO_OCI: BLOB insert and fetch test +--EXTENSIONS-- +pdo +pdo_oci +--SKIPIF-- + +--FILE-- +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); +$db->setAttribute(PDO::ATTR_AUTOCOMMIT, false); + +try { + $db->exec("DROP TABLE test_blob"); +} catch (PDOException $e) { + // Table may not exist, ignore +} +// Create table +$db->exec("CREATE TABLE test_blob (id NUMBER, picture BLOB)"); + +for ($id = 1; $id < 3; $id++) { + $db->beginTransaction(); + + // Sample image data (replace with actual paths or data) + // For testing, we'll use dummy data + $imageData = file_get_contents(dirname(__FILE__) .'/test' . $id . '.gif'); + + // Insert and bind output LOB + $lob = null; + $stmt = $db->prepare("INSERT INTO test_blob (id, picture) VALUES (:id, EMPTY_BLOB()) RETURNING picture INTO :picture"); + $stmt->bindParam(':id', $id, PDO::PARAM_INT); + $stmt->bindParam(':picture', $lob, PDO::PARAM_LOB); + $stmt->execute(); + + if (is_resource($lob)) { + fwrite($lob, $imageData); + fclose($lob); + } + + $db->commit(); +} + +// Select and fetch BLOB using fetchAll +echo "Using fetchAll:\n"; +$stm = $db->query("SELECT picture FROM test_blob"); +foreach ($stm->fetchAll(PDO::FETCH_NUM) as $row) { + if (is_resource($row[0])) { + rewind($row[0]); + $blob = stream_get_contents($row[0]); + } else { + $blob = $row[0]; + } + echo "Blob length: " . strlen($blob) . "\n"; +} + +echo "-----------------------------------\n"; + +// Select and fetch BLOB using fetch in loop +echo "Using fetch in loop:\n"; +$stmt = $db->query("SELECT picture FROM test_blob"); +while ($row = $stmt->fetch(PDO::FETCH_NUM)) { + if (is_resource($row[0])) { + rewind($row[0]); + $blob = stream_get_contents($row[0]); + } else { + $blob = $row[0]; + } + echo "Blob length: " . strlen($blob) . "\n"; +} +?> +--CLEAN-- +exec("begin + execute immediate 'drop table test_blob'; + exception when others then + if sqlcode <> -942 then + raise; + end if; + end;"); +?> +--EXPECT-- +Using fetchAll: +Blob length: 2523 +Blob length: 35 +----------------------------------- +Using fetch in loop: +Blob length: 2523 +Blob length: 35 diff --git a/tests/test1.gif b/tests/test1.gif new file mode 100644 index 0000000..f352c73 Binary files /dev/null and b/tests/test1.gif differ diff --git a/tests/test2.gif b/tests/test2.gif new file mode 100644 index 0000000..c4d4483 Binary files /dev/null and b/tests/test2.gif differ