Back to index

php5  5.3.10
Classes | Defines | Functions | Variables
oci_statement.c File Reference
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "pdo/php_pdo.h"
#include "pdo/php_pdo_driver.h"
#include "php_pdo_oci.h"
#include "php_pdo_oci_int.h"
#include "Zend/zend_extensions.h"

Go to the source code of this file.

Classes

struct  oci_lob_self

Defines

#define PDO_OCI_LOBMAXSIZE   (4294967295UL) /* OCI_LOBMAXSIZE */
#define STMT_CALL(name, params)
#define STMT_CALL_MSG(name, msg, params)

Functions

static php_stream * oci_create_lob_stream (pdo_stmt_t *stmt, OCILobLocator *lob TSRMLS_DC)
static int oci_stmt_dtor (pdo_stmt_t *stmt TSRMLS_DC)
static int oci_stmt_execute (pdo_stmt_t *stmt TSRMLS_DC)
static sb4 oci_bind_input_cb (dvoid *ctx, OCIBind *bindp, ub4 iter, ub4 index, dvoid **bufpp, ub4 *alenp, ub1 *piecep, dvoid **indpp)
static sb4 oci_bind_output_cb (dvoid *ctx, OCIBind *bindp, ub4 iter, ub4 index, dvoid **bufpp, ub4 **alenpp, ub1 *piecep, dvoid **indpp, ub2 **rcodepp)
static int oci_stmt_param_hook (pdo_stmt_t *stmt, struct pdo_bound_param_data *param, enum pdo_param_event event_type TSRMLS_DC)
static int oci_stmt_fetch (pdo_stmt_t *stmt, enum pdo_fetch_orientation ori, long offset TSRMLS_DC)
static sb4 oci_define_callback (dvoid *octxp, OCIDefine *define, ub4 iter, dvoid **bufpp, ub4 **alenpp, ub1 *piecep, dvoid **indpp, ub2 **rcodepp)
static int oci_stmt_describe (pdo_stmt_t *stmt, int colno TSRMLS_DC)
static size_t oci_blob_write (php_stream *stream, const char *buf, size_t count TSRMLS_DC)
static size_t oci_blob_read (php_stream *stream, char *buf, size_t count TSRMLS_DC)
static int oci_blob_close (php_stream *stream, int close_handle TSRMLS_DC)
static int oci_blob_flush (php_stream *stream TSRMLS_DC)
static int oci_blob_seek (php_stream *stream, off_t offset, int whence, off_t *newoffset TSRMLS_DC)
static int oci_stmt_get_col (pdo_stmt_t *stmt, int colno, char **ptr, unsigned long *len, int *caller_frees TSRMLS_DC)

Variables

static php_stream_ops oci_blob_stream_ops

Class Documentation

struct oci_lob_self

Definition at line 601 of file oci_statement.c.

Collaboration diagram for oci_lob_self:
Class Members
OCILobLocator * lob
ub4 offset
pdo_oci_stmt * S
pdo_stmt_t * stmt

Define Documentation

#define PDO_OCI_LOBMAXSIZE   (4294967295UL) /* OCI_LOBMAXSIZE */

Definition at line 34 of file oci_statement.c.

