/* {{{ proto string ora_error(int cursor_or_connection) Get an Oracle error message */ void php3_Ora_Error(INTERNAL_FUNCTION_PARAMETERS) { pval *arg; oraCursor *cursor; oraConnection *conn; int argc = ARG_COUNT(ht); if (argc < 0 || argc > 1 || getParametersArray(ht, argc, &arg) == FAILURE) { WRONG_PARAM_COUNT; } if (argc == 1) { convert_to_long(arg); if ((cursor = ora_get_cursor(list, arg->value.lval)) != NULL) { return_value->type = IS_STRING; return_value->value.str.val = estrdup(ora_error(&cursor->cda)); return_value->value.str.len = strlen(return_value->value.str.val); } else if ((conn = ora_get_conn(list,plist, arg->value.lval)) != NULL) { return_value->type = IS_STRING; return_value->value.str.val = estrdup(ora_error(&conn->lda)); return_value->value.str.len = strlen(return_value->value.str.val); } } else { return_value->type = IS_STRING; return_value->value.str.val = estrdup(ora_error(&db_err_conn.lda)); return_value->value.str.len = strlen(return_value->value.str.val); } }
// После фетча - перекодируем date и выкачиваем blob.s int ora_fetch(database *db) { t_ora *o = db->h; int i; db_col *c; //printf("Here fetch!"); getch(); if (!o) return ora_error(db); //printf("Try real fetch!, OCI_NO_DATA=%d",OCI_NO_DATA); getch(); if (++o->rownum>1) i = OCIStmtFetch( o->stmt, o->errhp, (ub4) 1, (ub4) OCI_FETCH_NEXT, (ub4) OCI_DEFAULT); else i=db->err_code; // Первый фетч делает сам Оракл... //printf("Returns code=%d... Try real fetch!",i); getch(); db->err_code = 0; // Clear last error code... if (i == OCI_NO_DATA ) { ora_error(db); db->err_code = 0; return 0; } if (!ora_ok(i)) return ora_error(db); debugf(" ..ora10 start fetch ...\n"); for(i = db->out.count-1, c = db->out.cols;i>=0; i--, c++) { c->null=(((short)c->null)!=0); // Перекодировка флажков is_null.. //if(!c->null) if(c->type==dbDate) { unsigned char *D=(void*)c->dbvalue; if (c->null) *(double*)c->value=0; else *(double*)c->value=dt_encode((D[0]-100)*100+(D[1]-100), D[2],D[3],D[4]-1,D[5]-1,D[6]-1); } else if (c->type==dbBlob) // Вытягиваем блобу... { db_blob_handle *b=(void*)c->value; // Это указатель на "вытащенный блоб", его нужно установить на... int cnt_read = 0, offset = 0, blob_length = 0; debugf(" ..ora10 download blob to handle=%d\n",b); if (c->null) { b->len=0; continue;} if (OCI_SUCCESS!=OCILobGetLength (o->svchp,o->errhp,o->blob_read, &blob_length)) return ora_error(db); // - Сюда сливаются БЛОБЫ от SELCETA -- db->out.blob,&db->out.bsize,&db->out.blen if (blob_length +1 >= db->out.bsize) { int sz = blob_length+1024; // Новая длина void *p; // Еще место нужно... Realloc... debugf(" ..ora10 blob size=%d\n",sz); db->out.bsize = sz; p = realloc(db->out.blob,db->out.bsize); // Думаем что памяти достаточно if (!p) { sprintf(db->error,"vdb - no memory"); db->err_code = -2; return 0; } db->out.blob = p ; } debugf(" .. ora Ok - begin read\n"); if (OCI_SUCCESS!=OCILobRead(o->svchp,o->errhp,o->blob_read, // Интересно, такое бывает? &cnt_read, 1, db->out.blob, db->out.bsize, 0, 0 csid_csfrm)) return ora_error(db); debugf(" .. ora ReadDone, no error cnt_read=%d\n",cnt_read); db->out.blen = cnt_read+1; // Zero termanited на всякий случай... // Корректируем указатель, т.к. блоб мог реаллокнуться.. debugf(" .. ora Setb->data\n"); b->data = db->out.blob; // Все заточено под один БЛОБ b->len = cnt_read; b->data[b->len] = 0; // Терминирование нулем - вещь полезная... debugf(" ora OK flashed to bh=%d- do it again\n",b); } } debugf(" ..ora - FetchDone OK\n"); return 1; }
// "Подготовка" (compile, parsing, preparing) SQL для выполнения по exec... int ora_compile(database *db, char *sql) { t_ora *o = db->h; if (!o) return ora_error(db); db->err_code = 0; o->execnum = 0; db->in.count = 0; // Все почистили... if (strncmp(sql,"vovka",5)==0) { in_command(sql+5,db->error); return 0; } //OCILobTrim(o->svchp, o->errhp, o->blob,0); if (!ora_ok(OCIStmtPrepare(o->stmt, o->errhp, (text *) sql, (ub4) strlen(sql), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT))) return ora_error(db); return 1; }
/* {{{ proto int ora_open(int connection) Open an Oracle cursor */ void php3_Ora_Open(INTERNAL_FUNCTION_PARAMETERS) { /* conn_index */ pval *arg; oraConnection *conn = NULL; oraCursor *cursor = NULL; int conn_ind; if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_long(arg); conn_ind = arg->value.lval; conn = ora_get_conn(list,plist, conn_ind); if (conn == NULL) { RETURN_FALSE; } if ((cursor = (oraCursor *)emalloc(sizeof(oraCursor))) == NULL){ php3_error(E_WARNING, "Out of memory"); RETURN_FALSE; } memset(cursor, 0, sizeof(oraCursor)); if (oopen(&cursor->cda, &conn->lda, (text *) 0, -1, -1, (text *) 0, -1)) { php3_error(E_WARNING, "Unable to open new cursor (%s)", ora_error(&cursor->cda)); efree(cursor); RETURN_FALSE; } cursor->open = 1; cursor->conn_ptr = conn; cursor->conn_id = conn_ind; RETURN_RESOURCE(ora_add_cursor(list, cursor)); }
/* {{{ proto int ora_fetch(int cursor) Fetch a row of result data from a cursor */ void php3_Ora_Fetch(INTERNAL_FUNCTION_PARAMETERS) { /* cursor_index */ pval *arg; oraCursor *cursor; if (getParameters(ht, 1, &arg) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_long(arg); /* Find the cursor */ if ((cursor = ora_get_cursor(list, arg->value.lval)) == NULL) { RETURN_FALSE; } if (cursor->ncols == 0){ php3_error(E_WARNING, "No tuples available on this cursor"); RETURN_FALSE; } /* Get data from Oracle */ if (ofetch(&cursor->cda)) { if (cursor->cda.rc != NO_DATA_FOUND) { php3_error(E_WARNING, "Ora_Fetch failed (%s)", ora_error(&cursor->cda)); } RETURN_FALSE; } cursor->fetched++; RETVAL_TRUE; }
/* {{{ proto int ora_parse(int cursor, string sql_statement [, int defer]) Parse an Oracle SQL statement */ void php3_Ora_Parse(INTERNAL_FUNCTION_PARAMETERS) { /* cursor_ind, sql_statement [, defer] */ int argc; pval *argv[3]; oraCursor *cursor; sword defer = 0; text *query; argc = ARG_COUNT(ht); if ((argc != 2 && argc != 3) || getParametersArray(ht, argc, argv) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_long(argv[0]); convert_to_string(argv[1]); if (argc == 3) { convert_to_long(argv[2]); if (argv[2]->value.lval != 0) { defer = DEFER_PARSE; } } query = (text *) estrndup(argv[1]->value.str.val,argv[1]->value.str.len); if (query == NULL) { php3_error(E_WARNING, "Invalid query"); RETURN_FALSE; } if (!(cursor = ora_get_cursor(list, argv[0]->value.lval))){ efree(query); RETURN_FALSE; } if (cursor->query) { efree(cursor->query); } cursor->query = query; cursor->fetched = 0; if(cursor->params && cursor->nparams > 0){ _php3_hash_destroy(cursor->params); efree(cursor->params); cursor->params = NULL; cursor->nparams = 0; } if (oparse(&cursor->cda, query, (sb4) - 1, defer, VERSION_7)) { php3_error(E_WARNING, "Ora_Parse failed (%s)", ora_error(&cursor->cda)); RETURN_FALSE; } RETURN_TRUE; }
// Все делается перед первым exec. Этот bind только запоминает имена переменных int ora_bind(database *db, char *name, int type, int *ind, void *val, int len) { db_col *c; int ptype = type; t_ora *o = db->h; type = ptype&0xFF; // Игнорируем флаги if (!o) return ora_error(db); // Если еще нет оракла... c=db_add_col(&db->in,name,type,len); if (!c) return 0; // No memory ??? c->dbflag = ptype>>16; //printf("col=%s db_flag=%d\n",c->name,c->dbflag); //c->null=(int)ind; c->value=val; c->null = 0; // Не нулевое значение указателя db->in.p=(void*)1; return 1; }
/* {{{ proto int ora_rollback(int connection) Roll back an Oracle transaction */ void php3_Ora_Rollback(INTERNAL_FUNCTION_PARAMETERS) { /* conn_index */ pval *arg; oraConnection *conn; if (getParameters(ht, 1, &arg) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_long(arg); conn = ora_get_conn(list,plist, arg->value.lval); if (conn == NULL) { RETURN_FALSE; } if (orol(&conn->lda)) { php3_error(E_WARNING, "Unable to roll back transaction (%s)", ora_error(&conn->lda)); RETURN_FALSE; } RETVAL_TRUE; }
/* {{{ proto int ora_commiton(int connection) Enable automatic commit */ void php3_Ora_CommitOn(INTERNAL_FUNCTION_PARAMETERS) { /* conn_index */ pval *arg; oraConnection *conn; if (getParameters(ht, 1, &arg) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_long(arg); if (!(conn = ora_get_conn(list,plist, arg->value.lval))) { RETURN_FALSE; } if (ocon(&conn->lda)) { php3_error(E_WARNING, "Unable to turn on auto-commit (%s)", ora_error(&conn->lda)); RETURN_FALSE; } RETURN_TRUE; }
/* {{{ proto int ora_exec(int cursor) Execute a parsed statement */ void php3_Ora_Exec(INTERNAL_FUNCTION_PARAMETERS) { /* cursor_index */ pval *arg; oraCursor *cursor = NULL; if (getParameters(ht, 1, &arg) == FAILURE) WRONG_PARAM_COUNT; convert_to_long(arg); if ((cursor = ora_get_cursor(list, arg->value.lval)) == NULL) { RETURN_FALSE; } if (cursor->cda.ft == FT_SELECT) { if (ora_describe_define(cursor) < 0) { /* error message is given by ora_describe_define() */ RETURN_FALSE; } } if(cursor->nparams > 0){ if(!ora_set_param_values(cursor, 0)){ RETURN_FALSE; } } if (oexec(&cursor->cda)) { php3_error(E_WARNING, "Ora_Exec failed (%s)", ora_error(&cursor->cda)); RETURN_FALSE; } if(cursor->nparams > 0){ if(!ora_set_param_values(cursor, 1)){ RETURN_FALSE; } } RETURN_TRUE; }
int _ora_connect(database *db,char *srvname,char *username,char *password) { t_ora * o; void *p; //printf("Connecting???\n"); // Создаем симпле-ора, ошибки памяти не проверяем... o = malloc( sizeof(t_ora) ); if (!o) { sprintf(db->error,"vora - no memory"); return 0;} memset(o,0,sizeof(t_ora)); db->h = o; db->disconnect = ora_disconnect; db->compile = ora_compile; db->exec = ora_exec; db->commit = ora_commit; db->rollback = ora_rollback; db->open = ora_open; db->fetch = ora_fetch; db->bind = ora_bind; o->envhp=env; // Copy It // Инициализиреум envhp - "сессионный набор" (для дальнейшего ЮЗА) OCIEnvInit( (OCIEnv **) &o->envhp, OCI_DEFAULT, (size_t) 0,(dvoid **) 0 ); debugf(" ..try connect to oracle {user:'******',pass:'******',server:'%s',env:0x%p}\n",username,password,srvname,o->envhp); // Инитим обьект типа ошибка Оракл OCIHandleAlloc( (dvoid *) o->envhp, (dvoid **) &o->errhp, OCI_HTYPE_ERROR,(size_t) 0, (dvoid **) 0); debugf(".. OCIHandleAlloc errhp:0x%p\n", o->errhp); //printf("ErrHP=%d\n",o->errhp); // Инитим "серверОракл" OCIHandleAlloc( (dvoid *) o->envhp, (dvoid **) &o->srvhp, OCI_HTYPE_SERVER,(size_t) 0, (dvoid **) 0); debugf(".. OCUHandleAlloc srvhp:0x%p, attaching\n", o->srvhp); // Следующие две команды совершенно непонятны... if (OCI_SUCCESS!=OCIServerAttach( o->srvhp, o->errhp, (text *)srvname, strlen(srvname), OCI_DEFAULT)) { debugf(" -- failed Server Attach"); ora_error(db); ora_disconnect(db); return 0; } debugf(".. Server Attached... srvhp:0x%p\n", o->srvhp); //return ora_disconnect(db); OCIHandleAlloc( (dvoid *) o->envhp, (dvoid **) &o->svchp, OCI_HTYPE_SVCCTX,(size_t) 0, (dvoid **) 0); // Забираем с сервера настройки для нашей сессии OCIAttrSet( (dvoid *) o->svchp, OCI_HTYPE_SVCCTX, (dvoid *)o->srvhp,(ub4) 0, OCI_ATTR_SERVER, (OCIError *) o->errhp); // Создаем обьет "авторизованность" OCIHandleAlloc((dvoid *) o->envhp, (dvoid **)&o->authp,(ub4) OCI_HTYPE_SESSION, (size_t) 0, (dvoid **) 0); // Записыавем имя пользователя OCIAttrSet((dvoid *) o->authp, (ub4) OCI_HTYPE_SESSION,(dvoid *) username, (ub4) strlen((char *)username), (ub4) OCI_ATTR_USERNAME, o->errhp); // Записываем пароль OCIAttrSet((dvoid *) o->authp, (ub4) OCI_HTYPE_SESSION, (dvoid *) password, (ub4) strlen((char *)password), (ub4) OCI_ATTR_PASSWORD, o->errhp); // Compile statement... OCIHandleAlloc( (dvoid *) o->envhp, (dvoid **) &o->stmt, OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0); // Это для получения "describe" от SELECT OCIHandleAlloc((dvoid *) o->envhp, (dvoid **) &o->dschp, (ub4) OCI_HTYPE_DESCRIBE,(size_t) 0, (dvoid **) 0); // Для блобчика готовим... OCIDescriptorAlloc((dvoid *) o->envhp, (dvoid **) &o->blob, (ub4) OCI_DTYPE_LOB, (size_t) 0, (dvoid **) 0); OCIAttrSet((dvoid *) o->blob, (ub4) OCI_DTYPE_LOB, 0,0, (ub4) OCI_ATTR_LOBEMPTY, o->errhp); //OCIDescriptorAlloc((dvoid *) o->envhp, (dvoid **) &o->blob_read, // (ub4) OCI_DTYPE_LOB, (size_t) 0, (dvoid **) 0); //OCIAttrSet((dvoid *) o->blob_read, (ub4) OCI_HTYPE_SESSION, // 0,0, (ub4) 0 /*OCI_ATTR_LOBEMPTY*/, o->errhp); debugf(" initing OCISessionBegin {svchp:%p,errhp:%p,authp:%p}\n",o->svchp,o->errhp,o->authp); if (OCI_SUCCESS!=OCISessionBegin (o->svchp,o->errhp,o->authp, OCI_CRED_RDBMS,(ub4) OCI_DEFAULT)) { ora_error(db); ora_disconnect(db); return 0; } debugf(" ora_session inited, set some attributes\n"); //return 1; // Его (blob) еще нужно создавать... интересно, что это за действо? //OCILobCreateTemporary(o->svchp,o->errhp,o->blob, // OCI_DEFAULT,OCI_DEFAULT,OCI_TEMP_BLOB,FALSE,OCI_DURATION_SESSION); //OCILobCreateTemporary(o->svchp,o->errhp,o->blob_read, // OCI_DEFAULT,OCI_DEFAULT,OCI_TEMP_BLOB,FALSE,OCI_DURATION_SESSION); // Нужное какое-то подсоединение... OCIAttrSet((dvoid *) o->svchp, (ub4) OCI_HTYPE_SVCCTX, (dvoid *) o->authp, (ub4) 0, (ub4) OCI_ATTR_SESSION, o->errhp); if (0) { // Как установить аттрибут??? ub1 yes = 1; int res; res = OCIAttrSet((dvoid *) o->stmt, (ub4) OCI_PTYPE_DATABASE, (dvoid *) &yes, (ub4) 1, (ub4) OCI_ATTR_AUTOCOMMIT_DDL, o->errhp); printf("\n ------------- Autocommit set result=%d, ok=%d\n",res, OCI_SUCCESS); if (res) { { ora_error(db); ora_disconnect(db); return 0; } } } debugf(" ok, oracle sever connected\n"); return 1; // Connected OK! }
/* {{{ proto mixed ora_getcolumn(int cursor, int column) Get data from a fetched row */ void php3_Ora_GetColumn(INTERNAL_FUNCTION_PARAMETERS) { /* cursor_index, column_index */ pval *argv[2]; int colno; oraCursor *cursor = NULL; oraColumn *column = NULL; sb2 type; if (ARG_COUNT(ht) != 2 || getParametersArray(ht, 2, argv) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_long(argv[0]); /* Find the cursor */ if ((cursor = ora_get_cursor(list, argv[0]->value.lval)) == NULL) { RETURN_FALSE; } if (cursor->ncols == 0){ php3_error(E_WARNING, "No tuples available at this cursor index"); RETURN_FALSE; } convert_to_long(argv[1]); colno = argv[1]->value.lval; if (colno >= cursor->ncols){ php3_error(E_WARNING, "Column index larger than number of columns"); RETURN_FALSE; } if (colno < 0){ php3_error(E_WARNING, "Column numbering starts at 0"); RETURN_FALSE; } if (cursor->fetched == 0){ if (ofetch(&cursor->cda)) { if (cursor->cda.rc != NO_DATA_FOUND) { php3_error(E_WARNING, "Ora_Fetch failed (%s)", ora_error(&cursor->cda)); } RETURN_FALSE; } cursor->fetched++; } column = &cursor->columns[colno]; type = column->dbtype; if (column->col_retcode != 0 && column->col_retcode != 1406) { /* So error fetching column. The most common is 1405, a NULL * was retreived. 1406 is ASCII or string buffer data was * truncated. The converted data from the database did not fit * into the buffer. Since we allocated the buffer to be large * enough, this should not occur. Anyway, we probably want to * return what we did get, in that case */ RETURN_FALSE; } else { switch(type) { case SQLT_CHR: case SQLT_NUM: case SQLT_INT: case SQLT_FLT: case SQLT_STR: case SQLT_UIN: case SQLT_AFC: case SQLT_AVC: case SQLT_DAT: RETURN_STRINGL(column->buf, min(column->col_retlen, column->dsize), 1); case SQLT_LNG: case SQLT_LBI: #if 0 { ub4 ret_len; /* XXX 64k max for LONG and LONG RAW */ oflng(&cursor->cda, (sword)(colno + 1), column->buf, DB_SIZE, 1, &ret_len, 0); RETURN_STRINGL(column->buf, ret_len, 1); } #else { ub4 ret_len; int offset = column->col_retlen; sb2 result; if (column->col_retcode == 1406) { /* truncation -> get the rest! */ while (1) { column->buf = erealloc(column->buf,offset + DB_SIZE + 1); if (! column->buf) { offset = 0; break; } result = oflng(&cursor->cda, (sword)(colno + 1), column->buf + offset, DB_SIZE, 1, &ret_len, offset); if (result) { break; } if (ret_len <= 0) { break; } offset += ret_len; } } if (column->buf && offset) { RETURN_STRINGL(column->buf, offset, 1); } else { RETURN_FALSE; } } #endif default: php3_error(E_WARNING, "Ora_GetColumn found invalid type (%d)", type); RETURN_FALSE; } } }
// Связывает переменные для выгрузки select во внутренние буфера... int ora_open(database *db) { t_ora *o = db->h; int nc, i , len; db_col *c; char szname[256]; ub4 name_len; // Буфер для имени колонки if (!o) return ora_error(db); o->rownum = 0; db->out.count=0; db->out.len=0; // Очищаем "внутренние" колонки // Теперь нужно еще и так сделать перез запросом колонок... if (!ora_ok(OCIStmtExecute(o->svchp, o->stmt, o->errhp, (ub4) 1, (ub4) 0, (CONST OCISnapshot *) NULL, (OCISnapshot *) NULL, OCI_DESCRIBE_ONLY))) return ora_error(db); for(nc=0;;nc++) { int dbtype=0,type; sword scale=0, ok; ub4 dblen; char *name; name_len=sizeof(name)-1; ok = (OCI_SUCCESS==OCIParamGet(o->stmt, OCI_HTYPE_STMT,o->errhp, &o->mypard,(ub4)nc+1)) && (OCI_SUCCESS==OCIAttrGet(o->mypard, (ub4) OCI_DTYPE_PARAM,(dvoid*) &dbtype,(ub4 *) 0, (ub4) OCI_ATTR_DATA_TYPE,(OCIError *)o->errhp)) && (OCI_SUCCESS==OCIAttrGet(o->mypard, (ub4) OCI_DTYPE_PARAM,(dvoid**)&name,(ub4 *) &name_len, (ub4) OCI_ATTR_NAME,(OCIError *)o->errhp )) && (OCI_SUCCESS==OCIAttrGet(o->mypard, (ub4) OCI_DTYPE_PARAM,(dvoid**)&dblen,&dblen, (ub4) OCI_ATTR_DISP_SIZE,(OCIError *)o->errhp )) && (OCI_SUCCESS==OCIAttrGet(o->mypard, (ub4) OCI_DTYPE_PARAM,(dvoid**)&scale,(ub4 *) 0, (ub4) OCI_ATTR_SCALE,(OCIError *)o->errhp )); if (!ok) break; if(name_len>255) name_len=255; strncpy(szname,name,name_len); szname[name_len]=0; //printf("Col:%d name='%*.*s' dbtype=%d dblen=%d scale=%d\n",nc,name_len,name_len,name, dbtype,dblen,scale); switch (dbtype) { case INT_TYPE: type=dbInt; break; case FLOAT_TYPE: case NUMBER_TYPE: type=dbDouble; break; case ROWID_TYPE: case 96: case 8: case 23: case STRING_TYPE: case VARCHAR2_TYPE: type=dbChar; dblen = 4*1024; break; case 112: // CLOB dblen = MAX_CLOB; type=dbChar; printf("Clob?\n"); break; case DATE_TYPE: type=dbDate; break; //case 112: type=dbBlob; break; // Char LOB case 113: type=dbBlob; break; // Bin LOB default: { sprintf(db->error,"VORA - open: unkown oracle type #%d pos=%d",dbtype,nc+1); db->out.count=0; return 0; } } c=db_add_col(&db->out,szname,type,dblen); c->dbtype=dbtype; if (!c) { sprintf(db->error,"vora - failed alloc memory"); return 0; } if((c->type==dbInt)||(c->type==dbDouble)) c->len=scale; } // А Это уже подвязка к локальным переменным #define ora_def(DATA,TYPE,SIZE) nl = OCIDefineByPos(o->stmt, &o->defs[i] , o->errhp, \ (ub4) i+1 , (dvoid *) DATA, \ (sb4) SIZE, TYPE, &c->null, (ub2 *) 0, \ (ub2 *) 0, OCI_DEFAULT) #define ora_def2(DATA,TYPE,SIZE) nl = OCIDefineByPos(o->stmt, &o->defs2[i] , o->errhp, \ (ub4) i+1 , (dvoid *) DATA, \ (sb4) SIZE, TYPE, &c->null, (ub2 *) 0, \ (ub2 *) 0, OCI_DEFAULT) for(i=0,c=db->out.cols; i<nc; i++,c++) { int nl ; // Код возврата операции повязывания... switch (c->type) { case dbInt: ora_def2(c->value,INT_TYPE,4); break; // Сразу в буфер! case dbDouble: ora_def2(c->value,SQLT_FLT,8); break; // Сразу в буфер! case dbDate: ora_def2(c->dbvalue,DATE_TYPE,8); break; case dbChar: ora_def2(c->dbvalue,STRING_TYPE,c->len+1); break; case dbBlob: { ora_def2(&o->blob_read,SQLT_BLOB,0); break; } } if(nl!=OCI_SUCCESS) { db->out.count=0; return ora_error(db); } } return 1; }
static sword ora_describe_define(oraCursor * cursor) { long col = 0; int i; sb2 type; sb4 dbsize; if (cursor == NULL) { return -1; } if (cursor->columns) { for(i = 0; i < cursor->ncols; i++){ if (cursor->columns[i].buf) efree(cursor->columns[i].buf); } efree(cursor->columns); } cursor->ncols = 0; while(1){ if (odescr(&cursor->cda, (sword) cursor->ncols + 1, &dbsize, (sb2 *)0, (sb1 *)0, (sb4 *)0, (sb4 *)0, (sb2 *)0, (sb2 *)0, (sb2 *)0)){ if (cursor->cda.rc == VAR_NOT_IN_LIST) { break; } else { php3_error(E_WARNING, "%s", ora_error(&cursor->cda)); cursor->ncols = 0; return -1; } } cursor->ncols++; } if (cursor->ncols > 0){ cursor->columns = (oraColumn *) emalloc(sizeof(oraColumn) * cursor->ncols); if (cursor->columns == NULL){ php3_error(E_WARNING, "Out of memory"); return -1; } } for(col = 0; col < cursor->ncols; col++){ memset(&cursor->columns[col], 0, sizeof(oraColumn)); cursor->columns[col].cbufl = ORANAMELEN; if (odescr(&cursor->cda, (sword)col + 1, &cursor->columns[col].dbsize, &cursor->columns[col].dbtype, &cursor->columns[col].cbuf[0], &cursor->columns[col].cbufl, &cursor->columns[col].dsize, &cursor->columns[col].prec, &cursor->columns[col].scale, &cursor->columns[col].nullok)) { if (cursor->cda.rc == VAR_NOT_IN_LIST) { break; } else { php3_error(E_WARNING, "%s", ora_error(&cursor->cda)); return -1; } } cursor->columns[col].cbuf[cursor->columns[col].cbufl] = '\0'; switch (cursor->columns[col].dbtype) { case SQLT_LBI: cursor->columns[col].dsize = DB_SIZE; type = SQLT_LBI; break; case SQLT_LNG: cursor->columns[col].dsize = DB_SIZE; default: type = SQLT_STR; break; } if ((cursor->columns[col].buf = (ub1 *) emalloc(cursor->columns[col].dsize + 1)) == NULL){ php3_error(E_WARNING, "Out of memory"); return -1; } /* Define an output variable for the column */ if (odefin(&cursor->cda, (sword)col + 1, cursor->columns[col].buf, cursor->columns[col].dsize + 1, type, -1, &cursor->columns[col].indp, (text *) 0, -1, -1, &cursor->columns[col].col_retlen, &cursor->columns[col].col_retcode)) { php3_error(E_WARNING, "%s", ora_error(&cursor->cda)); return -1; } } return 1; }
// Вызывается перед первым эхеком... int ora_check_bind(database *db) { int typ,len,i; db_col *c; void *val; t_ora *o = db->h; if(db->in.count==0) return 1; // Нету переменных, OK. for(i=0,c=db->in.cols; i<db->in.count; i++,c++) { val=(void*)c->value; c->dbvalue = c->value; // by default -))) switch (c->type) { case dbInt: typ=INT_TYPE; len=sizeof(int); break; case dbDouble: typ=SQLT_FLT; len=sizeof(double); break; case dbChar: typ=STRING_TYPE; len=c->len+1; break; case dbDate: typ=DATE_TYPE; // Придется декодировать... len=7; val=c->dbvalue; //c->value=(void*)c->dbtype; break; case dbBlob: val = c->name[0]!=':'?&o->blob_read:&o->blob; if (1) { int code; ub4 lobEmpty = 0; // if (o->blob) { OCIDescriptorFree(o->blob, (ub4) OCI_DTYPE_LOB); o->blob=0;} if (o->blob) { OCIDescriptorFree(o->blob, (ub4) OCI_DTYPE_LOB); o->blob=0;} OCIDescriptorAlloc((dvoid *) o->envhp, (dvoid **) &o->blob, (ub4) OCI_DTYPE_LOB, (size_t) 0, (dvoid **) 0); OCILobCreateTemporary(o->svchp,o->errhp,o->blob, OCI_DEFAULT,OCI_DEFAULT,OCI_TEMP_BLOB,FALSE,OCI_DURATION_SESSION); //if( code=OCILobCreateTemporary(o->svchp, o->errhp, o->blob, //(ub2)0, SQLCS_IMPLICIT, //OCI_TEMP_BLOB, OCI_ATTR_NOCACHE, //OCI_DURATION_SESSION) ) //{ // (void) printf("FAILED: CreateTemporary() code=%d \n",code); // return 0; //} // code=OCIDescriptorAlloc((dvoid *) o->envhp, (dvoid **) &o->blob, // (ub4) OCI_DTYPE_LOB, (size_t) 0, (dvoid **) 0); // printf("Created with code=%d\n",code); // code=OCIAttrSet((dvoid *) o->blob, (ub4) OCI_DTYPE_LOB, // &lobEmpty, sizeof(lobEmpty), // (ub4) OCI_ATTR_LOBEMPTY, o->errhp); //if (o->blob) len = 0; typ = SQLT_BLOB; //printf("init oblob=%d code=%d\n",o->blob,code); code = OCILobTrim(o->svchp, o->errhp, o->blob,0); //printf("LobTrimmed %d code=%d!\n",o->blob,code); } len = 0; typ = SQLT_BLOB; break; default: sprintf(db->error,"VORA-bind: unknown type %d pos=%d",c->type,i); return 0; } //rintf("Start bind var %s\n",c->name); if (!ora_ok(db->err_code = OCIBindByName(o->stmt,&o->defs[db->out.count+i], o->errhp, (text *) c->name, -1, val, len, typ, (short*)&c->null, (ub2 *) 0, (ub2 *) 0, (ub4) 0, (ub4 *) 0, OCI_DEFAULT))) { ora_error(db); strcat(db->error," on bind "); strcat(db->error,c->name); return 0; } //rintf("End bind %s\n",c->name); } return 1; }
// Это просто роллбак... int ora_rollback(database *db) { t_ora *o = db->h; if (!o) return ora_error(db); if (!ora_ok(OCITransRollback(o->svchp,o->errhp, 0))) return ora_error(db); return 1; }
void php3_Ora_Do_Logon(INTERNAL_FUNCTION_PARAMETERS, int persistent) { char *user = NULL; char *pwd = NULL; pval *arg1, *arg2; oraConnection *db_conn; list_entry *index_ptr; char *hashed_details; int hashed_len, len, id; ORACLE_TLS_VARS; if (getParameters(ht, 2, &arg1, &arg2) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string(arg1); convert_to_string(arg2); user = arg1->value.str.val; pwd = arg2->value.str.val; if (!ORACLE_GLOBAL(php3_oracle_module).allow_persistent) { persistent = 0; } if (ORACLE_GLOBAL(php3_oracle_module).max_links != -1 && ORACLE_GLOBAL(php3_oracle_module).num_links >= ORACLE_GLOBAL(php3_oracle_module).max_links) { php3_error(E_WARNING, "Oracle: Too many open links (%d)", ORACLE_GLOBAL(php3_oracle_module).num_links); RETURN_FALSE; } /* the user requested a persistent connection */ if (persistent && ORACLE_GLOBAL(php3_oracle_module).max_persistent != -1 && ORACLE_GLOBAL(php3_oracle_module).num_persistent >= ORACLE_GLOBAL(php3_oracle_module).max_persistent) { php3_error(E_WARNING,"Oracle: Too many open persistent links (%d)", ORACLE_GLOBAL(php3_oracle_module).num_persistent); RETURN_FALSE; } len = strlen(user) + strlen(pwd) + 9; hashed_details = emalloc(len); if (hashed_details == NULL) { php3_error(E_WARNING, "Out of memory"); RETURN_FALSE; } hashed_len = _php3_sprintf(hashed_details, "ora_%s_%s", user, pwd); /* try to find if we already have this link in our persistent list, * no matter if it is to be persistent or not */ if (_php3_hash_find(plist, hashed_details, hashed_len + 1, (void **) &index_ptr) == FAILURE) { /* the link is not in the persistent list */ list_entry new_index_ptr; if (persistent) db_conn = (oraConnection *)malloc(sizeof(oraConnection)); else db_conn = (oraConnection *)emalloc(sizeof(oraConnection)); if (db_conn == NULL){ efree(hashed_details); php3_error(E_WARNING, "Out of memory"); RETURN_FALSE; } memset((void *) db_conn,0,sizeof(oraConnection)); #if HAS_OLOG if (olog(&db_conn->lda, db_conn->hda, user, strlen(user), pwd, strlen(pwd), 0, -1, OCI_LM_DEF)) { #else if (orlon(&db_conn->lda, db_conn->hda, user, strlen(user), pwd, strlen(pwd), 0)) { #endif php3_error(E_WARNING, "Unable to connect to ORACLE (%s)", ora_error(&db_conn->lda)); /* The next line is to provide error information * for OraError && OraErrorCode calls */ db_err_conn = *db_conn; if (persistent) free(db_conn); else efree(db_conn); efree(hashed_details); RETURN_FALSE; } db_conn->open = 1; if (persistent){ /*new_le.type = ORACLE_GLOBAL(php3_oracle_module).le_pconn; new_le.ptr = db_conn;*/ RETVAL_RESOURCE(php3_plist_insert(db_conn, ORACLE_GLOBAL(php3_oracle_module).le_pconn)); new_index_ptr.ptr = (void *) return_value->value.lval; new_index_ptr.type = le_index_ptr; if (_php3_hash_update(plist,hashed_details,hashed_len + 1,(void *) &new_index_ptr, sizeof(list_entry),NULL) == FAILURE) { ologof(&db_conn->lda); free(db_conn); efree(hashed_details); php3_error(E_WARNING, "Can't update hashed details list"); RETURN_FALSE; } ORACLE_GLOBAL(php3_oracle_module).num_persistent++; } else { /* non persistent, simply add to list */ RETVAL_RESOURCE(php3_list_insert(db_conn, ORACLE_GLOBAL(php3_oracle_module).le_conn)); } ORACLE_GLOBAL(php3_oracle_module).num_links++; } else { int type; /* the link is already in the persistent list */ if (index_ptr->type != le_index_ptr) { efree(hashed_details); php3_error(E_WARNING, "Oops, something went completly wrong"); RETURN_FALSE; } id = (int) index_ptr->ptr; db_conn = (oraConnection *)php3_plist_find(id, &type); if (db_conn && (type == ORACLE_GLOBAL(php3_oracle_module).le_conn || type == ORACLE_GLOBAL(php3_oracle_module).le_pconn)){ if(!_ora_ping(db_conn)) { /* XXX Reinitialize lda, hda ? */ #if HAS_OLOG if(olog(&db_conn->lda, db_conn->hda, user, strlen(user), pwd, strlen(pwd), 0, -1, OCI_LM_DEF)) { #else if(orlon(&db_conn->lda, db_conn->hda, user, strlen(user), pwd, strlen(pwd), 0)) { #endif /* The next line is to provide error information * for OraError && OraErrorCode calls */ db_err_conn = *db_conn; php3_error(E_WARNING, "Unable to reconnect to ORACLE (%s)", ora_error(&db_conn->lda)); /* Delete list entry for this connection */ php3_plist_delete(id); /* Delete hashed list entry for this dead connection */ _php3_hash_del(plist, hashed_details, hashed_len); efree(hashed_details); RETURN_FALSE; } } RETVAL_RESOURCE(id); } } _php3_hash_add(ORACLE_GLOBAL(php3_oracle_module).conns, (void*)&db_conn, sizeof(void*), (void*)&db_conn, sizeof(void*), NULL); efree(hashed_details); } /* {{{ proto int ora_logoff(int connection) Close an Oracle connection */ void php3_Ora_Logoff(INTERNAL_FUNCTION_PARAMETERS) { /* conn_index */ int type, ind; oraConnection *conn; pval *arg; ORACLE_TLS_VARS; if (getParameters(ht, 1, &arg) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_long(arg); ind = (int)arg->value.lval; conn = (oraConnection *)php3_list_find(ind, &type); if (!conn || (type != ORACLE_GLOBAL(php3_oracle_module).le_conn && type != ORACLE_GLOBAL(php3_oracle_module).le_pconn)) { return; } php3_list_delete(ind); }
// Это просто коммит... int ora_commit(database *db) { t_ora *o = db->h; if (!o) return ora_error(db); if (!ora_ok(OCITransCommit(o->svchp,o->errhp, 0))) return ora_error(db); return 1; }
// Перекодировка is_null, in bind vars, закачка блобов и потом ora_exec int ora_exec(database *db) { t_ora *o = db->h; db_col *c; int i; if (!o) return ora_error(db); //if (!o->execnum) // { // o->execnum = 1; if (!ora_check_bind(db)) return 0; // Если первый раз - подвязать переменные... // } debugf(" ..ora - check bind ok!\n"); o->execnum++; // Номер запуска exec... for(i=0,c=db->in.cols;i<db->in.count;i++,c++) if ((c->dbflag & 2)==0) { // Все ин-параметры if(c->type==dbDate) // Перекодируем дату { unsigned char *D=(void*)c->dbvalue; double uval = *(double*)c->value; int Year,Month,Day,Hour,Min,Sec; if (!uval) c->null=ORA_NULL; else { c->null=0; dt_decode(uval,&Year,&Month,&Day,&Hour,&Min,&Sec); D[0]=100+Year/100; D[1]=Year%100+100; D[2]=Month; D[3]=Day; D[4]=Hour+1; D[5]=Min+1; D[6]=Sec+1; } //printf("ORA uval=%lf\n",uval); getch(); } else if (c->type == dbBlob && (!(c->dbflag & 2))) { // Закачиваем блобы... db_blob_handle *b = (void*) c->value; // Странно, но я храню блоб тута... int cnt_write = 0, offset = 0, code; cnt_write = b->len; // Сколько записывать... code = OCILobTrim(o->svchp, o->errhp, o->blob,0); //printf("2LobTrimmed data=%d len=%d olob=%d code=%d!\n",b->data,b->len,o->blob,code); c->null = ORA_NULL; if (b->data && b->len>0) { c->null = 0; if ( !ora_ok(db->err_code = OCILobWrite(o->svchp, o->errhp, o->blob, &cnt_write, 1, (dvoid *) b->data, (ub4) b->len, OCI_ONE_PIECE, 0, 0 csid_csfrm) )) { debugf("F**k! cant write blob err_code=%d ND=%d!\n",db->err_code,OCI_NEED_DATA); //if (db->err_code!=-2) // ZU? return ora_error(db); } debugf("vora- ok write %d bytes of lob\n",b->len); } } } debugf(" ..ora - begin OCIStmtExecute stmt=%p!\n",o->stmt); db->err_code = OCIStmtExecute(o->svchp, o->stmt, o->errhp, (ub4) 1, (ub4) 0, (CONST OCISnapshot *) NULL, (OCISnapshot *) NULL,OCI_DEFAULT); debugf("ORARES on exec = %d\n",db->err_code); if (db->err_code == OCI_NO_DATA) return 1; // ExecOK, данные не сфетчились... if (!ora_ok(db->err_code)) return ora_error(db); // А это уже ошибка... debugf("ORA - decode out\n"); //return 1; // Далее - идет обратная декодировка. Пока не отлаживаем for(i = 0, c = db->in.cols;i<db->in.count; i++, c++) if (c->dbflag & 2) { // Смотрим на аут-параметры int is_null; debugf("----ORA --- chek OUT HERE=%s\n",c->name); //printf("NULL=%d on %s\n",*(short*)c->null,c->name); //is_null = c->null && ((*(short*)(c->null)) ); //if (c->null) *(int*)(c->null) = is_null; //printf("Check in var=%s is_null = %d val=%d\n",c->name,is_null,*(int*)c->value); //if (is_null) continue; if ( c->type==dbDate) { unsigned char *D=(void*)c->dbvalue; if (c->null) *(double*)c->value=0; else *(double*)c->value=dt_encode((D[0]-100)*100+(D[1]-100), D[2],D[3],D[4]-1,D[5]-1,D[6]-1); } else if (c->type==dbBlob) { // Вытягиваем блобу... db_blob_handle *b=(void*)c->value; // Это указатель на "вытащенный блоб", его нужно установить на... int cnt_read = 0, offset = 0, blob_length = 0; debugf("ORA --- chek out blob null==%d\n",c->null); if (c->null) {b->len=0; continue;} /// OCILobLock ??? //db->err_code = OCILobOpen ( o->svchp, o->errhp, o->blob_read, OCI_LOB_READONLY ); //printf("Lob opened error = %d\n", db->err_code); //if (db->out.size<1) { // db->out.data = realloc(db->out.data,1); // db->out.size = 1; // } //OCILobRead(o->svchp,o->errhp,o->blob_read, // Интересно, такое бывает? //&cnt_read, 1, db->out.blob, 1 , 0, 0); // Just for FUN ... // printf("Read = %d bytes\n", cnt_read ); if (!ora_ok(db->err_code=OCILobGetLength (o->svchp,o->errhp,o->blob_read, &blob_length))) { debugf("Fail get blob length code=%d result=%d!\n",db->err_code,blob_length); blob_length = 100* 1024 ; // return 1; // ZUZUKA ora_error(db); } //printf("Getting out blob len = %d..\n",blob_length); // - Сюда сливаются БЛОБЫ от SELCETA -- db->out.blob,&db->out.bsize,&db->out.blen if (blob_length +1 >= db->out.bsize) { // Еще место нужно... Realloc... db->out.bsize = blob_length+1024; // Новая длина db->out.blob = realloc(db->out.blob,db->out.bsize); // Думаем что памяти достаточно } if (!ora_ok(db->err_code=OCILobRead(o->svchp,o->errhp,o->blob_read, // Интересно, такое бывает? &cnt_read, 1, db->out.blob, db->out.bsize, 0, 0 csid_csfrm))) { //printf("Fail read blob err=%d!\n"); return ora_error(db); } //OCILobTrim(o->svchp, o->errhp, o->blob_read,0); db->out.blen = cnt_read+1; // Zero termanited на всякий случай... //printf("Read blob len = %d bh=%d\n",cnt_read,b); // Корректируем указатель, т.к. блоб мог реаллокнуться.. b->data = db->out.blob; // Все заточено под один БЛОБ b->len = cnt_read; b->data[b->len] = 0; // Терминирование нулем - вещь полезная... } } return 1; }
/* {{{ proto int ora_do(int connection, int cursor) Parse and execute a statement and fetch first result row */ void php3_Ora_Do(INTERNAL_FUNCTION_PARAMETERS) { pval *argv[2]; oraConnection *conn = NULL; oraCursor *cursor = NULL; text *query; if (ARG_COUNT(ht) != 2 || getParametersArray(ht, 2, argv) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_long(argv[0]); convert_to_string(argv[1]); conn = ora_get_conn(list,plist, argv[0]->value.lval); if (conn == NULL) { RETURN_FALSE; } if ((cursor = (oraCursor *)emalloc(sizeof(oraCursor))) == NULL){ php3_error(E_WARNING, "Out of memory"); RETURN_FALSE; } memset(cursor, 0, sizeof(oraCursor)); query = (text *) estrndup(argv[1]->value.str.val,argv[1]->value.str.len); if (query == NULL) { php3_error(E_WARNING, "Invalid query in Ora_Do"); RETURN_FALSE; } cursor->query = query; if (oopen(&cursor->cda, &conn->lda, (text *) 0, -1, -1, (text *) 0, -1)) { php3_error(E_WARNING, "Unable to open new cursor (%s)", ora_error(&cursor->cda)); efree(cursor); RETURN_FALSE; } cursor->open = 1; cursor->conn_ptr = conn; cursor->conn_id = argv[0]->value.lval; /* Prepare stmt */ if (oparse(&cursor->cda, query, (sb4) - 1, 1, VERSION_7)){ php3_error(E_WARNING, "Ora_Do failed (%s)", ora_error(&cursor->cda)); _close_oracur(cursor); RETURN_FALSE; } /* Execute stmt (and fetch 1st row for selects) */ if (cursor->cda.ft == FT_SELECT) { if (ora_describe_define(cursor) < 0){ /* error message is given by ora_describe_define() */ _close_oracur(cursor); RETURN_FALSE; } if (oexfet(&cursor->cda, 1, 0, 0)) { php3_error(E_WARNING, "Ora_Do failed (%s)", ora_error(&cursor->cda)); _close_oracur(cursor); RETURN_FALSE; } cursor->fetched = 1; } else { if (oexec(&cursor->cda)) { php3_error(E_WARNING, "Ora_Do failed (%s)", ora_error(&cursor->cda)); _close_oracur(cursor); RETURN_FALSE; } } RETURN_RESOURCE(ora_add_cursor(list, cursor)); }
/* {{{ proto int ora_fetch_into(int cursor, array result [, int flags]) Fetch a row into the specified result array */ void php3_Ora_FetchInto(INTERNAL_FUNCTION_PARAMETERS) { pval *arg1, *arr, *flg, *tmp; oraCursor *cursor; int i; int flags = 0; switch(ARG_COUNT(ht)){ case 2: if (getParameters(ht, 2, &arg1, &arr) == FAILURE) { WRONG_PARAM_COUNT; } break; case 3: if (getParameters(ht, 3, &arg1, &arr, &flg) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_long(flg); flags = flg->value.lval; break; default: WRONG_PARAM_COUNT; break; } if (!ParameterPassedByReference(ht, 2)){ php3_error(E_WARNING, "Array not passed by reference in call to ora_fetch_into()"); RETURN_FALSE; } convert_to_long(arg1); /* Find the cursor */ if ((cursor = ora_get_cursor(list, arg1->value.lval)) == NULL) { RETURN_FALSE; } if (cursor->ncols == 0){ php3_error(E_WARNING, "No tuples available on this cursor"); RETURN_FALSE; } if (ofetch(&cursor->cda)) { if (cursor->cda.rc != NO_DATA_FOUND) { php3_error(E_WARNING, "Ora_Fetch_Into failed (%s)", ora_error(&cursor->cda)); } RETURN_FALSE; } cursor->fetched++; if (arr->type != IS_ARRAY){ php3tls_pval_destructor(arr); if (array_init(arr) == FAILURE){ php3_error(E_WARNING, "Can't convert to type Array"); RETURN_FALSE; } } _php3_hash_internal_pointer_reset(arr->value.ht); #if PHP_API_VERSION < 19990421 tmp = emalloc(sizeof(pval)); #endif for (i = 0; i < cursor->ncols; i++) { if (cursor->columns[i].col_retcode == 1405) { if (!(flags&ORA_FETCHINTO_NULLS)){ continue; /* don't add anything for NULL columns, unless the calles wants it */ } else { tmp->value.str.val = empty_string; tmp->value.str.len = 0; } } else if (cursor->columns[i].col_retcode != 0 && cursor->columns[i].col_retcode != 1406) { /* So error fetching column. The most common is 1405, a NULL */ /* was retreived. 1406 is ASCII or string buffer data was */ /* truncated. The converted data from the database did not fit */ /* into the buffer. Since we allocated the buffer to be large */ /* enough, this should not occur. Anyway, we probably want to */ /* return what we did get, in that case */ RETURN_FALSE; } else { #if PHP_API_VERSION >= 19990421 MAKE_STD_ZVAL(tmp); #endif tmp->type = IS_STRING; tmp->value.str.len = 0; switch(cursor->columns[i].dbtype) { case SQLT_LNG: case SQLT_LBI: { ub4 ret_len; int offset = cursor->columns[i].col_retlen; sb2 result; if (cursor->columns[i].col_retcode == 1406) { /* truncation -> get the rest! */ while (1) { cursor->columns[i].buf = erealloc(cursor->columns[i].buf,offset + DB_SIZE + 1); if (! cursor->columns[i].buf) { offset = 0; break; } result = oflng(&cursor->cda, (sword)(i + 1), cursor->columns[i].buf + offset, DB_SIZE, 1, &ret_len, offset); if (result) { break; } if (ret_len <= 0) { break; } offset += ret_len; } } if (cursor->columns[i].buf && offset) { tmp->value.str.len = offset; } else { tmp->value.str.len = 0; } } break; default: tmp->value.str.len = min(cursor->columns[i].col_retlen, cursor->columns[i].dsize); break; } tmp->value.str.val = estrndup(cursor->columns[i].buf,tmp->value.str.len); } if (flags&ORA_FETCHINTO_ASSOC){ #if PHP_API_VERSION >= 19990421 _php3_hash_update(arr->value.ht, cursor->columns[i].cbuf, cursor->columns[i].cbufl+1, (void *) &tmp, sizeof(pval*), NULL); #else _php3_hash_update(arr->value.ht, cursor->columns[i].cbuf, cursor->columns[i].cbufl+1, (void *) tmp, sizeof(pval), NULL); #endif } else { #if PHP_API_VERSION >= 19990421 _php3_hash_index_update(arr->value.ht, i, (void *) &tmp, sizeof(pval*), NULL); #else _php3_hash_index_update(arr->value.ht, i, (void *) tmp, sizeof(pval), NULL); #endif } } #if PHP_API_VERSION < 19990421 efree(tmp); #endif RETURN_LONG(cursor->ncols); }
/* {{{ proto int ora_bind(int cursor, string php_variable_name, string sql_parameter_name, int length [, int type]) Bind a PHP variable to an Oracle parameter */ void php3_Ora_Bind(INTERNAL_FUNCTION_PARAMETERS) { /* cursor_ind, php_var_name, sql_var_name, data_len [, inout]*/ /* inout: 0 = in/out, 1 = in, 2 = out */ int argc; pval *argv[5]; oraParam *newparam, *paramptr; oraCursor *cursor; char *paramname; argc = ARG_COUNT(ht); if (argc < 4 || argc > 5 || getParametersArray(ht, argc, argv) == FAILURE){ WRONG_PARAM_COUNT; } convert_to_long(argv[0]); convert_to_string(argv[1]); convert_to_string(argv[2]); convert_to_long(argv[3]); cursor = ora_get_cursor(list, argv[0]->value.lval); if (cursor == NULL) { php3_error(E_WARNING, "Invalid cursor index %d", argv[0]->value.lval); RETURN_FALSE; } if(cursor->params == NULL){ cursor->params = (HashTable *)emalloc(sizeof(HashTable)); if (!cursor->params || _php3_hash_init(cursor->params, 19, NULL, HASH_DTOR pval_ora_param_destructor, 0) == FAILURE) { php3_error(E_ERROR, "Unable to initialize parameter list"); RETURN_FALSE; } } if((newparam = (oraParam *)emalloc(sizeof(oraParam))) == NULL){ php3_error(E_WARNING, "Out of memory for parameter"); RETURN_FALSE; } if((paramname = estrndup(argv[1]->value.str.val, argv[1]->value.str.len)) == NULL){ php3_error(E_WARNING, "Out of memory for parametername"); efree(newparam); RETURN_FALSE; } if (_php3_hash_add(cursor->params, paramname, argv[1]->value.str.len + 1, newparam, sizeof(oraParam), (void **)¶mptr) == FAILURE) { /* XXX _php3_hash_destroy */ efree(paramname); efree(newparam); php3_error(E_ERROR, "Could not make parameter placeholder"); RETURN_FALSE; } efree(newparam); efree(paramname); paramptr->progvl = argv[3]->value.lval + 1; if(argc > 4){ convert_to_long(argv[4]); paramptr->inout = (short)argv[4]->value.lval; }else{ paramptr->inout = 0; } if((paramptr->progv = (text *)emalloc(paramptr->progvl)) == NULL){ php3_error(E_WARNING, "Out of memory for parameter value"); RETURN_FALSE; } /* XXX Maximum for progvl */ paramptr->alen = paramptr->progvl; if (obndra(&cursor->cda, argv[2]->value.str.val, -1, (ub1 *)paramptr->progv, paramptr->progvl, SQLT_STR, /* ftype */ -1, /* scale */ 0/*¶mptr->ind*/, /* ind */ ¶mptr->alen, /* alen */ 0 /*¶mptr->arcode*/, 0, /* maxsize */ 0, 0, -1, -1)) { php3_error(E_WARNING, "Ora_Bind failed (%s)", ora_error(&cursor->cda)); RETURN_FALSE; } cursor->nparams++; RETURN_TRUE; }