#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:
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:
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,
# 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
};
/* 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 {