static const char *dbd_freetds_get_entry(const apr_dbd_row_t *row, int n) { /* FIXME: support different data types */ /* this fails - bind gets some vars but not others return (const char*)row->res->vars[n].data; */ DBPROCESS* proc = row->res->proc; BYTE *ptr = dbdata(proc, n+1); int t = dbcoltype(proc, n+1); int l = dbcollen(proc, n+1); if (dbwillconvert(t, SYBCHAR)) { dbconvert(proc, t, ptr, l, SYBCHAR, (BYTE *)row->buf, -1); return (const char*)row->buf; } return (char*)ptr; }
static int colwidth( DBPROCESS * dbproc, int icol ) { int width = dbwillconvert(dbcoltype(dbproc, icol), SYBCHAR); return 255 == width? dbcollen(dbproc, icol) : width; }
static int onDataResponse(eio_req *req) { v8::HandleScope scope; data_callback_t *callbackData = (data_callback_t *) req->data; if(req->result == FAIL){ Local<Value> argv[1]; argv[0] = v8::Exception::Error(v8::String::New("An error occurred executing that statement")); callbackData->callback->Call(Context::GetCurrent()->Global(), 1, argv); } uint32_t rownum = 0; bool err = false; COL *columns, *pcol; int ncols = 0; v8::Local<v8::Array> results = v8::Array::New(); while(dbresults(callbackData->dbconn) != NO_MORE_RESULTS){ ncols = dbnumcols(callbackData->dbconn); columns = (COL *) calloc(ncols, sizeof(struct COL)); for (pcol = columns; pcol - columns < ncols; pcol++) { int i = pcol - columns + 1; pcol->name = v8::String::New(dbcolname(callbackData->dbconn, i)); pcol->type = dbcoltype(callbackData->dbconn, i); pcol->size = dbcollen(callbackData->dbconn, i); if (SYBCHAR != pcol->type) { pcol->size = dbwillconvert(pcol->type, SYBCHAR); } //todo: work out if I'm leaking if((pcol->buffer = (void *) malloc(pcol->size + 1)) == NULL) { err = true; break; } } if(err){ for (pcol = columns; pcol - columns < ncols; pcol++) { free(pcol->buffer); free(columns); } Local<Value> argv[1]; argv[0] = v8::Exception::Error(v8::String::New("Could not allocate memory for columns")); callbackData->callback->Call(Context::GetCurrent()->Global(), 1, argv); return 0; } for (pcol = columns; pcol - columns < ncols; pcol++) { int i = pcol - columns + 1; int binding = NTBSTRINGBIND; // switch(pcol->type){ // case TINYBIND: // case SMALLBIND: // case INTBIND: // case FLT8BIND: // case REALBIND: // case SMALLDATETIMEBIND: // case MONEYBIND: // case SMALLMONEYBIND: // case BINARYBIND: // case BITBIND: // case NUMERICBIND: // case DECIMALBIND: // case BIGINTBIND: // // all numbers in JS are doubles // binding = REALBIND; // break; // } if(dbbind(callbackData->dbconn, i, binding, pcol->size + 1, (BYTE*)pcol->buffer) == FAIL){ err = true; }else if(dbnullbind(callbackData->dbconn, i, &pcol->status) == FAIL){ err = true; } } if(err){ for (pcol = columns; pcol - columns < ncols; pcol++) { free(pcol->buffer); free(columns); } Local<Value> argv[1]; argv[0] = v8::Exception::Error(v8::String::New("Could not allocate memory for columns")); callbackData->callback->Call(Context::GetCurrent()->Global(), 1, argv); return 0; } int row_code; while ((row_code = dbnextrow(callbackData->dbconn)) != NO_MORE_ROWS){ if(row_code == REG_ROW) { v8::Local<v8::Object> tuple = v8::Object::New(); for (pcol = columns; pcol - columns < ncols; pcol++) { if(pcol->status == -1){ tuple->Set(pcol->name, v8::Null()); continue; } switch(pcol->type){ case SQLINTN: case SQLINT1: case SQLINT2: case SQLINT4: case SQLINT8: case SQLFLT8: case SQLDATETIME: case SQLDATETIM4: case SQLBIT: case SQLFLT4: case SQLNUMERIC: case SQLDECIMAL: case SQLFLTN: case SQLDATETIMN: case 36: case SQLCHAR: case SQLVARCHAR: case SQLTEXT: tuple->Set(pcol->name, v8::String::New((char*) pcol->buffer)); break; // case SQLINTN: // case SQLINT1: // case SQLINT2: // case SQLINT4: // case SQLINT8: // case SQLFLT8: // case SQLDATETIME: // case SQLDATETIM4: // case SQLBIT: // case SQLFLT4: // case SQLNUMERIC: // case SQLDECIMAL: // case SQLFLTN: // case SQLDATETIMN: // DBREAL val; // memcpy(&val, pcol->buffer, pcol->size); // tuple->Set(pcol->name, v8::Number::New((double)val)); break; case SQLIMAGE: case SQLMONEY4: case SQLMONEY: case SQLBINARY: case SQLVARBINARY: case SQLMONEYN: case SQLVOID: default: printf("unsupported col type %d\n", pcol->type); break; } } results->Set(rownum++, tuple); } } for (pcol = columns; pcol - columns < ncols; pcol++) { free(pcol->buffer); } free(columns); } v8::Local<v8::Value> argv[2] = { Local<Value>::New(Null()), results }; callbackData->callback->Call(Context::GetCurrent()->Global(), 2, argv); callbackData->callback.Dispose(); delete callbackData; return 0; }
static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, zend_ulong *len, int *caller_frees) { pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data; pdo_dblib_db_handle *H = S->H; int coltype; unsigned int tmp_len; char *tmp_ptr = NULL; coltype = dbcoltype(H->link, colno+1); *len = dbdatlen(H->link, colno+1); *ptr = dbdata(H->link, colno+1); if (*len == 0 && *ptr == NULL) { return 1; } switch (coltype) { case SQLVARBINARY: case SQLBINARY: case SQLIMAGE: case SQLTEXT: /* FIXME: Above types should be returned as a stream as they can be VERY large */ case SQLCHAR: case SQLVARCHAR: tmp_ptr = emalloc(*len + 1); memcpy(tmp_ptr, *ptr, *len); tmp_ptr[*len] = '\0'; *ptr = tmp_ptr; break; case SQLMONEY: case SQLMONEY4: case SQLMONEYN: { DBFLT8 money_value; dbconvert(NULL, coltype, *ptr, *len, SQLFLT8, (LPBYTE)&money_value, 8); *len = spprintf(&tmp_ptr, 0, "%.4f", money_value); *ptr = tmp_ptr; break; } case SQLUNIQUE: { *len = 37; tmp_ptr = emalloc(*len + 1); *len = dbconvert(NULL, SQLUNIQUE, *ptr, *len, SQLCHAR, tmp_ptr, *len); php_strtoupper(tmp_ptr, *len); tmp_ptr[36] = '\0'; *ptr = tmp_ptr; break; } default: if (dbwillconvert(coltype, SQLCHAR)) { tmp_len = 32 + (2 * (*len)); /* FIXME: We allocate more than we need here */ tmp_ptr = emalloc(tmp_len); *len = dbconvert(NULL, coltype, *ptr, *len, SQLCHAR, tmp_ptr, -1); *ptr = tmp_ptr; } else { *len = 0; /* FIXME: Silently fails and returns null on conversion errors */ *ptr = NULL; } } *caller_frees = 1; return 1; }
static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, zend_ulong *len, int *caller_frees) { pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data; pdo_dblib_db_handle *H = S->H; int coltype; LPBYTE data; DBCHAR *tmp_data; DBINT data_len, tmp_data_len; zval *zv = NULL; coltype = dbcoltype(H->link, colno+1); data = dbdata(H->link, colno+1); data_len = dbdatlen(H->link, colno+1); if (data_len != 0 || data != NULL) { if (pdo_dblib_stmt_should_stringify_col(stmt, coltype) && dbwillconvert(coltype, SQLCHAR)) { pdo_dblib_stmt_stringify_col(coltype, data, data_len, &zv); } if (!zv) { switch (coltype) { case SQLCHAR: case SQLVARCHAR: case SQLTEXT: { #if ilia_0 while (data_len>0 && data[data_len-1] == ' ') { /* nuke trailing whitespace */ data_len--; } #endif } case SQLVARBINARY: case SQLBINARY: case SQLIMAGE: { zv = emalloc(sizeof(zval)); ZVAL_STRINGL(zv, (DBCHAR *) data, data_len); break; } #ifdef SQLMSDATETIME2 case SQLMSDATETIME2: #endif case SQLDATETIME: case SQLDATETIM4: { size_t dl; DBDATEREC di; DBDATEREC dt; dbconvert(H->link, coltype, data, -1, SQLDATETIME, (LPBYTE) &dt, -1); dbdatecrack(H->link, &di, (DBDATETIME *) &dt); dl = spprintf(&tmp_data, 20, "%04d-%02d-%02d %02d:%02d:%02d", #if defined(PHP_DBLIB_IS_MSSQL) || defined(MSDBLIB) di.year, di.month, di.day, di.hour, di.minute, di.second #else di.dateyear, di.datemonth+1, di.datedmonth, di.datehour, di.dateminute, di.datesecond #endif ); zv = emalloc(sizeof(zval)); ZVAL_STRINGL(zv, tmp_data, dl); efree(tmp_data); break; } case SQLFLT4: { zv = emalloc(sizeof(zval)); ZVAL_DOUBLE(zv, *(DBFLT4 *) data); break; } case SQLFLT8: { zv = emalloc(sizeof(zval)); ZVAL_DOUBLE(zv, *(DBFLT8 *) data); break; } case SQLINT8: { zv = emalloc(sizeof(zval)); ZVAL_LONG(zv, *(DBBIGINT *) data); break; } case SQLINT4: { zv = emalloc(sizeof(zval)); ZVAL_LONG(zv, *(DBINT *) data); break; } case SQLINT2: { zv = emalloc(sizeof(zval)); ZVAL_LONG(zv, *(DBSMALLINT *) data); break; } case SQLINT1: case SQLBIT: { zv = emalloc(sizeof(zval)); ZVAL_LONG(zv, *(DBTINYINT *) data); break; } case SQLDECIMAL: case SQLNUMERIC: case SQLMONEY: case SQLMONEY4: case SQLMONEYN: { DBFLT8 float_value; dbconvert(NULL, coltype, data, 8, SQLFLT8, (LPBYTE) &float_value, -1); zv = emalloc(sizeof(zval)); ZVAL_DOUBLE(zv, float_value); break; } case SQLUNIQUE: { if (H->stringify_uniqueidentifier) { /* 36-char hex string representation */ tmp_data_len = 36; tmp_data = safe_emalloc(tmp_data_len, sizeof(char), 1); data_len = dbconvert(NULL, SQLUNIQUE, data, data_len, SQLCHAR, (LPBYTE) tmp_data, tmp_data_len); php_strtoupper(tmp_data, data_len); zv = emalloc(sizeof(zval)); ZVAL_STRINGL(zv, tmp_data, data_len); efree(tmp_data); } else { /* 16-byte binary representation */ zv = emalloc(sizeof(zval)); ZVAL_STRINGL(zv, (DBCHAR *) data, 16); } break; } default: { if (dbwillconvert(coltype, SQLCHAR)) { pdo_dblib_stmt_stringify_col(coltype, data, data_len, &zv); } break; } } } } if (zv != NULL) { *ptr = (char*)zv; *len = sizeof(zval); } else { *ptr = NULL; *len = 0; } *caller_frees = 1; return 1; }
void MSSqlDatatable::update() { // clear. this->clear(); # ifdef _FREETDS DBPROCESS* proc = (DBPROCESS*)_proc; // update. uint const ncols = dbnumcols(proc); struct COL { char *name; char *buffer; int type, size, status; } *columns, *pcol; if ((columns = (COL*)calloc(ncols, sizeof(struct COL))) == NULL) { return; } RETCODE sta = 0; rows_type& rows = this->_rows; cols_type& cols = this->_cols; cols.resize(ncols); //Read metadata and bind. for (pcol = columns; pcol - columns < ncols; pcol++) { int c = (int)(pcol - columns + 1); pcol->name = dbcolname(proc, c); pcol->type = dbcoltype(proc, c); pcol->size = dbcollen(proc, c); // add cols. cols[c - 1] = new variant_t(pcol->name, core::copy); if (SYBCHAR != pcol->type) { pcol->size = dbwillconvert(pcol->type, SYBCHAR); } if ((pcol->buffer = (char*)calloc(1, pcol->size + 1)) == NULL){ break; } sta = dbbind(proc, c, NTBSTRINGBIND, pcol->size + 1, (byte*)pcol->buffer); if (sta == FAIL) { break; } sta = dbnullbind(proc, c, &pcol->status); if (sta == FAIL) { break; } } // Get rows. while ((sta = dbnextrow(proc)) != NO_MORE_ROWS){ switch (sta) { case REG_ROW: { DBMSqlDatatable::row_type *row = new DBMSqlDatatable::row_type; row->resize(ncols); for (pcol=columns; pcol - columns < ncols; ++pcol) { int c = (int)(pcol - columns + 1); char const* buffer = pcol->status == -1 ? "" : pcol->buffer; (*row)[c - 1] = new variant_t(buffer, core::copy); } rows.push_back(row); } break; } } /* free metadata and data buffers */ for (pcol=columns; pcol - columns < ncols; pcol++) { free(pcol->buffer); } free(columns); # endif # ifdef _MSSQL _RecordsetPtr& rcdset = *((_RecordsetPtr*)_proc); usize const ncols = (usize const)rcdset->Fields->GetCount(); rows_type& rows = this->_rows; cols_type& cols = this->_cols; cols.resize(ncols); // read cols. for (uint idx = 0; idx < ncols; ++idx) { # ifdef NNT_DEBUG try { # endif _bstr_t name = rcdset->Fields->GetItem((long)idx)->GetName(); cols[idx] = new variant_t((char const*)name, core::copy); # ifdef NNT_DEBUG } catch (_com_error& err) { _bstr_t msg = err.ErrorMessage(); trace_msg((char const*)msg); } # endif } // read rows. while (!rcdset->adoEOF) { row_type* row = new row_type; row->resize(ncols); for (uindex idx = 0; idx < ncols; ++idx) { # ifdef NNT_DEBUG try { # endif _bstr_t val = rcdset->GetCollect((long)idx); (*row)[idx] = new variant_t((char const*)val, core::copy); # ifdef NNT_DEBUG } catch (_com_error& err) { _bstr_t msg = err.ErrorMessage(); trace_msg((char const*)msg); } # endif } rows.push_back(row); rcdset->MoveNext(); } # endif }