#define STMT_CALL (   name,
  params 
)
Value:
do {                                                                                                            \
              S->last_err = name params;                                                                 \
              S->last_err = _oci_error(S->err, stmt->dbh, stmt, #name, S->last_err, FALSE, __FILE__, __LINE__ TSRMLS_CC); \
              if (S->last_err) {                                                                                \
                     return 0;                                                                                         \
              }                                                                                                               \
       } while(0)

Definition at line 36 of file oci_statement.c.

#define STMT_CALL_MSG (   name,
  msg,
  params 
)
Value:
do {                                                                                                            \
              S->last_err = name params;                                                                 \
              S->last_err = _oci_error(S->err, stmt->dbh, stmt, #name ": " #msg, S->last_err, FALSE, __FILE__, __LINE__ TSRMLS_CC); \
              if (S->last_err) {                                                                                \
                     return 0;                                                                                         \
              }                                                                                                               \
       } while(0)

Definition at line 45 of file oci_statement.c.


Function Documentation

static sb4 oci_bind_input_cb ( dvoid *  ctx,
OCIBind *  bindp,
ub4  iter,
ub4  index,
dvoid **  bufpp,
ub4 *  alenp,
ub1 *  piecep,
dvoid **  indpp 
) [static]

Definition at line 187 of file oci_statement.c.

{
       struct pdo_bound_param_data *param = (struct pdo_bound_param_data*)ctx;
       pdo_oci_bound_param *P = (pdo_oci_bound_param*)param->driver_data;
       TSRMLS_FETCH();

       if (!param || !param->parameter) {
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "param is NULL in oci_bind_input_cb; this should not happen");
              return OCI_ERROR;
       }

       *indpp = &P->indicator;

       if (P->thing) {
              *bufpp = P->thing;
              *alenp = sizeof(void*);
       } else if (ZVAL_IS_NULL(param->parameter)) {
              /* insert a NULL value into the column */
              P->indicator = -1; /* NULL */
              *bufpp = 0;
              *alenp = -1;
       } else if (!P->thing) {
              /* regular string bind */
              convert_to_string(param->parameter);
              *bufpp = Z_STRVAL_P(param->parameter);
              *alenp = Z_STRLEN_P(param->parameter);
       }

       *piecep = OCI_ONE_PIECE;
       return OCI_CONTINUE;
} /* }}} */

Here is the caller graph for this function:

static sb4 oci_bind_output_cb ( dvoid *  ctx,
OCIBind *  bindp,
ub4  iter,
ub4  index,
dvoid **  bufpp,
ub4 **  alenpp,
ub1 *  piecep,
dvoid **  indpp,
ub2 **  rcodepp 
) [static]

Definition at line 219 of file oci_statement.c.

{
       struct pdo_bound_param_data *param = (struct pdo_bound_param_data*)ctx;
       pdo_oci_bound_param *P = (pdo_oci_bound_param*)param->driver_data;
       TSRMLS_FETCH();

       if (!param || !param->parameter) {
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "param is NULL in oci_bind_output_cb; this should not happen");
              return OCI_ERROR;
       }

       if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB) {
              P->actual_len = sizeof(OCILobLocator*);
              *bufpp = P->thing;
              *alenpp = &P->actual_len;
              *piecep = OCI_ONE_PIECE;
              *rcodepp = &P->retcode;
              *indpp = &P->indicator;
              return OCI_CONTINUE;
       }

       if (Z_TYPE_P(param->parameter) == IS_OBJECT || Z_TYPE_P(param->parameter) == IS_RESOURCE) {
              return OCI_CONTINUE;
       }

       convert_to_string(param->parameter);
       zval_dtor(param->parameter);

       Z_STRLEN_P(param->parameter) = param->max_value_len;
       Z_STRVAL_P(param->parameter) = ecalloc(1, Z_STRLEN_P(param->parameter)+1);
       P->used_for_output = 1;

       P->actual_len = Z_STRLEN_P(param->parameter);
       *alenpp = &P->actual_len;
       *bufpp = Z_STRVAL_P(param->parameter);
       *piecep = OCI_ONE_PIECE;
       *rcodepp = &P->retcode;
       *indpp = &P->indicator;

       return OCI_CONTINUE;
} /* }}} */

Here is the caller graph for this function:

static int oci_blob_close ( php_stream *  stream,
int close_handle  TSRMLS_DC 
) [static]

Definition at line 650 of file oci_statement.c.

{
       struct oci_lob_self *self = (struct oci_lob_self*)stream->abstract;
       pdo_stmt_t *stmt = self->stmt;

       if (close_handle) {
              OCILobClose(self->S->H->svc, self->S->err, self->lob);
              OCIDescriptorFree(self->lob, OCI_DTYPE_LOB);
              efree(self);
       }

       php_pdo_stmt_delref(stmt TSRMLS_CC);
       return 0;
}

Here is the call graph for this function:

