Linux ip-172-26-2-223 5.4.0-1018-aws #18-Ubuntu SMP Wed Jun 24 01:15:00 UTC 2020 x86_64
Apache
: 172.26.2.223 | : 3.138.105.128
Cant Read [ /etc/named.conf ]
8.1.13
www
www.github.com/MadExploits
Terminal
AUTO ROOT
Adminer
Backdoor Destroyer
Linux Exploit
Lock Shell
Lock File
Create User
CREATE RDP
PHP Mailer
BACKCONNECT
UNLOCK SHELL
HASH IDENTIFIER
CPANEL RESET
CREATE WP USER
BLACK DEFEND!
README
+ Create Folder
+ Create File
/
www /
server /
php /
80 /
src /
ext /
pdo_oci /
[ HOME SHELL ]
Name
Size
Permission
Action
tests
[ DIR ]
drwxr-xr-x
CREDITS
40
B
-rw-r--r--
config.m4
6.32
KB
-rw-r--r--
config.w32
1.45
KB
-rw-r--r--
oci_driver.c
22.64
KB
-rw-r--r--
oci_statement.c
27.33
KB
-rw-r--r--
pdo_oci.c
3.76
KB
-rw-r--r--
php_pdo_oci.h
1.38
KB
-rw-r--r--
php_pdo_oci_int.h
2.94
KB
-rw-r--r--
Delete
Unzip
Zip
${this.title}
Close
Code Editor : oci_statement.c
/* +----------------------------------------------------------------------+ | Copyright (c) The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Wez Furlong <wez@php.net> | +----------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #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" #define PDO_OCI_LOBMAXSIZE (4294967295UL) /* OCI_LOBMAXSIZE */ #define STMT_CALL(name, params) \ do { \ S->last_err = name params; \ S->last_err = _oci_error(S->err, stmt->dbh, stmt, #name, S->last_err, FALSE, __FILE__, __LINE__); \ if (S->last_err) { \ return 0; \ } \ } while(0) #define STMT_CALL_MSG(name, msg, params) \ do { \ S->last_err = name params; \ S->last_err = _oci_error(S->err, stmt->dbh, stmt, #name ": " #msg, S->last_err, FALSE, __FILE__, __LINE__); \ if (S->last_err) { \ return 0; \ } \ } while(0) static php_stream *oci_create_lob_stream(zval *dbh, pdo_stmt_t *stmt, OCILobLocator *lob); #define OCI_TEMPLOB_CLOSE(envhp, svchp, errhp, lob) \ do \ { \ boolean isTempLOB; \ OCILobIsTemporary(envhp, errhp, lob, &isTempLOB); \ if (isTempLOB) \ OCILobFreeTemporary(svchp, errhp, lob); \ } while(0) static int oci_stmt_dtor(pdo_stmt_t *stmt) /* {{{ */ { 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: OCI_TEMPLOB_CLOSE(S->H->env, S->H->svc, S->H->err, (OCILobLocator *) S->cols[i].data); OCIDescriptorFree(S->cols[i].data, OCI_DTYPE_LOB); break; default: efree(S->cols[i].data); } } } efree(S->cols); S->cols = NULL; } efree(S); stmt->driver_data = NULL; return 1; } /* }}} */ static int oci_stmt_execute(pdo_stmt_t *stmt) /* {{{ */ { 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 sb4 oci_bind_input_cb(dvoid *ctx, OCIBind *bindp, ub4 iter, ub4 index, dvoid **bufpp, ub4 *alenp, ub1 *piecep, dvoid **indpp) /* {{{ */ { struct pdo_bound_param_data *param = (struct pdo_bound_param_data*)ctx; pdo_oci_bound_param *P = (pdo_oci_bound_param*)param->driver_data; zval *parameter; ZEND_ASSERT(param); *indpp = &P->indicator; if (Z_ISREF(param->parameter)) parameter = Z_REFVAL(param->parameter); else parameter = ¶m->parameter; if (P->thing) { *bufpp = P->thing; *alenp = sizeof(void*); } else if (ZVAL_IS_NULL(parameter)) { /* insert a NULL value into the column */ P->indicator = -1; /* NULL */ *bufpp = 0; *alenp = -1; } else if (!P->thing) { /* regular string bind */ if (!try_convert_to_string(parameter)) { return OCI_ERROR; } *bufpp = Z_STRVAL_P(parameter); *alenp = (ub4) Z_STRLEN_P(parameter); } *piecep = OCI_ONE_PIECE; return OCI_CONTINUE; } /* }}} */ static sb4 oci_bind_output_cb(dvoid *ctx, OCIBind *bindp, ub4 iter, ub4 index, dvoid **bufpp, ub4 **alenpp, ub1 *piecep, dvoid **indpp, ub2 **rcodepp) /* {{{ */ { struct pdo_bound_param_data *param = (struct pdo_bound_param_data*)ctx; pdo_oci_bound_param *P = (pdo_oci_bound_param*)param->driver_data; zval *parameter; ZEND_ASSERT(param); if (Z_ISREF(param->parameter)) parameter = Z_REFVAL(param->parameter); else parameter = ¶m->parameter; 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(parameter) == IS_OBJECT || Z_TYPE_P(parameter) == IS_RESOURCE) { return OCI_CONTINUE; } zval_ptr_dtor(parameter); Z_STR_P(parameter) = zend_string_alloc(param->max_value_len, 1); P->used_for_output = 1; P->actual_len = (ub4) Z_STRLEN_P(parameter); *alenpp = &P->actual_len; *bufpp = (Z_STR_P(parameter))->val; *piecep = OCI_ONE_PIECE; *rcodepp = &P->retcode; *indpp = &P->indicator; return OCI_CONTINUE; } /* }}} */ static int oci_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param, enum pdo_param_event event_type) /* {{{ */ { 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; zval *parameter; if (Z_ISREF(param->parameter)) parameter = Z_REFVAL(param->parameter); else parameter = ¶m->parameter; P = (pdo_oci_bound_param*)param->driver_data; switch (event_type) { case PDO_PARAM_EVT_FETCH_PRE: case PDO_PARAM_EVT_FETCH_POST: case PDO_PARAM_EVT_NORMALIZE: /* Do nothing */ break; case PDO_PARAM_EVT_FREE: P = param->driver_data; if (P && P->thing) { OCI_TEMPLOB_CLOSE(S->H->env, S->H->svc, S->H->err, P->thing); OCIDescriptorFree(P->thing, OCI_DTYPE_LOB); P->thing = NULL; efree(P); } else 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 = (sb4) sizeof(OCILobLocator*); break; case PDO_PARAM_STR: default: P->oci_type = SQLT_CHR; value_sz = (sb4) param->max_value_len; if (param->max_value_len == 0) { value_sz = (sb4) 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->val, (sb4) param->name->len, 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, ((ub4)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(parameter) == IS_STRING) { /* OCI likes to stick non-terminated strings in things */ *Z_STRVAL_P(parameter) = '\0'; } zval_ptr_dtor_str(parameter); ZVAL_UNDEF(parameter); } else if (Z_TYPE_P(parameter) == IS_STRING) { Z_STR_P(parameter) = zend_string_init(Z_STRVAL_P(parameter), P->actual_len, 1); } } else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB && P->thing) { php_stream *stm; if (Z_TYPE_P(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->database_object_handle, stmt, (OCILobLocator*)P->thing); if (stm) { OCILobOpen(S->H->svc, S->err, (OCILobLocator*)P->thing, OCI_LOB_READWRITE); php_stream_to_zval(stm, parameter); } } 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, 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 = (ub4) n; OCILobWrite(S->H->svc, S->err, (OCILobLocator*)P->thing, &amt, offset, consume, (ub4) 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(parameter) == IS_STRING) { /* stick the string into the LOB */ consume = Z_STRVAL_P(parameter); n = Z_STRLEN_P(parameter); if (n) { OCILobOpen(S->H->svc, S->err, (OCILobLocator*)P->thing, OCI_LOB_READWRITE); while (n) { amt = (ub4) n; OCILobWrite(S->H->svc, S->err, (OCILobLocator*)P->thing, &amt, offset, consume, (ub4) n, OCI_ONE_PIECE, NULL, NULL, 0, SQLCS_IMPLICIT); consume += amt; n -= amt; } OCILobClose(S->H->svc, S->err, (OCILobLocator*)P->thing); } } OCI_TEMPLOB_CLOSE(S->H->env, S->H->svc, S->H->err, P->thing); OCIDescriptorFree(P->thing, OCI_DTYPE_LOB); P->thing = NULL; } } return 1; } } return 1; } /* }}} */ static int oci_stmt_fetch(pdo_stmt_t *stmt, enum pdo_fetch_orientation ori, zend_long offset) /* {{{ */ { #ifdef HAVE_OCISTMTFETCH2 ub4 ociori = OCI_FETCH_NEXT; #endif pdo_oci_stmt *S = (pdo_oci_stmt*)stmt->driver_data; #ifdef 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, (sb4) 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; } /* }}} */ static sb4 oci_define_callback(dvoid *octxp, OCIDefine *define, ub4 iter, dvoid **bufpp, ub4 **alenpp, ub1 *piecep, dvoid **indpp, ub2 **rcodepp) { pdo_oci_column *col = (pdo_oci_column*)octxp; switch (col->dtype) { case SQLT_BLOB: case SQLT_CLOB: *piecep = OCI_ONE_PIECE; *bufpp = col->data; *alenpp = &col->datalen; *indpp = (dvoid *)&col->indicator; break; EMPTY_SWITCH_DEFAULT_CASE(); } return OCI_CONTINUE; } static int oci_stmt_describe(pdo_stmt_t *stmt, int colno) /* {{{ */ { pdo_oci_stmt *S = (pdo_oci_stmt*)stmt->driver_data; OCIParam *param = NULL; text *colname; ub2 dtype, data_size, 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*)¶m, 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)); /* 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 = precis; col->maxlen = data_size; col->name = zend_string_init((char *)colname, namelen, 0); 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 if (dtype == SQLT_BIN) { S->cols[colno].datalen = (ub4) col->maxlen * 2; /* raw characters to hex digits */ } else { S->cols[colno].datalen = (ub4) (col->maxlen * S->H->max_char_width); } 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; } /* }}} */ struct _oci_lob_env { OCISvcCtx *svc; OCIError *err; }; typedef struct _oci_lob_env oci_lob_env; struct oci_lob_self { zval dbh; pdo_stmt_t *stmt; pdo_oci_stmt *S; OCILobLocator *lob; oci_lob_env *E; ub4 offset; }; static ssize_t oci_blob_write(php_stream *stream, const char *buf, size_t count) { struct oci_lob_self *self = (struct oci_lob_self*)stream->abstract; ub4 amt; sword r; amt = (ub4) count; r = OCILobWrite(self->E->svc, self->E->err, self->lob, &amt, self->offset, (char*)buf, (ub4) count, OCI_ONE_PIECE, NULL, NULL, 0, SQLCS_IMPLICIT); if (r != OCI_SUCCESS) { return (ssize_t)-1; } self->offset += amt; return amt; } static ssize_t oci_blob_read(php_stream *stream, char *buf, size_t count) { struct oci_lob_self *self = (struct oci_lob_self*)stream->abstract; ub4 amt; sword r; amt = (ub4) count; r = OCILobRead(self->E->svc, self->E->err, self->lob, &amt, self->offset, buf, (ub4) 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_close(php_stream *stream, int close_handle) { struct oci_lob_self *self = (struct oci_lob_self *)stream->abstract; pdo_stmt_t *stmt = self->stmt; if (close_handle) { zend_object *obj = &stmt->std; OCILobClose(self->E->svc, self->E->err, self->lob); zval_ptr_dtor(&self->dbh); GC_DELREF(obj); efree(self->E); efree(self); } /* php_pdo_free_statement(stmt); */ return 0; } static int oci_blob_flush(php_stream *stream) { struct oci_lob_self *self = (struct oci_lob_self*)stream->abstract; OCILobFlushBuffer(self->E->svc, self->E->err, self->lob, 0); return 0; } static int oci_blob_seek(php_stream *stream, zend_off_t offset, int whence, zend_off_t *newoffset) { struct oci_lob_self *self = (struct oci_lob_self*)stream->abstract; if (offset >= PDO_OCI_LOBMAXSIZE) { return -1; } else { self->offset = (ub4) offset + 1; /* Oracle LOBS are 1-based, but PHP is 0-based */ return 0; } } static const php_stream_ops oci_blob_stream_ops = { oci_blob_write, oci_blob_read, oci_blob_close, oci_blob_flush, "pdo_oci blob stream", oci_blob_seek, NULL, NULL, NULL }; static php_stream *oci_create_lob_stream(zval *dbh, pdo_stmt_t *stmt, OCILobLocator *lob) { php_stream *stm; struct oci_lob_self *self = ecalloc(1, sizeof(*self)); ZVAL_COPY_VALUE(&self->dbh, dbh); self->lob = lob; self->offset = 1; /* 1-based */ self->stmt = stmt; self->S = (pdo_oci_stmt*)stmt->driver_data; self->E = ecalloc(1, sizeof(oci_lob_env)); self->E->svc = self->S->H->svc; self->E->err = self->S->err; stm = php_stream_alloc(&oci_blob_stream_ops, self, 0, "r+b"); if (stm) { zend_object *obj; obj = &stmt->std; Z_ADDREF(self->dbh); GC_ADDREF(obj); return stm; } efree(self); return NULL; } static int oci_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, size_t *len, int *caller_frees) /* {{{ */ { 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->database_object_handle, stmt, (OCILobLocator*)C->data); OCILobOpen(S->H->svc, S->err, (OCILobLocator*)C->data, OCI_LOB_READONLY); } *len = (size_t) 0; return *ptr ? 1 : 0; } *ptr = C->data; *len = (size_t) C->fetched_len; return 1; } else { /* it was truncated */ php_error_docref(NULL, E_WARNING, "Column %d data was too large for buffer and was truncated to fit it", colno); *ptr = C->data; *len = (size_t) C->fetched_len; return 1; } } /* }}} */ static int oci_stmt_col_meta(pdo_stmt_t *stmt, zend_long colno, zval *return_value) /* {{{ */ { pdo_oci_stmt *S = (pdo_oci_stmt*)stmt->driver_data; OCIParam *param = NULL; ub2 dtype, precis; sb1 scale; zval flags; ub1 isnull, charset_form; if (!S->stmt) { return FAILURE; } if (colno >= stmt->column_count) { /* error invalid column */ return FAILURE; } array_init(return_value); array_init(&flags); /* describe the column */ STMT_CALL(OCIParamGet, (S->stmt, OCI_HTYPE_STMT, S->err, (dvoid*)¶m, colno+1)); /* column data type */ STMT_CALL_MSG(OCIAttrGet, "OCI_ATTR_DATA_TYPE", (param, OCI_DTYPE_PARAM, &dtype, 0, OCI_ATTR_DATA_TYPE, S->err)); /* column precision */ STMT_CALL_MSG(OCIAttrGet, "OCI_ATTR_PRECISION", (param, OCI_DTYPE_PARAM, &precis, 0, OCI_ATTR_PRECISION, S->err)); /* column scale */ STMT_CALL_MSG(OCIAttrGet, "OCI_ATTR_SCALE", (param, OCI_DTYPE_PARAM, &scale, 0, OCI_ATTR_SCALE, S->err)); /* string column charset form */ if (dtype == SQLT_CHR || dtype == SQLT_VCS || dtype == SQLT_AFC || dtype == SQLT_CLOB) { STMT_CALL_MSG(OCIAttrGet, "OCI_ATTR_CHARSET_FORM", (param, OCI_DTYPE_PARAM, &charset_form, 0, OCI_ATTR_CHARSET_FORM, S->err)); } if (dtype) { /* if there is a declared type */ switch (dtype) { #ifdef SQLT_TIMESTAMP case SQLT_TIMESTAMP: add_assoc_string(return_value, "oci:decl_type", "TIMESTAMP"); add_assoc_string(return_value, "native_type", "TIMESTAMP"); break; #endif #ifdef SQLT_TIMESTAMP_TZ case SQLT_TIMESTAMP_TZ: add_assoc_string(return_value, "oci:decl_type", "TIMESTAMP WITH TIMEZONE"); add_assoc_string(return_value, "native_type", "TIMESTAMP WITH TIMEZONE"); break; #endif #ifdef SQLT_TIMESTAMP_LTZ case SQLT_TIMESTAMP_LTZ: add_assoc_string(return_value, "oci:decl_type", "TIMESTAMP WITH LOCAL TIMEZONE"); add_assoc_string(return_value, "native_type", "TIMESTAMP WITH LOCAL TIMEZONE"); break; #endif #ifdef SQLT_INTERVAL_YM case SQLT_INTERVAL_YM: add_assoc_string(return_value, "oci:decl_type", "INTERVAL YEAR TO MONTH"); add_assoc_string(return_value, "native_type", "INTERVAL YEAR TO MONTH"); break; #endif #ifdef SQLT_INTERVAL_DS case SQLT_INTERVAL_DS: add_assoc_string(return_value, "oci:decl_type", "INTERVAL DAY TO SECOND"); add_assoc_string(return_value, "native_type", "INTERVAL DAY TO SECOND"); break; #endif case SQLT_DAT: add_assoc_string(return_value, "oci:decl_type", "DATE"); add_assoc_string(return_value, "native_type", "DATE"); break; case SQLT_FLT : case SQLT_NUM: /* if the precision is nonzero and scale is -127 then it is a FLOAT */ if (scale == -127 && precis != 0) { add_assoc_string(return_value, "oci:decl_type", "FLOAT"); add_assoc_string(return_value, "native_type", "FLOAT"); } else { add_assoc_string(return_value, "oci:decl_type", "NUMBER"); add_assoc_string(return_value, "native_type", "NUMBER"); } break; case SQLT_LNG: add_assoc_string(return_value, "oci:decl_type", "LONG"); add_assoc_string(return_value, "native_type", "LONG"); break; case SQLT_BIN: add_assoc_string(return_value, "oci:decl_type", "RAW"); add_assoc_string(return_value, "native_type", "RAW"); break; case SQLT_LBI: add_assoc_string(return_value, "oci:decl_type", "LONG RAW"); add_assoc_string(return_value, "native_type", "LONG RAW"); break; case SQLT_CHR: case SQLT_VCS: if (charset_form == SQLCS_NCHAR) { add_assoc_string(return_value, "oci:decl_type", "NVARCHAR2"); add_assoc_string(return_value, "native_type", "NVARCHAR2"); } else { add_assoc_string(return_value, "oci:decl_type", "VARCHAR2"); add_assoc_string(return_value, "native_type", "VARCHAR2"); } break; case SQLT_AFC: if (charset_form == SQLCS_NCHAR) { add_assoc_string(return_value, "oci:decl_type", "NCHAR"); add_assoc_string(return_value, "native_type", "NCHAR"); } else { add_assoc_string(return_value, "oci:decl_type", "CHAR"); add_assoc_string(return_value, "native_type", "CHAR"); } break; case SQLT_BLOB: add_assoc_string(return_value, "oci:decl_type", "BLOB"); add_next_index_string(&flags, "blob"); add_assoc_string(return_value, "native_type", "BLOB"); break; case SQLT_CLOB: if (charset_form == SQLCS_NCHAR) { add_assoc_string(return_value, "oci:decl_type", "NCLOB"); add_assoc_string(return_value, "native_type", "NCLOB"); } else { add_assoc_string(return_value, "oci:decl_type", "CLOB"); add_assoc_string(return_value, "native_type", "CLOB"); } add_next_index_string(&flags, "blob"); break; case SQLT_BFILE: add_assoc_string(return_value, "oci:decl_type", "BFILE"); add_next_index_string(&flags, "blob"); add_assoc_string(return_value, "native_type", "BFILE"); break; case SQLT_RDD: add_assoc_string(return_value, "oci:decl_type", "ROWID"); add_assoc_string(return_value, "native_type", "ROWID"); break; case SQLT_BFLOAT: case SQLT_IBFLOAT: add_assoc_string(return_value, "oci:decl_type", "BINARY_FLOAT"); add_assoc_string(return_value, "native_type", "BINARY_FLOAT"); break; case SQLT_BDOUBLE: case SQLT_IBDOUBLE: add_assoc_string(return_value, "oci:decl_type", "BINARY_DOUBLE"); add_assoc_string(return_value, "native_type", "BINARY_DOUBLE"); break; default: add_assoc_long(return_value, "oci:decl_type", dtype); add_assoc_string(return_value, "native_type", "UNKNOWN"); } } else { /* if the column is NULL */ add_assoc_long(return_value, "oci:decl_type", 0); add_assoc_string(return_value, "native_type", "NULL"); } /* column can be null */ STMT_CALL_MSG(OCIAttrGet, "OCI_ATTR_IS_NULL", (param, OCI_DTYPE_PARAM, &isnull, 0, OCI_ATTR_IS_NULL, S->err)); if (isnull) { add_next_index_string(&flags, "nullable"); } else { add_next_index_string(&flags, "not_null"); } /* PDO type */ switch (dtype) { case SQLT_BFILE: case SQLT_BLOB: case SQLT_CLOB: add_assoc_long(return_value, "pdo_type", PDO_PARAM_LOB); break; default: add_assoc_long(return_value, "pdo_type", PDO_PARAM_STR); } add_assoc_long(return_value, "scale", scale); add_assoc_zval(return_value, "flags", &flags); OCIDescriptorFree(param, OCI_DTYPE_PARAM); return SUCCESS; } /* }}} */ const struct pdo_stmt_methods oci_stmt_methods = { oci_stmt_dtor, oci_stmt_execute, oci_stmt_fetch, oci_stmt_describe, oci_stmt_get_col, oci_stmt_param_hook, NULL, /* set_attr */ NULL, /* get_attr */ oci_stmt_col_meta, NULL, NULL };
Close