summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorWez Furlong <wez@php.net>2005-02-06 22:11:12 +0000
committerWez Furlong <wez@php.net>2005-02-06 22:11:12 +0000
commitccf0a6a5579721aac7398a486d946f985f9b0a08 (patch)
tree36c2978bdf647c3c0529a5f779708079adb87e0a /ext
parentf400f0e665bb8a8cdc9b13c09be7d9cc1e03db9f (diff)
downloadphp-git-ccf0a6a5579721aac7398a486d946f985f9b0a08.tar.gz
add a caller_frees parameter to get_col() to allow drivers that need
to allocate data on demand to do so without worrying about cleaning it up. Spec out how LOB parameters are returned.
Diffstat (limited to 'ext')
-rwxr-xr-xext/pdo/pdo_stmt.c39
-rwxr-xr-xext/pdo/php_pdo_driver.h23
2 files changed, 57 insertions, 5 deletions
diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c
index 83bbec7e96..b88c43ee06 100755
--- a/ext/pdo/pdo_stmt.c
+++ b/ext/pdo/pdo_stmt.c
@@ -33,6 +33,7 @@
#include "php_pdo_driver.h"
#include "php_pdo_int.h"
#include "zend_exceptions.h"
+#include "php_memory_streams.h"
#if COMPILE_DL_PDO
/* {{{ content from zend_arg_defs.c:
@@ -369,13 +370,14 @@ static inline void fetch_value(pdo_stmt_t *stmt, zval *dest, int colno TSRMLS_DC
struct pdo_column_data *col;
char *value = NULL;
unsigned long value_len = 0;
+ int caller_frees = 0;
col = &stmt->columns[colno];
value = NULL;
value_len = 0;
- stmt->methods->get_col(stmt, colno, &value, &value_len TSRMLS_CC);
+ stmt->methods->get_col(stmt, colno, &value, &value_len, &caller_frees TSRMLS_CC);
switch (col->param_type) {
case PDO_PARAM_INT:
@@ -395,14 +397,47 @@ static inline void fetch_value(pdo_stmt_t *stmt, zval *dest, int colno TSRMLS_DC
break;
case PDO_PARAM_LOB:
+ if (value == NULL) {
+ ZVAL_NULL(dest);
+ } else if (value_len == 0) {
+ php_stream_to_zval((php_stream*)value, dest);
+ } else {
+ /* they gave us a string, but LOBs are represented as streams in PDO */
+ php_stream *stm;
+#ifdef TEMP_STREAM_TAKE_BUFFER
+ if (caller_frees) {
+ stm = php_stream_memory_open(TEMP_STREAM_TAKE_BUFFER, value, value_len);
+ if (stm) {
+ caller_frees = 0;
+ }
+ } else
+#endif
+ {
+ stm = php_stream_memory_open(TEMP_STREAM_READONLY, value, value_len);
+ }
+ if (stm) {
+ php_stream_to_zval(stm, dest);
+ } else {
+ ZVAL_NULL(dest);
+ }
+ }
+ break;
+
case PDO_PARAM_STR:
if (value && !(value_len == 0 && stmt->dbh->oracle_nulls)) {
- ZVAL_STRINGL(dest, value, value_len, 1);
+ ZVAL_STRINGL(dest, value, value_len, !caller_frees);
+ if (caller_frees) {
+ caller_frees = 0;
+ }
break;
}
default:
ZVAL_NULL(dest);
}
+
+ if (caller_frees && value) {
+ efree(value);
+ }
}
static int do_fetch_common(pdo_stmt_t *stmt, enum pdo_fetch_orientation ori,
diff --git a/ext/pdo/php_pdo_driver.h b/ext/pdo/php_pdo_driver.h
index b054611328..4644ff8c63 100755
--- a/ext/pdo/php_pdo_driver.h
+++ b/ext/pdo/php_pdo_driver.h
@@ -35,14 +35,29 @@ struct pdo_bound_param_data;
# define FALSE 0
#endif
-#define PDO_DRIVER_API 20050205
+#define PDO_DRIVER_API 20050206
enum pdo_param_type {
PDO_PARAM_NULL,
- PDO_PARAM_INT, /* int as in long, the php native int type */
+
+ /* int as in long (the php native int type).
+ * If you mark a column as an int, PDO expects get_col to return
+ * a pointer to a long */
+ PDO_PARAM_INT,
+
+ /* get_col ptr should point to start of the string buffer */
PDO_PARAM_STR,
+
+ /* get_col: when len is 0 ptr should point to a php_stream *,
+ * otherwise it should behave like a string. Indicate a NULL field
+ * value by setting the ptr to NULL */
PDO_PARAM_LOB,
+
+ /* get_col: will expect the ptr to point to a new PDOStatement object handle,
+ * but this isn't wired up yet */
PDO_PARAM_STMT, /* hierarchical result set */
+
+ /* get_col ptr should point to a zend_bool */
PDO_PARAM_BOOL
};
@@ -275,8 +290,10 @@ typedef int (*pdo_stmt_describe_col_func)(pdo_stmt_t *stmt, int colno TSRMLS_DC)
/* retrieves pointer and size of the value for a column.
* Note that PDO expects the driver to manage the lifetime of this data;
* it will copy the value into a zval on behalf of the script.
+ * If the driver sets caller_frees, ptr should point to emalloc'd memory
+ * and PDO will free it as soon as it is done using it.
*/
-typedef int (*pdo_stmt_get_col_data_func)(pdo_stmt_t *stmt, int colno, char **ptr, unsigned long *len TSRMLS_DC);
+typedef int (*pdo_stmt_get_col_data_func)(pdo_stmt_t *stmt, int colno, char **ptr, unsigned long *len, int *caller_frees TSRMLS_DC);
/* hook for bound params */
enum pdo_param_event {