mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Added PDO::pgsqlLOBCreate(), PDO::pgsqlLOBOpen() and PDO::pgsqlLOBUnlink().
This commit is contained in:
parent
2ad81f4584
commit
131033352d
9 changed files with 361 additions and 22 deletions
|
@ -30,8 +30,8 @@
|
|||
<license>PHP</license>
|
||||
<release>
|
||||
<state>stable</state>
|
||||
<version>1.0</version>
|
||||
<date>2005-11-26</date>
|
||||
<version>1.0.1</version>
|
||||
<date>2005-11-28</date>
|
||||
|
||||
<notes>
|
||||
Now features native prepared statements and numerous other improvements.
|
||||
|
@ -42,6 +42,8 @@ intend to build and/or use it.
|
|||
|
||||
If you are running on windows, you can download the binary from here:
|
||||
http://pecl4win.php.net/ext.php/php_pdo_pgsql.dll
|
||||
|
||||
Added PDO::pgsqlLOBCreate(), PDO::pgsqlLOBOpen() and PDO::pgsqlLOBUnlink().
|
||||
</notes>
|
||||
|
||||
<filelist>
|
||||
|
@ -57,7 +59,7 @@ http://pecl4win.php.net/ext.php/php_pdo_pgsql.dll
|
|||
</filelist>
|
||||
<deps>
|
||||
<dep type="php" rel="ge" version="5.0.3"/>
|
||||
<dep type="ext" rel="ge" name="pdo" version="1.0"/>
|
||||
<dep type="ext" rel="ge" name="pdo" version="1.0.2"/>
|
||||
</deps>
|
||||
</release>
|
||||
</package>
|
||||
|
|
|
@ -61,7 +61,7 @@ zend_module_entry pdo_pgsql_module_entry = {
|
|||
PHP_RINIT(pdo_pgsql),
|
||||
PHP_RSHUTDOWN(pdo_pgsql),
|
||||
PHP_MINFO(pdo_pgsql),
|
||||
"1.0",
|
||||
"1.0.1",
|
||||
STANDARD_MODULE_PROPERTIES
|
||||
};
|
||||
/* }}} */
|
||||
|
|
|
@ -12,7 +12,9 @@
|
|||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Edin Kadribasic <edink@emini.dk> |
|
||||
| Authors: Edin Kadribasic <edink@emini.dk> |
|
||||
| Ilia Alshanestsky <ilia@prohost.org> |
|
||||
| Wez Furlong <wez@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
|
@ -108,6 +110,81 @@ static int pdo_pgsql_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *in
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ pdo_pgsql_create_lob_stream */
|
||||
static size_t pgsql_lob_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC)
|
||||
{
|
||||
struct pdo_pgsql_lob_self *self = (struct pdo_pgsql_lob_self*)stream->abstract;
|
||||
return lo_write(self->conn, self->lfd, (char*)buf, count);
|
||||
}
|
||||
|
||||
static size_t pgsql_lob_read(php_stream *stream, char *buf, size_t count TSRMLS_DC)
|
||||
{
|
||||
struct pdo_pgsql_lob_self *self = (struct pdo_pgsql_lob_self*)stream->abstract;
|
||||
return lo_read(self->conn, self->lfd, buf, count);
|
||||
}
|
||||
|
||||
static int pgsql_lob_close(php_stream *stream, int close_handle TSRMLS_DC)
|
||||
{
|
||||
struct pdo_pgsql_lob_self *self = (struct pdo_pgsql_lob_self*)stream->abstract;
|
||||
pdo_dbh_t *dbh = self->dbh;
|
||||
|
||||
if (close_handle) {
|
||||
lo_close(self->conn, self->lfd);
|
||||
}
|
||||
efree(self);
|
||||
php_pdo_dbh_delref(dbh TSRMLS_DC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pgsql_lob_flush(php_stream *stream TSRMLS_DC)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pgsql_lob_seek(php_stream *stream, off_t offset, int whence,
|
||||
off_t *newoffset TSRMLS_DC)
|
||||
{
|
||||
struct pdo_pgsql_lob_self *self = (struct pdo_pgsql_lob_self*)stream->abstract;
|
||||
int pos = lo_lseek(self->conn, self->lfd, offset, whence);
|
||||
*newoffset = pos;
|
||||
return pos >= 0 ? 0 : -1;
|
||||
}
|
||||
|
||||
php_stream_ops pdo_pgsql_lob_stream_ops = {
|
||||
pgsql_lob_write,
|
||||
pgsql_lob_read,
|
||||
pgsql_lob_close,
|
||||
pgsql_lob_flush,
|
||||
"pdo_pgsql lob stream",
|
||||
pgsql_lob_seek,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
php_stream *pdo_pgsql_create_lob_stream(pdo_dbh_t *dbh, int lfd, Oid oid TSRMLS_DC)
|
||||
{
|
||||
php_stream *stm;
|
||||
struct pdo_pgsql_lob_self *self = ecalloc(1, sizeof(*self));
|
||||
pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
|
||||
|
||||
self->dbh = dbh;
|
||||
self->lfd = lfd;
|
||||
self->oid = oid;
|
||||
self->conn = H->server;
|
||||
|
||||
stm = php_stream_alloc(&pdo_pgsql_lob_stream_ops, self, 0, "r+b");
|
||||
|
||||
if (stm) {
|
||||
php_pdo_dbh_addref(dbh TSRMLS_CC);
|
||||
return stm;
|
||||
}
|
||||
|
||||
efree(self);
|
||||
return NULL;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int pgsql_handle_closer(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
|
||||
|
@ -397,6 +474,124 @@ static int pgsql_handle_rollback(pdo_dbh_t *dbh TSRMLS_DC)
|
|||
return pdo_pgsql_transaction_cmd("ROLLBACK", dbh TSRMLS_CC);
|
||||
}
|
||||
|
||||
/* {{{ string pgSQL::pgsqlLOBCreate()
|
||||
Creates a new large object, returning its identifier. Must be called inside a transaction. */
|
||||
static PHP_METHOD(pgSQL, pgsqlLOBCreate)
|
||||
{
|
||||
pdo_dbh_t *dbh;
|
||||
pdo_pgsql_db_handle *H;
|
||||
Oid lfd;
|
||||
|
||||
dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
PDO_CONSTRUCT_CHECK;
|
||||
|
||||
H = (pdo_pgsql_db_handle *)dbh->driver_data;
|
||||
lfd = lo_creat(H->server, INV_READ|INV_WRITE);
|
||||
|
||||
if (lfd != InvalidOid) {
|
||||
char *buf;
|
||||
spprintf(&buf, 0, "%lu", lfd);
|
||||
RETURN_STRING(buf, 0);
|
||||
}
|
||||
|
||||
pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "HY000");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ resource pgSQL::pgsqlLOBOpen(string oid [, string mode = 'rb'])
|
||||
Opens an existing large object stream. Must be called inside a transaction. */
|
||||
static PHP_METHOD(pgSQL, pgsqlLOBOpen)
|
||||
{
|
||||
pdo_dbh_t *dbh;
|
||||
pdo_pgsql_db_handle *H;
|
||||
Oid oid;
|
||||
int lfd;
|
||||
char *oidstr;
|
||||
int oidstrlen;
|
||||
char *modestr = "rb";
|
||||
int modestrlen;
|
||||
int mode = INV_READ;
|
||||
char *end_ptr;
|
||||
|
||||
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s",
|
||||
&oidstr, &oidstrlen, &modestr, &modestrlen)) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
oid = (Oid)strtoul(oidstr, &end_ptr, 10);
|
||||
if (oid == 0 && (errno == ERANGE || errno == EINVAL)) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
if (strpbrk(modestr, "+w")) {
|
||||
mode = INV_READ|INV_WRITE;
|
||||
}
|
||||
|
||||
dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
PDO_CONSTRUCT_CHECK;
|
||||
|
||||
H = (pdo_pgsql_db_handle *)dbh->driver_data;
|
||||
|
||||
lfd = lo_open(H->server, oid, mode);
|
||||
|
||||
if (lfd >= 0) {
|
||||
php_stream *stream = pdo_pgsql_create_lob_stream(dbh, lfd, oid TSRMLS_CC);
|
||||
if (stream) {
|
||||
php_stream_to_zval(stream, return_value);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "HY000");
|
||||
}
|
||||
RETURN_FALSE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ bool pgSQL::pgsqlLOBUnlink(int oid)
|
||||
Deletes the large object identified by oid. Must be called inside a transaction. */
|
||||
static PHP_METHOD(pgSQL, pgsqlLOBUnlink)
|
||||
{
|
||||
pdo_dbh_t *dbh;
|
||||
pdo_pgsql_db_handle *H;
|
||||
long lfd;
|
||||
|
||||
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",
|
||||
&lfd)) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
PDO_CONSTRUCT_CHECK;
|
||||
|
||||
H = (pdo_pgsql_db_handle *)dbh->driver_data;
|
||||
|
||||
if (1 == lo_unlink(H->server, lfd)) {
|
||||
RETURN_TRUE;
|
||||
}
|
||||
pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "HY000");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static function_entry dbh_methods[] = {
|
||||
PHP_ME(pgSQL, pgsqlLOBCreate, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(pgSQL, pgsqlLOBOpen, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(pgSQL, pgsqlLOBUnlink, NULL, ZEND_ACC_PUBLIC)
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
static function_entry *pdo_pgsql_get_driver_methods(pdo_dbh_t *dbh, int kind TSRMLS_DC)
|
||||
{
|
||||
switch (kind) {
|
||||
case PDO_DBH_DRIVER_METHOD_KIND_DBH:
|
||||
return dbh_methods;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static struct pdo_dbh_methods pgsql_methods = {
|
||||
pgsql_handle_closer,
|
||||
pgsql_handle_preparer,
|
||||
|
@ -410,7 +605,7 @@ static struct pdo_dbh_methods pgsql_methods = {
|
|||
pdo_pgsql_fetch_error_func,
|
||||
pdo_pgsql_get_attribute,
|
||||
NULL, /* check_liveness */
|
||||
NULL /* get_driver_methods */
|
||||
pdo_pgsql_get_driver_methods /* get_driver_methods */
|
||||
};
|
||||
|
||||
static int pdo_pgsql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) /* {{{ */
|
||||
|
@ -462,7 +657,7 @@ static int pdo_pgsql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_
|
|||
H->pgoid = -1;
|
||||
|
||||
dbh->methods = &pgsql_methods;
|
||||
dbh->alloc_own_columns = 1;
|
||||
dbh->alloc_own_columns = 0;
|
||||
dbh->max_escaped_char_length = 2;
|
||||
|
||||
ret = 1;
|
||||
|
|
|
@ -12,7 +12,9 @@
|
|||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Edin Kadribasic <edink@emini.dk> |
|
||||
| Authors: Edin Kadribasic <edink@emini.dk> |
|
||||
| Ilia Alshanestsky <ilia@prohost.org> |
|
||||
| Wez Furlong <wez@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
|
@ -39,7 +41,6 @@
|
|||
#define TEXTOID 25
|
||||
#define OIDOID 26
|
||||
|
||||
|
||||
static int pgsql_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)
|
||||
{
|
||||
pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
|
||||
|
@ -184,6 +185,12 @@ static int pgsql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *
|
|||
#if HAVE_PQPREPARE
|
||||
if (S->stmt_name && param->is_param) {
|
||||
switch (event_type) {
|
||||
case PDO_PARAM_EVT_FREE:
|
||||
if (param->driver_data) {
|
||||
efree(param->driver_data);
|
||||
}
|
||||
break;
|
||||
|
||||
case PDO_PARAM_EVT_ALLOC:
|
||||
/* decode name from $1, $2 into 0, 1 etc. */
|
||||
if (param->name) {
|
||||
|
@ -224,10 +231,26 @@ static int pgsql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *
|
|||
php_stream *stm;
|
||||
php_stream_from_zval_no_verify(stm, ¶m->parameter);
|
||||
if (stm) {
|
||||
SEPARATE_ZVAL_IF_NOT_REF(¶m->parameter);
|
||||
Z_TYPE_P(param->parameter) = IS_STRING;
|
||||
Z_STRLEN_P(param->parameter) = php_stream_copy_to_mem(stm,
|
||||
&Z_STRVAL_P(param->parameter), PHP_STREAM_COPY_ALL, 0);
|
||||
if (php_stream_is(stm, &pdo_pgsql_lob_stream_ops)) {
|
||||
struct pdo_pgsql_lob_self *self = (struct pdo_pgsql_lob_self*)stm->abstract;
|
||||
pdo_pgsql_bound_param *P = param->driver_data;
|
||||
|
||||
if (P == NULL) {
|
||||
P = ecalloc(1, sizeof(*P));
|
||||
param->driver_data = P;
|
||||
}
|
||||
P->oid = htonl(self->oid);
|
||||
S->param_values[param->paramno] = (char*)&P->oid;
|
||||
S->param_lengths[param->paramno] = sizeof(P->oid);
|
||||
S->param_formats[param->paramno] = 1;
|
||||
S->param_types[param->paramno] = OIDOID;
|
||||
return 1;
|
||||
} else {
|
||||
SEPARATE_ZVAL_IF_NOT_REF(¶m->parameter);
|
||||
Z_TYPE_P(param->parameter) = IS_STRING;
|
||||
Z_STRLEN_P(param->parameter) = php_stream_copy_to_mem(stm,
|
||||
&Z_STRVAL_P(param->parameter), PHP_STREAM_COPY_ALL, 0);
|
||||
}
|
||||
} else {
|
||||
/* expected a stream resource */
|
||||
pdo_pgsql_error_stmt(stmt, PGRES_FATAL_ERROR, "HY105");
|
||||
|
@ -308,6 +331,7 @@ static int pgsql_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
|
|||
{
|
||||
pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
|
||||
struct pdo_column_data *cols = stmt->columns;
|
||||
struct pdo_bound_param_data *param;
|
||||
|
||||
if (!S->result) {
|
||||
return 0;
|
||||
|
@ -324,10 +348,25 @@ static int pgsql_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
|
|||
case BOOLOID:
|
||||
cols[colno].param_type = PDO_PARAM_BOOL;
|
||||
break;
|
||||
|
||||
case OIDOID:
|
||||
/* did the user bind the column as a LOB ? */
|
||||
if (stmt->bound_columns && (
|
||||
SUCCESS == zend_hash_index_find(stmt->bound_columns,
|
||||
colno, (void**)¶m) ||
|
||||
SUCCESS == zend_hash_find(stmt->bound_columns,
|
||||
cols[colno].name, cols[colno].namelen,
|
||||
(void**)¶m))) {
|
||||
if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB) {
|
||||
cols[colno].param_type = PDO_PARAM_LOB;
|
||||
break;
|
||||
}
|
||||
}
|
||||
cols[colno].param_type = PDO_PARAM_INT;
|
||||
break;
|
||||
|
||||
case INT2OID:
|
||||
case INT4OID:
|
||||
case OIDOID:
|
||||
cols[colno].param_type = PDO_PARAM_INT;
|
||||
break;
|
||||
|
||||
|
@ -487,9 +526,24 @@ static int pgsql_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, unsigned
|
|||
break;
|
||||
|
||||
case PDO_PARAM_LOB:
|
||||
*ptr = php_pdo_pgsql_unescape_bytea(*ptr, &tmp_len);
|
||||
*len = tmp_len;
|
||||
*caller_frees = 1;
|
||||
if (S->cols[colno].pgsql_type == OIDOID) {
|
||||
/* ooo, a real large object */
|
||||
char *end_ptr;
|
||||
Oid oid = (Oid)strtoul(*ptr, &end_ptr, 10);
|
||||
int loid = lo_open(S->H->server, oid, INV_READ);
|
||||
if (loid >= 0) {
|
||||
*ptr = (char*)pdo_pgsql_create_lob_stream(stmt->dbh, loid, oid TSRMLS_CC);
|
||||
*len = 0;
|
||||
return *ptr ? 1 : 0;
|
||||
}
|
||||
*ptr = NULL;
|
||||
*len = 0;
|
||||
return 0;
|
||||
} else {
|
||||
*ptr = php_pdo_pgsql_unescape_bytea(*ptr, &tmp_len);
|
||||
*len = tmp_len;
|
||||
*caller_frees = 1;
|
||||
}
|
||||
break;
|
||||
case PDO_PARAM_NULL:
|
||||
case PDO_PARAM_STR:
|
||||
|
|
|
@ -12,7 +12,9 @@
|
|||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Edin Kadribasic <edink@emini.dk> |
|
||||
| Authors: Edin Kadribasic <edink@emini.dk> |
|
||||
| Ilia Alshanestsky <ilia@prohost.org> |
|
||||
| Wez Furlong <wez@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
|
@ -22,6 +24,7 @@
|
|||
#define PHP_PDO_PGSQL_INT_H
|
||||
|
||||
#include <libpq-fe.h>
|
||||
#include <libpq/libpq-fs.h>
|
||||
#include <php.h>
|
||||
|
||||
#define PHP_PDO_PGSQL_CONNECTION_FAILURE_SQLSTATE "08006"
|
||||
|
@ -66,10 +69,7 @@ typedef struct {
|
|||
} pdo_pgsql_stmt;
|
||||
|
||||
typedef struct {
|
||||
char *repr;
|
||||
long repr_len;
|
||||
int pgsql_type;
|
||||
void *thing; /* for LOBS, REFCURSORS etc. */
|
||||
Oid oid;
|
||||
} pdo_pgsql_bound_param;
|
||||
|
||||
extern pdo_driver_t pdo_pgsql_driver;
|
||||
|
@ -90,6 +90,17 @@ enum {
|
|||
PDO_PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT = PDO_ATTR_DRIVER_SPECIFIC,
|
||||
};
|
||||
|
||||
struct pdo_pgsql_lob_self {
|
||||
pdo_dbh_t *dbh;
|
||||
PGconn *conn;
|
||||
int lfd;
|
||||
Oid oid;
|
||||
};
|
||||
|
||||
|
||||
php_stream *pdo_pgsql_create_lob_stream(pdo_dbh_t *stmt, int lfd, Oid oid TSRMLS_DC);
|
||||
extern php_stream_ops pdo_pgsql_lob_stream_ops;
|
||||
|
||||
#endif /* PHP_PDO_PGSQL_INT_H */
|
||||
|
||||
/*
|
||||
|
|
|
@ -3,6 +3,7 @@ PDO PgSQL Bug #33876
|
|||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('pdo') || !extension_loaded('pdo_pgsql')) die('skip not loaded');
|
||||
require dirname(__FILE__) . '/config.inc';
|
||||
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||
PDOTest::skip();
|
||||
?>
|
||||
|
|
|
@ -5,6 +5,7 @@ Postgres
|
|||
if (!extension_loaded('pdo_pgsql')) print 'skip'; ?>
|
||||
--REDIRECTTEST--
|
||||
# magic auto-configuration
|
||||
# Also update config.inc if you make changes here...
|
||||
|
||||
$config = array(
|
||||
'TESTS' => 'ext/pdo/tests'
|
||||
|
|
14
ext/pdo_pgsql/tests/config.inc
Normal file
14
ext/pdo_pgsql/tests/config.inc
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?php # vim:se ft=php:
|
||||
if (false !== getenv('PDO_PGSQL_TEST_DSN')) {
|
||||
# user set them from their shell
|
||||
$config['ENV']['PDOTEST_DSN'] = getenv('PDO_PGSQL_TEST_DSN');
|
||||
if (false !== getenv('PDO_PGSQL_TEST_ATTR')) {
|
||||
$config['ENV']['PDOTEST_ATTR'] = getenv('PDO_PGSQL_TEST_ATTR');
|
||||
}
|
||||
} else {
|
||||
$config['ENV']['PDOTEST_DSN'] = 'pgsql:host=localhost port=5432 dbname=test user=root password=';
|
||||
}
|
||||
|
||||
foreach ($config['ENV'] as $k => $v) {
|
||||
putenv("$k=$v");
|
||||
}
|
61
ext/pdo_pgsql/tests/large_objects.phpt
Normal file
61
ext/pdo_pgsql/tests/large_objects.phpt
Normal file
|
@ -0,0 +1,61 @@
|
|||
--TEST--
|
||||
PDO PgSQL Large Objects
|
||||
--SKIPIF--
|
||||
<?php # vim:se ft=php:
|
||||
if (!extension_loaded('pdo') || !extension_loaded('pdo_pgsql')) die('skip not loaded');
|
||||
require dirname(__FILE__) . '/config.inc';
|
||||
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||
PDOTest::skip();
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||
$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
|
||||
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);
|
||||
|
||||
$db->exec('CREATE TABLE test (blobid integer not null primary key, bloboid OID)');
|
||||
|
||||
$db->beginTransaction();
|
||||
$oid = $db->pgsqlLOBCreate();
|
||||
try {
|
||||
$stm = $db->pgsqlLOBOpen($oid);
|
||||
fwrite($stm, "Hello dude\n");
|
||||
|
||||
$stmt = $db->prepare("INSERT INTO test (blobid, bloboid) values (?, ?)");
|
||||
$stmt->bindValue(1, 1);
|
||||
/* bind as LOB; the oid from the pgsql stream will be inserted instead
|
||||
* of the stream contents. Binding other streams will attempt to bind
|
||||
* as bytea, and will most likely lead to an error.
|
||||
* You can also just bind the $oid in as a string. */
|
||||
$stmt->bindParam(2, $stm, PDO::PARAM_LOB);
|
||||
$stmt->execute();
|
||||
$stm = null;
|
||||
|
||||
/* Pull it out */
|
||||
$stmt = $db->prepare("SELECT * from test");
|
||||
$stmt->execute();
|
||||
$stmt->bindColumn('bloboid', $lob, PDO::PARAM_LOB);
|
||||
echo "Fetching:\n";
|
||||
while (($row = $stmt->fetch(PDO::FETCH_ASSOC))) {
|
||||
var_dump($row['blobid']);
|
||||
var_dump(stream_get_contents($lob));
|
||||
}
|
||||
echo "Fetched!\n";
|
||||
} catch (Exception $e) {
|
||||
/* catch exceptions so that we can guarantee to clean
|
||||
* up the LOB */
|
||||
echo "Exception! at line ", $e->getLine(), "\n";
|
||||
var_dump($e->getMessage());
|
||||
}
|
||||
|
||||
/* Now to remove the large object from the database, so it doesn't
|
||||
* linger and clutter up the storage */
|
||||
$db->pgsqlLOBUnlink($oid);
|
||||
|
||||
--EXPECT--
|
||||
Fetching:
|
||||
int(1)
|
||||
string(11) "Hello dude
|
||||
"
|
||||
Fetched!
|
Loading…
Add table
Add a link
Reference in a new issue