]> granicus.if.org Git - php/commitdiff
add a caller_frees parameter to get_col() to allow drivers that need
authorWez Furlong <wez@php.net>
Sun, 6 Feb 2005 22:11:12 +0000 (22:11 +0000)
committerWez Furlong <wez@php.net>
Sun, 6 Feb 2005 22:11:12 +0000 (22:11 +0000)
to allocate data on demand to do so without worrying about cleaning it up.

Spec out how LOB parameters are returned.

ext/pdo/pdo_stmt.c
ext/pdo/php_pdo_driver.h

index 83bbec7e962e0c5942fa5d6bc40d8c36852df19e..b88c43ee0619d81e861c1daf7681137f060e0cc5 100755 (executable)
@@ -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,
index b0546113283248c2339073ddcdf04d54edc23b2b..4644ff8c63082e5ea865ad55e3dbe362a297763e 100755 (executable)
@@ -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 {