static int oci_blob_flush ( php_stream *stream  TSRMLS_DC) [static]

Definition at line 665 of file oci_statement.c.

{
       struct oci_lob_self *self = (struct oci_lob_self*)stream->abstract;
       OCILobFlushBuffer(self->S->H->svc, self->S->err, self->lob, 0);
       return 0;
}
static size_t oci_blob_read ( php_stream *  stream,
char *  buf,
size_t count  TSRMLS_DC 
) [static]

Definition at line 628 of file oci_statement.c.

{
       struct oci_lob_self *self = (struct oci_lob_self*)stream->abstract;
       ub4 amt;
       sword r;

       amt = count;
       r = OCILobRead(self->S->H->svc, self->S->err, self->lob,
              &amt, self->offset, buf, count,
              NULL, NULL, 0, SQLCS_IMPLICIT);

       if (r != OCI_SUCCESS && r != OCI_NEED_DATA) {
              return (size_t)-1;
       }

       self->offset += amt;
       if (amt < count) {
              stream->eof = 1;
       }
       return amt;
}
static int oci_blob_seek ( php_stream *  stream,
off_t  offset,
int  whence,
off_t *newoffset  TSRMLS_DC 
) [static]

Definition at line 672 of file oci_statement.c.

{
       struct oci_lob_self *self = (struct oci_lob_self*)stream->abstract;

       if (offset >= PDO_OCI_LOBMAXSIZE) {
              return -1;
       } else {
              self->offset = offset + 1;  /* Oracle LOBS are 1-based, but PHP is 0-based */
              return 0;
       }
}
static size_t oci_blob_write ( php_stream *  stream,
const char *  buf,
size_t count  TSRMLS_DC 
) [static]

Definition at line 608 of file oci_statement.c.

{
       struct oci_lob_self *self = (struct oci_lob_self*)stream->abstract;
       ub4 amt;
       sword r;

       amt = count;
       r = OCILobWrite(self->S->H->svc, self->S->err, self->lob,
              &amt, self->offset, (char*)buf, count,
              OCI_ONE_PIECE,
              NULL, NULL, 0, SQLCS_IMPLICIT);

       if (r != OCI_SUCCESS) {
              return (size_t)-1;
       }

       self->offset += amt;
       return amt;
}
static php_stream * oci_create_lob_stream ( pdo_stmt_t *  stmt,
OCILobLocator *lob  TSRMLS_DC 
) [static]

Definition at line 696 of file oci_statement.c.

