void Blob::getData(tntdb::Blob& blob) const { log_debug("OCILobGetLength"); ub4 len; sword ret = OCILobGetLength(conn->getSvcCtxHandle(), conn->getErrorHandle(), lob, &len); conn->checkError(ret, "OCILobGetLength"); log_debug("len=" << len); log_debug("OCILobOpen"); ret = OCILobOpen(conn->getSvcCtxHandle(), conn->getErrorHandle(), lob, OCI_LOB_READONLY); conn->checkError(ret, "OCILobOpen"); char* buffer = blob.reserve(len, true); memset(buffer, '\0', len); ub4 amt = len; log_debug("OCILobRead"); ret = OCILobRead(conn->getSvcCtxHandle(), conn->getErrorHandle(), lob, &amt, 1, buffer, len, 0, 0, 0, SQLCS_IMPLICIT); conn->checkError(ret, "OCILobRead"); log_debug("OCILobClose"); ret = OCILobClose(conn->getSvcCtxHandle(), conn->getErrorHandle(), lob); conn->checkError(ret, "OCILobClose"); }
// После фетча - перекодируем 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; }
/* ** Push a value on top of the stack. */ static int pushvalue (lua_State *L, cur_data *cur, int i) { /* column index ranges from 1 to numcols */ /* C array index ranges from 0 to numcols-1 */ column_data *col = &(cur->cols[i-1]); if (col->null) { /* Oracle NULL => Lua nil */ lua_pushnil (L); return 1; } switch (col->type) { case SQLT_NUM: case SQLT_INT: case SQLT_FLT: lua_pushnumber (L, col->val.d); break; case SQLT_CHR: case SQLT_STR: case SQLT_VCS: case SQLT_AFC: case SQLT_AVC: lua_pushstring (L, (char *)(col->val.s)); break; case SQLT_CLOB: { ub4 lob_len; conn_data *conn; env_data *env; lua_rawgeti (L, LUA_REGISTRYINDEX, cur->conn); conn = lua_touserdata (L, -1); lua_rawgeti (L, LUA_REGISTRYINDEX, conn->env); env = lua_touserdata (L, -1); lua_pop (L, 2); ASSERT (L, OCILobGetLength (conn->svchp, cur->errhp, (OCILobLocator *)col->val.s, &lob_len), cur->errhp); if (lob_len > 0) { char *lob_buffer=malloc(lob_len); ub4 amount = lob_len; ASSERT(L, OCILobRead(conn->svchp, cur->errhp, (OCILobLocator *) col->val.s, &amount, (ub4) 1, (dvoid *) lob_buffer, (ub4) lob_len, (dvoid *)0, (sb4 (*) (dvoid *, CONST dvoid *, ub4, ub1)) 0, (ub2) 0, (ub1) SQLCS_IMPLICIT), cur->errhp); lua_pushlstring (L, lob_buffer, amount); free(lob_buffer); } else { lua_pushstring (L, ""); } break; } default: luaL_error (L, LUASQL_PREFIX"unexpected error"); } return 1; }
char* OWStatement::ReadCLob( OCILobLocator* phLocator ) { ub4 nSize = 0; ub4 nAmont = 0; char* pszBuffer = NULL; if( CheckError( OCILobGetLength ( poConnection->hSvcCtx, hError, phLocator, (ub4*) &nSize ), hError ) ) { return NULL; } nSize *= this->poConnection->nCharSize; pszBuffer = (char*) VSIMalloc( sizeof(char*) * nSize ); if( pszBuffer == NULL) { return NULL; } if( CheckError( OCILobRead( poConnection->hSvcCtx, hError, phLocator, (ub4*) &nAmont, (ub4) 1, (dvoid*) pszBuffer, (ub4) nSize, (dvoid*) NULL, NULL, (ub2) 0, (ub1) SQLCS_IMPLICIT ), hError ) ) { CPLFree( pszBuffer ); return NULL; } pszBuffer[nAmont] = '\0'; return pszBuffer; }
DB_ROW zbx_db_fetch(DB_RESULT result) { #if defined(HAVE_IBM_DB2) int i; #elif defined(HAVE_ORACLE) int i; sword rc; static char errbuf[512]; sb4 errcode; #endif if (NULL == result) return NULL; #if defined(HAVE_IBM_DB2) if (SUCCEED != zbx_ibm_db2_success(SQLFetch(result->hstmt))) /* e.g., SQL_NO_DATA_FOUND */ return NULL; for (i = 0; i < result->ncolumn; i++) { result->values[i] = (SQL_NULL_DATA == result->values_len[i] ? NULL : result->values_cli[i]); } return result->values; #elif defined(HAVE_MYSQL) return mysql_fetch_row(result); #elif defined(HAVE_ORACLE) if (OCI_NO_DATA == (rc = OCIStmtFetch2(result->stmthp, oracle.errhp, 1, OCI_FETCH_NEXT, 0, OCI_DEFAULT))) return NULL; for (i = 0; i < result->ncolumn; i++) { if (NULL != result->clobs[i]) { ub4 alloc, amount, amt = 0; ub1 csfrm; rc = OCILobGetLength(oracle.svchp, oracle.errhp, result->clobs[i], &amount); if (OCI_SUCCESS != rc) break; rc = OCILobCharSetForm(oracle.envhp, oracle.errhp, result->clobs[i], &csfrm); if (OCI_SUCCESS != rc) break; if (result->values_alloc[i] < (alloc = amount * 4 + 1)) { result->values_alloc[i] = alloc; result->values[i] = zbx_realloc(result->values[i], result->values_alloc[i]); } amt = amount; rc = OCILobRead(oracle.svchp, oracle.errhp, result->clobs[i], &amt, (ub4)1, (dvoid *)result->values[i], (ub4)(result->values_alloc[i] - 1), (dvoid *)NULL, (OCICallbackLobRead)NULL, (ub2)0, csfrm); if (OCI_SUCCESS != rc) zabbix_errlog(ERR_Z3006, rc, zbx_oci_error(rc)); result->values[i][amt] = '\0'; } } if (OCI_SUCCESS == rc) return result->values; if (OCI_SUCCESS != (rc = OCIErrorGet((dvoid *)oracle.errhp, (ub4)1, (text *)NULL, &errcode, (text *)errbuf, (ub4)sizeof(errbuf), OCI_HTYPE_ERROR))) { zabbix_errlog(ERR_Z3006, rc, zbx_oci_error(rc)); return NULL; } switch (errcode) { case 3113: /* ORA-03113: end-of-file on communication channel */ case 3114: /* ORA-03114: not connected to ORACLE */ zabbix_errlog(ERR_Z3006, errcode, errbuf); return NULL; } return result->values; #elif defined(HAVE_POSTGRESQL) /* free old data */ if (NULL != result->values) zbx_free(result->values); /* EOF */ if (result->cursor == result->row_num) return NULL; /* init result */ result->fld_num = PQnfields(result->pg_result); if (result->fld_num > 0) { int i; result->values = zbx_malloc(result->values, sizeof(char *) * result->fld_num); for (i = 0; i < result->fld_num; i++) { if (PQgetisnull(result->pg_result, result->cursor, i)) { result->values[i] = NULL; } else { result->values[i] = PQgetvalue(result->pg_result, result->cursor, i); if (PQftype(result->pg_result, i) == ZBX_PG_BYTEAOID) /* binary data type BYTEAOID */ zbx_pg_unescape_bytea((u_char *)result->values[i]); } } } result->cursor++; return result->values; #elif defined(HAVE_SQLITE3) /* EOF */ if (result->curow >= result->nrow) return NULL; if (NULL == result->data) return NULL; result->curow++; /* NOTE: first row == header row */ return &(result->data[result->curow * result->ncolumn]); #endif }
// Перекодировка 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; }