wez Mon Nov 28 21:11:40 2005 EDT Added files: (Branch: PHP_5_1) /php-src/ext/pdo_pgsql/tests config.inc large_objects.phpt
Modified files: /php-src/ext/pdo_pgsql package.xml pdo_pgsql.c pgsql_driver.c pgsql_statement.c php_pdo_pgsql_int.h /php-src/ext/pdo_pgsql/tests bug_33876.phpt common.phpt Log: Added PDO::pgsqlLOBCreate(), PDO::pgsqlLOBOpen() and PDO::pgsqlLOBUnlink().
http://cvs.php.net/diff.php/php-src/ext/pdo_pgsql/package.xml?r1=1.5.2.4&r2=1.5.2.5&ty=u Index: php-src/ext/pdo_pgsql/package.xml diff -u php-src/ext/pdo_pgsql/package.xml:1.5.2.4 php-src/ext/pdo_pgsql/package.xml:1.5.2.5 --- php-src/ext/pdo_pgsql/package.xml:1.5.2.4 Sat Nov 26 15:50:07 2005 +++ php-src/ext/pdo_pgsql/package.xml Mon Nov 28 21:11:37 2005 @@ -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 @@ 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 @@ </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> http://cvs.php.net/diff.php/php-src/ext/pdo_pgsql/pdo_pgsql.c?r1=1.7.2.6&r2=1.7.2.7&ty=u Index: php-src/ext/pdo_pgsql/pdo_pgsql.c diff -u php-src/ext/pdo_pgsql/pdo_pgsql.c:1.7.2.6 php-src/ext/pdo_pgsql/pdo_pgsql.c:1.7.2.7 --- php-src/ext/pdo_pgsql/pdo_pgsql.c:1.7.2.6 Sat Nov 26 15:50:08 2005 +++ php-src/ext/pdo_pgsql/pdo_pgsql.c Mon Nov 28 21:11:37 2005 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pdo_pgsql.c,v 1.7.2.6 2005/11/26 20:50:08 wez Exp $ */ +/* $Id: pdo_pgsql.c,v 1.7.2.7 2005/11/29 02:11:37 wez Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -61,7 +61,7 @@ PHP_RINIT(pdo_pgsql), PHP_RSHUTDOWN(pdo_pgsql), PHP_MINFO(pdo_pgsql), - "1.0", + "1.0.1", STANDARD_MODULE_PROPERTIES }; /* }}} */ http://cvs.php.net/diff.php/php-src/ext/pdo_pgsql/pgsql_driver.c?r1=1.53.2.1&r2=1.53.2.2&ty=u Index: php-src/ext/pdo_pgsql/pgsql_driver.c diff -u php-src/ext/pdo_pgsql/pgsql_driver.c:1.53.2.1 php-src/ext/pdo_pgsql/pgsql_driver.c:1.53.2.2 --- php-src/ext/pdo_pgsql/pgsql_driver.c:1.53.2.1 Thu Nov 24 22:35:04 2005 +++ php-src/ext/pdo_pgsql/pgsql_driver.c Mon Nov 28 21:11:37 2005 @@ -12,11 +12,13 @@ | obtain it through the world-wide-web, please send a note to | | [EMAIL PROTECTED] so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Author: Edin Kadribasic <[EMAIL PROTECTED]> | + | Authors: Edin Kadribasic <[EMAIL PROTECTED]> | + | Ilia Alshanestsky <[EMAIL PROTECTED]> | + | Wez Furlong <[EMAIL PROTECTED]> | +----------------------------------------------------------------------+ */ -/* $Id: pgsql_driver.c,v 1.53.2.1 2005/11/25 03:35:04 wez Exp $ */ +/* $Id: pgsql_driver.c,v 1.53.2.2 2005/11/29 02:11:37 wez Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -108,6 +110,81 @@ } /* }}} */ +/* {{{ 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 @@ 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 @@ 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 @@ 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; http://cvs.php.net/diff.php/php-src/ext/pdo_pgsql/pgsql_statement.c?r1=1.31.2.4&r2=1.31.2.5&ty=u Index: php-src/ext/pdo_pgsql/pgsql_statement.c diff -u php-src/ext/pdo_pgsql/pgsql_statement.c:1.31.2.4 php-src/ext/pdo_pgsql/pgsql_statement.c:1.31.2.5 --- php-src/ext/pdo_pgsql/pgsql_statement.c:1.31.2.4 Thu Nov 24 22:35:04 2005 +++ php-src/ext/pdo_pgsql/pgsql_statement.c Mon Nov 28 21:11:38 2005 @@ -12,11 +12,13 @@ | obtain it through the world-wide-web, please send a note to | | [EMAIL PROTECTED] so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Author: Edin Kadribasic <[EMAIL PROTECTED]> | + | Authors: Edin Kadribasic <[EMAIL PROTECTED]> | + | Ilia Alshanestsky <[EMAIL PROTECTED]> | + | Wez Furlong <[EMAIL PROTECTED]> | +----------------------------------------------------------------------+ */ -/* $Id: pgsql_statement.c,v 1.31.2.4 2005/11/25 03:35:04 wez Exp $ */ +/* $Id: pgsql_statement.c,v 1.31.2.5 2005/11/29 02:11:38 wez Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -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 @@ #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 @@ 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 @@ { 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 @@ 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 @@ 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: http://cvs.php.net/diff.php/php-src/ext/pdo_pgsql/php_pdo_pgsql_int.h?r1=1.13.2.1&r2=1.13.2.2&ty=u Index: php-src/ext/pdo_pgsql/php_pdo_pgsql_int.h diff -u php-src/ext/pdo_pgsql/php_pdo_pgsql_int.h:1.13.2.1 php-src/ext/pdo_pgsql/php_pdo_pgsql_int.h:1.13.2.2 --- php-src/ext/pdo_pgsql/php_pdo_pgsql_int.h:1.13.2.1 Thu Nov 24 22:35:04 2005 +++ php-src/ext/pdo_pgsql/php_pdo_pgsql_int.h Mon Nov 28 21:11:38 2005 @@ -12,16 +12,19 @@ | obtain it through the world-wide-web, please send a note to | | [EMAIL PROTECTED] so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Author: Edin Kadribasic <[EMAIL PROTECTED]> | + | Authors: Edin Kadribasic <[EMAIL PROTECTED]> | + | Ilia Alshanestsky <[EMAIL PROTECTED]> | + | Wez Furlong <[EMAIL PROTECTED]> | +----------------------------------------------------------------------+ */ -/* $Id: php_pdo_pgsql_int.h,v 1.13.2.1 2005/11/25 03:35:04 wez Exp $ */ +/* $Id: php_pdo_pgsql_int.h,v 1.13.2.2 2005/11/29 02:11:38 wez Exp $ */ #ifndef PHP_PDO_PGSQL_INT_H #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 @@ } 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 @@ 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 */ /* http://cvs.php.net/diff.php/php-src/ext/pdo_pgsql/tests/bug_33876.phpt?r1=1.1.2.4&r2=1.1.2.5&ty=u Index: php-src/ext/pdo_pgsql/tests/bug_33876.phpt diff -u php-src/ext/pdo_pgsql/tests/bug_33876.phpt:1.1.2.4 php-src/ext/pdo_pgsql/tests/bug_33876.phpt:1.1.2.5 --- php-src/ext/pdo_pgsql/tests/bug_33876.phpt:1.1.2.4 Mon Oct 17 20:15:02 2005 +++ php-src/ext/pdo_pgsql/tests/bug_33876.phpt Mon Nov 28 21:11:39 2005 @@ -3,6 +3,7 @@ --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(); ?> http://cvs.php.net/diff.php/php-src/ext/pdo_pgsql/tests/common.phpt?r1=1.1&r2=1.1.2.1&ty=u Index: php-src/ext/pdo_pgsql/tests/common.phpt diff -u php-src/ext/pdo_pgsql/tests/common.phpt:1.1 php-src/ext/pdo_pgsql/tests/common.phpt:1.1.2.1 --- php-src/ext/pdo_pgsql/tests/common.phpt:1.1 Thu Jul 7 11:20:06 2005 +++ php-src/ext/pdo_pgsql/tests/common.phpt Mon Nov 28 21:11:39 2005 @@ -5,6 +5,7 @@ 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' http://cvs.php.net/co.php/php-src/ext/pdo_pgsql/tests/config.inc?r=1.1&p=1 Index: php-src/ext/pdo_pgsql/tests/config.inc +++ php-src/ext/pdo_pgsql/tests/config.inc http://cvs.php.net/co.php/php-src/ext/pdo_pgsql/tests/large_objects.phpt?r=1.1&p=1 Index: php-src/ext/pdo_pgsql/tests/large_objects.phpt +++ php-src/ext/pdo_pgsql/tests/large_objects.phpt
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php