{
       php_stream *stm;
       struct oci_lob_self *self = ecalloc(1, sizeof(*self));
       self->lob = lob;
       self->offset = 1; /* 1-based */
       self->stmt = stmt;
       self->S = (pdo_oci_stmt*)stmt->driver_data;

       stm = php_stream_alloc(&oci_blob_stream_ops, self, 0, "r+b");

       if (stm) {
              php_pdo_stmt_addref(stmt TSRMLS_CC);
              return stm;
       }

       efree(self);
       return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static sb4 oci_define_callback ( dvoid *  octxp,
OCIDefine *  define,
ub4  iter,
dvoid **  bufpp,
ub4 **  alenpp,
ub1 *  piecep,
dvoid **  indpp,
ub2 **  rcodepp 
) [static]

Definition at line 474 of file oci_statement.c.

{
       pdo_oci_column *col = (pdo_oci_column*)octxp;
       TSRMLS_FETCH();

       switch (col->dtype) {
              case SQLT_BLOB:
              case SQLT_CLOB:
                     *piecep = OCI_ONE_PIECE;
                     *bufpp = col->data;
                     *alenpp = &col->datalen;
                     *indpp = (dvoid *)&col->indicator;
                     break;

              default:
                     php_error_docref(NULL TSRMLS_CC, E_WARNING,
                            "unhandled datatype in oci_define_callback; this should not happen");
                     return OCI_ERROR;
       }

       return OCI_CONTINUE;
}

Here is the caller graph for this function:

static int oci_stmt_describe ( pdo_stmt_t *  stmt,
int colno  TSRMLS_DC 
) [static]

Definition at line 498 of file oci_statement.c.

{
       pdo_oci_stmt *S = (pdo_oci_stmt*)stmt->driver_data;
       OCIParam *param = NULL;
       text *colname;
       ub2 dtype, data_size, scale, precis;
       ub4 namelen;
       struct pdo_column_data *col = &stmt->columns[colno];
       zend_bool dyn = FALSE;

       /* describe the column */
       STMT_CALL(OCIParamGet, (S->stmt, OCI_HTYPE_STMT, S->err, (dvoid*)&param, colno+1));

       /* what type ? */
       STMT_CALL_MSG(OCIAttrGet, "OCI_ATTR_DATA_TYPE",
                     (param, OCI_DTYPE_PARAM, &dtype, 0, OCI_ATTR_DATA_TYPE, S->err));

       /* how big ? */
       STMT_CALL_MSG(OCIAttrGet, "OCI_ATTR_DATA_SIZE",
                     (param, OCI_DTYPE_PARAM, &data_size, 0, OCI_ATTR_DATA_SIZE, S->err));

       /* scale ? */
       STMT_CALL_MSG(OCIAttrGet, "OCI_ATTR_SCALE",
                     (param, OCI_DTYPE_PARAM, &scale, 0, OCI_ATTR_SCALE, S->err));

       /* precision ? */
       STMT_CALL_MSG(OCIAttrGet, "OCI_ATTR_PRECISION",
                     (param, OCI_DTYPE_PARAM, &precis, 0, OCI_ATTR_PRECISION, S->err));

       /* name ? */
       STMT_CALL_MSG(OCIAttrGet, "OCI_ATTR_NAME",
                     (param, OCI_DTYPE_PARAM, &colname, &namelen, OCI_ATTR_NAME, S->err));

       col->precision = scale;
       col->maxlen = data_size;
       col->namelen = namelen;
       col->name = estrndup((char *)colname, namelen);

       S->cols[colno].dtype = dtype;

       /* how much room do we need to store the field */
       switch (dtype) {
              case SQLT_LBI:
              case SQLT_LNG:
                     if (dtype == SQLT_LBI) {
                            dtype = SQLT_BIN;
                     } else {
                            dtype = SQLT_CHR;
                     }
                     S->cols[colno].datalen = 512; /* XXX should be INT_MAX and fetched by pieces */
                     S->cols[colno].data = emalloc(S->cols[colno].datalen + 1);
                     col->param_type = PDO_PARAM_STR;
                     break;

              case SQLT_BLOB:
              case SQLT_CLOB:
                     col->param_type = PDO_PARAM_LOB;
                     STMT_CALL(OCIDescriptorAlloc, (S->H->env, (dvoid**)&S->cols[colno].data, OCI_DTYPE_LOB, 0, NULL));
                     S->cols[colno].datalen = sizeof(OCILobLocator*);
                     dyn = TRUE;
                     break;

              case SQLT_BIN:
              default:
                     if (dtype == SQLT_DAT || dtype == SQLT_NUM || dtype == SQLT_RDD
#ifdef SQLT_TIMESTAMP
                                   || dtype == SQLT_TIMESTAMP
#endif
#ifdef SQLT_TIMESTAMP_TZ
                                   || dtype == SQLT_TIMESTAMP_TZ
#endif
                                   ) {
                            /* should be big enough for most date formats and numbers */
                            S->cols[colno].datalen = 512;
#if defined(SQLT_IBFLOAT) && defined(SQLT_IBDOUBLE)
                     } else if (dtype == SQLT_IBFLOAT || dtype == SQLT_IBDOUBLE) {
                            S->cols[colno].datalen = 1024;
#endif
                     } else {
                            S->cols[colno].datalen = col->maxlen;
                     }
                     if (dtype == SQLT_BIN) {
                            S->cols[colno].datalen *= 3;
                     }
                     S->cols[colno].data = emalloc(S->cols[colno].datalen + 1);
                     dtype = SQLT_CHR;

                     /* returning data as a string */
                     col->param_type = PDO_PARAM_STR;
       }

       STMT_CALL(OCIDefineByPos, (S->stmt, &S->cols[colno].def, S->err, colno+1,
                            S->cols[colno].data, S->cols[colno].datalen, dtype, &S->cols[colno].indicator,
                            &S->cols[colno].fetched_len, &S->cols[colno].retcode, dyn ? OCI_DYNAMIC_FETCH : OCI_DEFAULT));

       if (dyn) {
              STMT_CALL(OCIDefineDynamic, (S->cols[colno].def, S->err, &S->cols[colno],
                            oci_define_callback));
       }

       return 1;
} /* }}} */

Here is the call graph for this function:

static int oci_stmt_dtor ( pdo_stmt_t *stmt  TSRMLS_DC) [static]

Definition at line 56 of file oci_statement.c.

{
       pdo_oci_stmt *S = (pdo_oci_stmt*)stmt->driver_data;
       HashTable *BC = stmt->bound_columns;
       HashTable *BP = stmt->bound_params;

       int i;

       if (S->stmt) {
              /* cancel server side resources for the statement if we didn't
               * fetch it all */
              OCIStmtFetch(S->stmt, S->err, 0, OCI_FETCH_NEXT, OCI_DEFAULT);

              /* free the handle */
              OCIHandleFree(S->stmt, OCI_HTYPE_STMT);
              S->stmt = NULL;
       }
       if (S->err) {
              OCIHandleFree(S->err, OCI_HTYPE_ERROR);
              S->err = NULL;
       }

       /* need to ensure these go away now */
       if (BC) {
              zend_hash_destroy(BC);
              FREE_HASHTABLE(stmt->bound_columns);
              stmt->bound_columns = NULL;
       }

       if (BP) {
              zend_hash_destroy(BP);
              FREE_HASHTABLE(stmt->bound_params);
              stmt->bound_params = NULL;
       }

       if (S->einfo.errmsg) {
              pefree(S->einfo.errmsg, stmt->dbh->is_persistent);
              S->einfo.errmsg = NULL;
       }

       if (S->cols) {
              for (i = 0; i < stmt->column_count; i++) {
                     if (S->cols[i].data) {
                            switch (S->cols[i].dtype) {
                                   case SQLT_BLOB:
                                   case SQLT_CLOB:
                                          /* do nothing */
                                          break;
                                   default:
                                          efree(S->cols[i].data);
                            }
                     }
              }
              efree(S->cols);
              S->cols = NULL;
       }
       efree(S);

       stmt->driver_data = NULL;

       return 1;
} /* }}} */

Here is the call graph for this function:

static int oci_stmt_execute ( pdo_stmt_t *stmt  TSRMLS_DC) [static]

Definition at line 119 of file oci_statement.c.

{
       pdo_oci_stmt *S = (pdo_oci_stmt*)stmt->driver_data;
       ub4 rowcount;
       b4 mode;

       if (!S->stmt_type) {
              STMT_CALL_MSG(OCIAttrGet, "OCI_ATTR_STMT_TYPE",
                            (S->stmt, OCI_HTYPE_STMT, &S->stmt_type, 0, OCI_ATTR_STMT_TYPE, S->err));
       }

       if (stmt->executed) {
              /* ensure that we cancel the cursor from a previous fetch */
              OCIStmtFetch(S->stmt, S->err, 0, OCI_FETCH_NEXT, OCI_DEFAULT);
       }

#ifdef OCI_STMT_SCROLLABLE_READONLY /* needed for oci8 ? */
       if (S->exec_type == OCI_STMT_SCROLLABLE_READONLY) {
              mode = OCI_STMT_SCROLLABLE_READONLY;
       } else
#endif
       if (stmt->dbh->auto_commit && !stmt->dbh->in_txn) {
              mode = OCI_COMMIT_ON_SUCCESS;
       } else {
              mode = OCI_DEFAULT;
       }

       STMT_CALL(OCIStmtExecute, (S->H->svc, S->stmt, S->err,
                            (S->stmt_type == OCI_STMT_SELECT && !S->have_blobs) ? 0 : 1, 0, NULL, NULL,
                            mode));

       if (!stmt->executed) {
              ub4 colcount;
              /* do first-time-only definition of bind/mapping stuff */

              /* how many columns do we have ? */
              STMT_CALL_MSG(OCIAttrGet, "ATTR_PARAM_COUNT",
                            (S->stmt, OCI_HTYPE_STMT, &colcount, 0, OCI_ATTR_PARAM_COUNT, S->err));

              stmt->column_count = (int)colcount;

              if (S->cols) {
                     int i;
                     for (i = 0; i < stmt->column_count; i++) {
                            if (S->cols[i].data) {
                                   switch (S->cols[i].dtype) {
                                          case SQLT_BLOB:
                                          case SQLT_CLOB:
                                                 /* do nothing */
                                                 break;
                                          default:
                                                 efree(S->cols[i].data);
                                   }
                            }
                     }
                     efree(S->cols);
              }

              S->cols = ecalloc(colcount, sizeof(pdo_oci_column));
       }

       STMT_CALL_MSG(OCIAttrGet, "ATTR_ROW_COUNT",
                     (S->stmt, OCI_HTYPE_STMT, &rowcount, 0, OCI_ATTR_ROW_COUNT, S->err));
       stmt->row_count = (long)rowcount;

       return 1;
} /* }}} */
static int oci_stmt_fetch ( pdo_stmt_t *  stmt,
enum pdo_fetch_orientation  ori,
long offset  TSRMLS_DC 
) [static]

Definition at line 434 of file oci_statement.c.

{
#if HAVE_OCISTMTFETCH2
       ub4 ociori;
#endif
       pdo_oci_stmt *S = (pdo_oci_stmt*)stmt->driver_data;

#if HAVE_OCISTMTFETCH2
       switch (ori) {
              case PDO_FETCH_ORI_NEXT:    ociori = OCI_FETCH_NEXT; break;
              case PDO_FETCH_ORI_PRIOR:   ociori = OCI_FETCH_PRIOR; break;
              case PDO_FETCH_ORI_FIRST:   ociori = OCI_FETCH_FIRST; break;
              case PDO_FETCH_ORI_LAST:    ociori = OCI_FETCH_LAST; break;
              case PDO_FETCH_ORI_ABS:            ociori = OCI_FETCH_ABSOLUTE; break;
              case PDO_FETCH_ORI_REL:            ociori = OCI_FETCH_RELATIVE; break;
       }
       S->last_err = OCIStmtFetch2(S->stmt, S->err, 1, ociori, offset, OCI_DEFAULT);
#else
       S->last_err = OCIStmtFetch(S->stmt, S->err, 1, OCI_FETCH_NEXT, OCI_DEFAULT);
#endif

       if (S->last_err == OCI_NO_DATA) {
              /* no (more) data */
              return 0;
       }

       if (S->last_err == OCI_NEED_DATA) {
              oci_stmt_error("OCI_NEED_DATA");
              return 0;
       }

       if (S->last_err == OCI_SUCCESS_WITH_INFO || S->last_err == OCI_SUCCESS) {
              return 1;
       }

       oci_stmt_error("OCIStmtFetch");

       return 0;
} /* }}} */

Here is the call graph for this function:

static int oci_stmt_get_col ( pdo_stmt_t *  stmt,
int  colno,
char **  ptr,
unsigned long *  len,
int *caller_frees  TSRMLS_DC 
) [static]

Definition at line 716 of file oci_statement.c.

{
       pdo_oci_stmt *S = (pdo_oci_stmt*)stmt->driver_data;
       pdo_oci_column *C = &S->cols[colno];

       /* check the indicator to ensure that the data is intact */
       if (C->indicator == -1) {
              /* A NULL value */
              *ptr = NULL;
              *len = 0;
              return 1;
       } else if (C->indicator == 0) {
              /* it was stored perfectly */

              if (C->dtype == SQLT_BLOB || C->dtype == SQLT_CLOB) {
                     if (C->data) {
                            *ptr = (char*)oci_create_lob_stream(stmt, (OCILobLocator*)C->data TSRMLS_CC);
                            OCILobOpen(S->H->svc, S->err, (OCILobLocator*)C->data, OCI_LOB_READONLY);
                     }
                     *len = 0;
                     return *ptr ? 1 : 0;
              }

              *ptr = C->data;
              *len = C->fetched_len;
              return 1;
       } else {
              /* it was truncated */
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "column %d data was too large for buffer and was truncated to fit it", colno);

              *ptr = C->data;
              *len = C->fetched_len;
              return 1;
       }
} /* }}} */

Here is the call graph for this function:

static int oci_stmt_param_hook ( pdo_stmt_t *  stmt,
struct pdo_bound_param_data param,
enum pdo_param_event event_type  TSRMLS_DC 
) [static]

Definition at line 261 of file oci_statement.c.

{
       pdo_oci_stmt *S = (pdo_oci_stmt*)stmt->driver_data;

       /* we're only interested in parameters for prepared SQL right now */
       if (param->is_param) {
              pdo_oci_bound_param *P;
              sb4 value_sz = -1;

              P = (pdo_oci_bound_param*)param->driver_data;

              switch (event_type) {
                     case PDO_PARAM_EVT_FREE:
                            P = param->driver_data;
                            if (P) {
                                   efree(P);
                            }
                            break;

                     case PDO_PARAM_EVT_ALLOC:
                            P = (pdo_oci_bound_param*)ecalloc(1, sizeof(pdo_oci_bound_param));
                            param->driver_data = P;

                            /* figure out what we're doing */
                            switch (PDO_PARAM_TYPE(param->param_type)) {
                                   case PDO_PARAM_STMT:
                                          return 0;

                                   case PDO_PARAM_LOB:
                                          /* P->thing is now an OCILobLocator * */
                                          P->oci_type = SQLT_BLOB;
                                          value_sz = sizeof(OCILobLocator*);
                                          break;

                                   case PDO_PARAM_STR:
                                   default:
                                          P->oci_type = SQLT_CHR;
                                          value_sz = param->max_value_len;
                                          if (param->max_value_len == 0) {
                                                 value_sz = 1332; /* maximum size before value is interpreted as a LONG value */
                                          }

                            }

                            if (param->name) {
                                   STMT_CALL(OCIBindByName, (S->stmt,
                                                 &P->bind, S->err, (text*)param->name,
                                                 param->namelen, 0, value_sz, P->oci_type,
                                                 &P->indicator, 0, &P->retcode, 0, 0,
                                                 OCI_DATA_AT_EXEC));
                            } else {
                                   STMT_CALL(OCIBindByPos, (S->stmt,
                                                 &P->bind, S->err, param->paramno+1,
                                                 0, value_sz, P->oci_type,
                                                 &P->indicator, 0, &P->retcode, 0, 0,
                                                 OCI_DATA_AT_EXEC));
                            }

                            STMT_CALL(OCIBindDynamic, (P->bind,
                                                 S->err,
                                                 param, oci_bind_input_cb,
                                                 param, oci_bind_output_cb));

                            return 1;

                     case PDO_PARAM_EVT_EXEC_PRE:
                            P->indicator = 0;
                            P->used_for_output = 0;
                            if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB) {
                                   ub4 empty = 0;
                                   STMT_CALL(OCIDescriptorAlloc, (S->H->env, &P->thing, OCI_DTYPE_LOB, 0, NULL));
                                   STMT_CALL(OCIAttrSet, (P->thing, OCI_DTYPE_LOB, &empty, 0, OCI_ATTR_LOBEMPTY, S->err));
                                   S->have_blobs = 1;
                            }
                            return 1;

                     case PDO_PARAM_EVT_EXEC_POST:
                            /* fixup stuff set in motion in oci_bind_output_cb */
                            if (P->used_for_output) {
                                   if (P->indicator == -1) {
                                          /* set up a NULL value */
                                          if (Z_TYPE_P(param->parameter) == IS_STRING
#if ZEND_EXTENSION_API_NO < 220040718
                                                        && Z_STRVAL_P(param->parameter) != empty_string
#endif
                                             ) {
                                                 /* OCI likes to stick non-terminated strings in things */
                                                 *Z_STRVAL_P(param->parameter) = '\0';
                                          }
                                          zval_dtor(param->parameter);
                                          ZVAL_NULL(param->parameter);
                                   } else if (Z_TYPE_P(param->parameter) == IS_STRING
#if ZEND_EXTENSION_API_NO < 220040718
                                                 && Z_STRVAL_P(param->parameter) != empty_string
#endif
                                                 ) {
                                          Z_STRLEN_P(param->parameter) = P->actual_len;
                                          Z_STRVAL_P(param->parameter) = erealloc(Z_STRVAL_P(param->parameter), P->actual_len+1);
                                          Z_STRVAL_P(param->parameter)[P->actual_len] = '\0';
                                   }
                            } else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB && P->thing) {
                                   php_stream *stm;

                                   if (Z_TYPE_P(param->parameter) == IS_NULL) {
                                          /* if the param is NULL, then we assume that they
                                           * wanted to bind a lob locator into it from the query
                                           * */

                                          stm = oci_create_lob_stream(stmt, (OCILobLocator*)P->thing TSRMLS_CC);
                                          if (stm) {
                                                 OCILobOpen(S->H->svc, S->err, (OCILobLocator*)P->thing, OCI_LOB_READWRITE);
                                                 php_stream_to_zval(stm, param->parameter);
                                                 P->thing = NULL;
                                          }
                                   } else {
                                          /* we're a LOB being used for insert; transfer the data now */
                                          size_t n;
                                          ub4 amt, offset = 1;
                                          char *consume;

                                          php_stream_from_zval_no_verify(stm, &param->parameter);
                                          if (stm) {
                                                 OCILobOpen(S->H->svc, S->err, (OCILobLocator*)P->thing, OCI_LOB_READWRITE);
                                                 do {
                                                        char buf[8192];
                                                        n = php_stream_read(stm, buf, sizeof(buf));
                                                        if ((int)n <= 0) {
                                                               break;
                                                        }
                                                        consume = buf;
                                                        do {
                                                               amt = n;
                                                               OCILobWrite(S->H->svc, S->err, (OCILobLocator*)P->thing,
                                                                             &amt, offset, consume, n,
                                                                             OCI_ONE_PIECE,
                                                                             NULL, NULL, 0, SQLCS_IMPLICIT);
                                                               offset += amt;
                                                               n -= amt;
                                                               consume += amt;
                                                        } while (n);
                                                 } while (1);
                                                 OCILobClose(S->H->svc, S->err, (OCILobLocator*)P->thing);
                                                 OCILobFlushBuffer(S->H->svc, S->err, (OCILobLocator*)P->thing, 0);
                                          } else if (Z_TYPE_P(param->parameter) == IS_STRING) {
                                                 /* stick the string into the LOB */
                                                 consume = Z_STRVAL_P(param->parameter);
                                                 n = Z_STRLEN_P(param->parameter);
                                                 if (n) {
                                                        OCILobOpen(S->H->svc, S->err, (OCILobLocator*)P->thing, OCI_LOB_READWRITE);
                                                        while (n) {
                                                               amt = n;
                                                               OCILobWrite(S->H->svc, S->err, (OCILobLocator*)P->thing,
                                                                             &amt, offset, consume, n,
                                                                             OCI_ONE_PIECE,
                                                                             NULL, NULL, 0, SQLCS_IMPLICIT);
                                                               consume += amt;
                                                               n -= amt;
                                                        }
                                                        OCILobClose(S->H->svc, S->err, (OCILobLocator*)P->thing);
                                                 }
                                          }
                                          OCIDescriptorFree(P->thing, OCI_DTYPE_LOB);
                                          P->thing = NULL;
                                   }
                            }

                            return 1;
              }
       }

       return 1;
} /* }}} */

Here is the call graph for this function:


Variable Documentation

Initial value:

Definition at line 684 of file oci_statement.c.