size_t CDBL_RowResult::ReadItem(void* buffer, size_t buffer_size,bool* is_null) { if ((unsigned int) m_CurrItem >= GetDefineParams().GetNum()) { if (is_null) *is_null = true; return 0; } const BYTE* d_ptr = Check(dbdata (GetCmd(), m_CurrItem + 1)); DBINT d_len = Check(dbdatlen(GetCmd(), m_CurrItem + 1)); if (d_ptr == 0 || d_len < 1) { // NULL value ++m_CurrItem; m_Offset = 0; if (is_null) *is_null = true; return 0; } if (is_null) *is_null = false; if ((size_t) (d_len - m_Offset) < buffer_size) { buffer_size = d_len - m_Offset; } if (buffer) memcpy(buffer, d_ptr + m_Offset, buffer_size); m_Offset += buffer_size; if (m_Offset >= (size_t) d_len) { m_Offset = 0; ++m_CurrItem; } return buffer_size; }
int syb_put_data (int no_des, int i, char *result) { DBPROCESS * dbp = descriptor[no_des]; data_type = dbcoltype (dbp, i); if (data_type == SYBBINARY) { /* Prefix the string by `Ox' for Hexa */ result[0] = '0'; result[1] = 'x'; size = dbconvert (dbp, data_type, dbdata (dbp, i), dbdatlen (dbp, i), SYBCHAR, &(result[2]), max_size-2); if (size != -1) { size += 2; } } else if (data_type == SYBLONGBINARY) { size = dbdatlen(dbp,i); memcpy(result, (char *)dbdata(dbp,i), size); size = TXTLEN(result)*2; } else { size = dbconvert (dbp, data_type, dbdata (dbp, i), dbdatlen (dbp, i), SYBCHAR, result, max_size); } if (size == -1) { return 0; } else { return size; } }
double syb_get_float_data (int no_des, int i) { double result; float result_real; DBPROCESS * dbp = descriptor[no_des]; data_type = dbcoltype (dbp, i); if ( (data_type == SYBFLT8) || (data_type == SYBMONEY) ) { dbconvert (dbp, data_type, dbdata (dbp, i), dbdatlen (dbp, i), SYBFLT8, &result, sizeof (result)); return result; } else if (data_type == SYBREAL) { dbconvert (dbp, data_type, dbdata (dbp, i), dbdatlen (dbp, i), SYBREAL, &result_real, sizeof (result_real)); return result_real; } return 0.0; }
int syb_get_date_data (int no_des, int i) { DBPROCESS * dbp = descriptor[no_des]; data_type = dbcoltype (dbp, i); if (data_type == SYBDATETIME) { if (dbdatecrack (dbp, &date, (DBDATETIME *) dbdata (dbp, i)) == FAIL) { return 0; } } return 1; }
int syb_get_boolean_data (int no_des, int i) { int result; DBPROCESS * dbp = descriptor[no_des]; data_type = dbcoltype (dbp,i); if (data_type == SYBBIT) { dbconvert (dbp, data_type, dbdata (dbp, i), dbdatlen (dbp, i), SYBINT4, &result, sizeof (result)); return (int) result; } return 0; }
int syb_get_integer_16_data (int no_des, int i) { int result; DBPROCESS * dbp = descriptor[no_des]; data_type = dbcoltype (dbp, i); if ( (data_type == SYBINT1) || (data_type == SYBINT2) || (data_type == SYBINT4) ) { dbconvert (dbp, data_type, dbdata (dbp, i), dbdatlen (dbp, i), SYBINT2, &result, sizeof (result)); return (int) result; } return 0; }
float syb_get_real_data (int no_des, int i) { float result_real; /*char result_real;*/ DBPROCESS * dbp = descriptor[no_des]; data_type = dbcoltype (dbp, i); if (data_type == SYBREAL) { dbconvert (dbp, data_type, dbdata (dbp, i), dbdatlen (dbp, i), SYBREAL, &result_real, sizeof (result_real)); return (float) result_real; } return 0.0; }
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; }
char *dblib_handle_last_id(pdo_dbh_t *dbh, const char *name, size_t *len) { pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data; RETCODE ret; char *id = NULL; /* * Would use scope_identity() but it's not implemented on Sybase */ if (FAIL == dbcmd(H->link, "SELECT @@IDENTITY")) { return NULL; } if (FAIL == dbsqlexec(H->link)) { return NULL; } ret = dbresults(H->link); if (ret == FAIL || ret == NO_MORE_RESULTS) { dbcancel(H->link); return NULL; } ret = dbnextrow(H->link); if (ret == FAIL || ret == NO_MORE_ROWS) { dbcancel(H->link); return NULL; } if (dbdatlen(H->link, 1) == 0) { dbcancel(H->link); return NULL; } id = emalloc(32); *len = dbconvert(NULL, (dbcoltype(H->link, 1)) , (dbdata(H->link, 1)) , (dbdatlen(H->link, 1)), SQLCHAR, (BYTE *)id, (DBINT)-1); dbcancel(H->link); return id; }
int BCPInRecords(ifstream bcpInfile, char *szExtSystem) { int intImportCount = 0; // Get current server datetime DBDATETIME dtCurDateTime; dtCurDateTime.dtdays = 0; dbcmd(dbproc, "select getdate()"); dbsqlexec(dbproc); if (dbresults(dbproc) == SUCCEED) if (dbnextrow(dbproc) != NO_MORE_ROWS) dbconvert(dbproc, SYBDATETIME, (dbdata(dbproc, 1)), (DBINT)-1, SYBDATETIME, (BYTE*)&dtCurDateTime, (DBINT)-1); if ( dtCurDateTime.dtdays == 0 ) return -1; // Call bcp_init if ( bcp_init(dbproc, "cags..x_import", NULL, "bcp_err.out", DB_IN) != SUCCEED ) { errfile << ERROR_PREFIX << "failed bcp_init" << endl; return -1; } bcp_bind(dbproc, (BYTE*)szExtSystem, 0, -1, (BYTE*)"", 1, SYBCHAR, 1); bcp_bind(dbproc, (BYTE*)&dtCurDateTime, 0, -1, NULL, 0, SYBDATETIME, 2); bcp_bind(dbproc, (BYTE*)&intImportCount, 0, -1, NULL, 0, SYBINT2, 3); bcp_bind(dbproc, (BYTE*)buffer, 0, -1, (BYTE*)"", 1, SYBVARCHAR, 4); while ( !bcpInfile.eof() ) { bcpInfile.getline(buffer, 255); // cout << buffer << endl; intImportCount++; // Bulk copy it into the database */ bcp_sendrow(dbproc); } // Close the bulk copy process so all the changes are committed return bcp_done(dbproc); }
static ngx_int_t ngx_dbd_freetds_field_read(ngx_dbd_t *dbd, u_char **value, off_t *offset, size_t *size, size_t *total) { ngx_dbd_freetds_ctx_t *ctx; ngx_log_debug0(NGX_LOG_DEBUG_MYSQL, dbd->log, 0, "dbd freetds field read"); ctx = dbd->ctx; if (ctx->cur_col++ == ctx->num_fields) { return NGX_DONE; } /* dbcollen(ctx->db, ctx->cur_col) */ /* dbvarylen(ctx->db, ctx->cur_col) */ /* dbcoltype(ctx->db, ctx->cur_col) */ /* dbcolutype */ /* dbcoltypeinfo */ /* dbcolinfo */ /* dbcolsource */ /* dbtablecolinfo */ /* dbwillconvert */ /* dbconvert */ *value = dbdata(ctx->db, (INT) ctx->cur_col); *size = dbdatlen(ctx->db, (INT) ctx->cur_col); *offset = 0; *total = *size; return NGX_OK; }
static VALUE rb_tinytds_result_insert(VALUE self) { GET_RESULT_WRAPPER(self); if (rwrap->client) { VALUE identity = Qnil; rb_tinytds_result_exec_helper(rwrap->client); dbcmd(rwrap->client, rwrap->cwrap->identity_insert_sql); if (nogvl_dbsqlexec(rwrap->client) != FAIL && nogvl_dbresults(rwrap->client) != FAIL && DBROWS(rwrap->client) != FAIL) { while (nogvl_dbnextrow(rwrap->client) != NO_MORE_ROWS) { int col = 1; BYTE *data = dbdata(rwrap->client, col); DBINT data_len = dbdatlen(rwrap->client, col); int null_val = ((data == NULL) && (data_len == 0)); if (!null_val) identity = LL2NUM(*(DBBIGINT *)data); } } return identity; } else { return Qnil; } }
static void print_results(DBPROCESS *dbproc) { static const char empty_string[] = ""; static const char dashes[] = "----------------------------------------------------------------" /* each line is 64 */ "----------------------------------------------------------------" "----------------------------------------------------------------" "----------------------------------------------------------------"; struct METADATA *metadata = NULL, return_status; struct DATA { char *buffer; int status; } *data = NULL; struct METACOMP { int numalts; struct METADATA *meta; struct DATA *data; } **metacompute = NULL; RETCODE erc; int row_code; int i, c, ret; int iresultset; int ncomputeids = 0, ncols = 0; /* * If using default column separator, we want columns to line up vertically, * so we use blank padding (STRINGBIND). * For any other separator, we use no padding. */ const int bindtype = (0 == strcmp(options.colsep, default_colsep))? STRINGBIND : NTBSTRINGBIND; /* * Set up each result set with dbresults() * This is more commonly implemented as a while() loop, but we're counting the result sets. */ fprintf(options.verbose, "%s:%d: calling dbresults: OK\n", options.appname, __LINE__); for (iresultset=1; (erc = dbresults(dbproc)) != NO_MORE_RESULTS; iresultset++) { if (erc == FAIL) { fprintf(stderr, "%s:%d: dbresults(), result set %d failed\n", options.appname, __LINE__, iresultset); return; } if (options.pivot.func) { const struct key_t *rk = &options.pivot.row_key, *ck = &options.pivot.col_key; erc = dbpivot(dbproc, rk->nkeys, rk->keys, ck->nkeys, ck->keys, options.pivot.func, options.pivot.val_col); } fprintf(options.verbose, "Result set %d\n", iresultset); /* Free prior allocations, if any. */ for (c=0; c < ncols; c++) { free(metadata[c].format_string); free(data[c].buffer); } free(metadata); metadata = NULL; free(data); data = NULL; ncols = 0; for (i=0; i < ncomputeids; i++) { for (c=0; c < metacompute[i]->numalts; c++) { free(metacompute[i]->meta[c].name); free(metacompute[i]->meta[c].format_string); } free(metacompute[i]->meta); free(metacompute[i]->data); free(metacompute[i]); } free(metacompute); metacompute = NULL; ncomputeids = 0; /* * Allocate memory for metadata and bound columns */ fprintf(options.verbose, "Allocating buffers\n"); ncols = dbnumcols(dbproc); metadata = (struct METADATA*) calloc(ncols, sizeof(struct METADATA)); assert(metadata); data = (struct DATA*) calloc(ncols, sizeof(struct DATA)); assert(data); /* metadata is more complicated only because there may be several compute ids for each result set */ fprintf(options.verbose, "Allocating compute buffers\n"); ncomputeids = dbnumcompute(dbproc); if (ncomputeids > 0) { metacompute = (struct METACOMP**) calloc(ncomputeids, sizeof(struct METACOMP*)); assert(metacompute); } for (i=0; i < ncomputeids; i++) { metacompute[i] = (struct METACOMP*) calloc(ncomputeids, sizeof(struct METACOMP)); assert(metacompute[i]); metacompute[i]->numalts = dbnumalts(dbproc, 1+i); fprintf(options.verbose, "%d columns found in computeid %d\n", metacompute[i]->numalts, 1+i); if (metacompute[i]->numalts > 0) { fprintf(options.verbose, "allocating column %d\n", 1+i); metacompute[i]->meta = (struct METADATA*) calloc(metacompute[i]->numalts, sizeof(struct METADATA)); assert(metacompute[i]->meta); metacompute[i]->data = (struct DATA*) calloc(metacompute[i]->numalts, sizeof(struct DATA)); assert(metacompute[i]->data); } } /* * For each column, get its name, type, and size. * Allocate a buffer to hold the data, and bind the buffer to the column. * "bind" here means to give db-lib the address of the buffer we want filled as each row is fetched. * TODO: Implement dbcoltypeinfo() for numeric/decimal datatypes. */ fprintf(options.verbose, "Metadata\n"); fprintf(options.verbose, "%-6s %-30s %-30s %-15s %-6s %-6s \n", "col", "name", "source", "type", "size", "varies"); fprintf(options.verbose, "%.6s %.30s %.30s %.15s %.6s %.6s \n", dashes, dashes, dashes, dashes, dashes, dashes); for (c=0; c < ncols; c++) { /* Get and print the metadata. Optional: get only what you need. */ char *name = dbcolname(dbproc, c+1); metadata[c].name = strdup(name ? (const char *) name : empty_string); name = dbcolsource(dbproc, c+1); metadata[c].source = (name)? name : empty_string; metadata[c].type = dbcoltype(dbproc, c+1); metadata[c].size = dbcollen(dbproc, c+1); assert(metadata[c].size != -1); /* -1 means indicates an out-of-range request*/ fprintf(options.verbose, "%6d %30s %30s %15s %6d %6d \n", c+1, metadata[c].name, metadata[c].source, dbprtype(metadata[c].type), metadata[c].size, dbvarylen(dbproc, c+1)); /* * Build the column header format string, based on the column width. * This is just one solution to the question, "How wide should my columns be when I print them out?" */ metadata[c].width = get_printable_size(metadata[c].type, metadata[c].size); if (metadata[c].width < strlen(metadata[c].name)) metadata[c].width = strlen(metadata[c].name); ret = set_format_string(&metadata[c], (c+1 < ncols)? options.colsep : "\n"); if (ret <= 0) { fprintf(stderr, "%s:%d: asprintf(), column %d failed\n", options.appname, __LINE__, c+1); return; } /* * Bind the column to our variable. * We bind everything to strings, because we want db-lib to convert everything to strings for us. * If you're performing calculations on the data in your application, you'd bind the numeric data * to C integers and floats, etc. instead. * * It is not necessary to bind to every column returned by the query. * Data in unbound columns are simply never copied to the user's buffers and are thus * inaccesible to the application. */ if (metadata[c].width < INT_MAX) { data[c].buffer = calloc(1, 1 + metadata[c].width); /* allow for null terminator */ assert(data[c].buffer); erc = dbbind(dbproc, c+1, bindtype, 0, (BYTE *) data[c].buffer); if (erc == FAIL) { fprintf(stderr, "%s:%d: dbbind(), column %d failed\n", options.appname, __LINE__, c+1); return; } erc = dbnullbind(dbproc, c+1, &data[c].status); if (erc == FAIL) { fprintf(stderr, "%s:%d: dbnullbind(), column %d failed\n", options.appname, __LINE__, c+1); return; } } else { /* We don't bind text buffers, but use dbreadtext instead. */ data[c].buffer = NULL; } } /* * Get metadata and bind the columns for any compute rows. */ for (i=0; i < ncomputeids; i++) { fprintf(options.verbose, "For computeid %d:\n", 1+i); for (c=0; c < metacompute[i]->numalts; c++) { /* read metadata */ struct METADATA *meta = &metacompute[i]->meta[c]; int nby, iby; BYTE *bylist; char *colname, *bynames; int altcolid = dbaltcolid(dbproc, i+1, c+1); metacompute[i]->meta[c].type = dbalttype(dbproc, i+1, c+1); metacompute[i]->meta[c].size = dbaltlen(dbproc, i+1, c+1); /* * Jump through hoops to determine a useful name for the computed column * If the query says "compute count(c) by a,b", we get a "by list" indicating a & b. */ bylist = dbbylist(dbproc, c+1, &nby); bynames = strdup("by ("); for (iby=0; iby < nby; iby++) { char *s = NULL; int ret = asprintf(&s, "%s%s%s", bynames, dbcolname(dbproc, bylist[iby]), (iby+1 < nby)? ", " : ")"); if (ret < 0) { fprintf(options.verbose, "Insufficient room to create name for column %d:\n", 1+c); break; } free(bynames); bynames = s; } if( altcolid == -1 ) { colname = "*"; } else { assert(0 < altcolid && altcolid <= dbnumcols(dbproc)); colname = metadata[--altcolid].name; } asprintf(&metacompute[i]->meta[c].name, "%s(%s)", dbprtype(dbaltop(dbproc, i+1, c+1)), colname); assert(metacompute[i]->meta[c].name); metacompute[i]->meta[c].width = get_printable_size(metacompute[i]->meta[c].type, metacompute[i]->meta[c].size); if (metacompute[i]->meta[c].width < strlen(metacompute[i]->meta[c].name)) metacompute[i]->meta[c].width = strlen(metacompute[i]->meta[c].name); ret = set_format_string(meta, (c+1 < metacompute[i]->numalts)? options.colsep : "\n"); if (ret <= 0) { free(bynames); fprintf(stderr, "%s:%d: asprintf(), column %d failed\n", options.appname, __LINE__, c+1); return; } fprintf(options.verbose, "\tcolumn %d is %s, type %s, size %d %s\n", c+1, metacompute[i]->meta[c].name, dbprtype(metacompute[i]->meta[c].type), metacompute[i]->meta[c].size, (nby > 0)? bynames : ""); free(bynames); /* allocate buffer */ assert(metacompute[i]->data); metacompute[i]->data[c].buffer = calloc(1, metacompute[i]->meta[c].width); assert(metacompute[i]->data[c].buffer); /* bind */ erc = dbaltbind(dbproc, i+1, c+1, bindtype, -1, (BYTE*) metacompute[i]->data[c].buffer); if (erc == FAIL) { fprintf(stderr, "%s:%d: dbaltbind(), column %d failed\n", options.appname, __LINE__, c+1); return; } } } fprintf(options.verbose, "\n"); fprintf(options.verbose, "Data\n"); if (!options.fquiet) { /* Print the column headers to stderr to keep them separate from the data. */ for (c=0; c < ncols; c++) { fprintf(options.headers, metadata[c].format_string, metadata[c].name); } /* Underline the column headers. */ for (c=0; c < ncols; c++) { fprintf(options.headers, metadata[c].format_string, dashes); } } /* * Print the data to stdout. */ while ((row_code = dbnextrow(dbproc)) != NO_MORE_ROWS) { switch (row_code) { case REG_ROW: for (c=0; c < ncols; c++) { if (metadata[c].width == INT_MAX) { /* TEXT/IMAGE */ BYTE *p = dbdata(dbproc, c+1); size_t len = dbdatlen(dbproc, c+1); if (len == 0) { fputs("NULL", stdout); } else { BYTE *pend = p + len; switch(dbcoltype(dbproc, c+1)) { case SYBTEXT: if (fwrite(p, len, 1, stdout) != 1) { perror("could not write to output file"); exit(EXIT_FAILURE); } break; default: /* image, binary */ fprintf(stdout, "0x"); for (; p < pend; p++) { printf("%02hx", (unsigned short int)*p); } break; } } fprintf(stdout, metadata[c].format_string, ""); /* col/row separator */ continue; } switch (data[c].status) { /* handle nulls */ case -1: /* is null */ /* TODO: FreeTDS 0.62 does not support dbsetnull() */ fprintf(stdout, metadata[c].format_string, "NULL"); break; case 0: /* case >1 is datlen when buffer is too small */ default: fprintf(stdout, metadata[c].format_string, data[c].buffer); break; } } break; case BUF_FULL: assert(row_code != BUF_FULL); break; case FAIL: fprintf(stderr, "bsqldb: fatal error: dbnextrow returned FAIL\n"); assert(row_code != FAIL); exit(EXIT_FAILURE); break; default: /* computeid */ fprintf(options.verbose, "Data for computeid %d\n", row_code); for (c=0; c < metacompute[row_code-1]->numalts; c++) { char fmt[256] = "%-"; struct METADATA *meta = &metacompute[row_code-1]->meta[c]; /* left justify the names */ strcat(fmt, &meta->format_string[1]); fprintf(options.headers, fmt, meta->name); } /* Underline the column headers. */ for (c=0; c < metacompute[row_code-1]->numalts; c++) { fprintf(options.headers, metacompute[row_code-1]->meta[c].format_string, dashes); } for (c=0; c < metacompute[row_code-1]->numalts; c++) { struct METADATA *meta = &metacompute[row_code-1]->meta[c]; struct DATA *data = &metacompute[row_code-1]->data[c]; switch (data->status) { /* handle nulls */ case -1: /* is null */ /* TODO: FreeTDS 0.62 does not support dbsetnull() */ fprintf(stdout, meta->format_string, "NULL"); break; case 0: /* case >1 is datlen when buffer is too small */ default: fprintf(stdout, meta->format_string, data->buffer); break; } } } } /* Check return status */ if (!options.fquiet) { fprintf(options.verbose, "Retrieving return status... "); if (dbhasretstat(dbproc) == TRUE) { fprintf(stderr, "Procedure returned %d\n", dbretstatus(dbproc)); } else { fprintf(options.verbose, "none\n"); } } /* * Get row count, if available. */ if (!options.fquiet) { if (DBCOUNT(dbproc) > -1) fprintf(stderr, "%d rows affected\n", DBCOUNT(dbproc)); else fprintf(stderr, "@@rowcount not available\n"); } /* * Check return parameter values */ fprintf(options.verbose, "Retrieving output parameters... "); if (dbnumrets(dbproc) > 0) { for (i = 1; i <= dbnumrets(dbproc); i++) { char parameter_string[1024]; return_status.name = dbretname(dbproc, i); fprintf(stderr, "ret name %d is %s\n", i, return_status.name); return_status.type = dbrettype(dbproc, i); fprintf(options.verbose, "\n\tret type %d is %d", i, return_status.type); return_status.size = dbretlen(dbproc, i); fprintf(options.verbose, "\n\tret len %d is %d\n", i, return_status.size); dbconvert(dbproc, return_status.type, dbretdata(dbproc, i), return_status.size, SYBVARCHAR, (BYTE *) parameter_string, -1); fprintf(stderr, "ret data %d is %s\n", i, parameter_string); } } else { fprintf(options.verbose, "none\n"); } } /* wend dbresults */ fprintf(options.verbose, "%s:%d: dbresults() returned NO_MORE_RESULTS (%d):\n", options.appname, __LINE__, erc); }
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; }
static VALUE rb_tinytds_result_fetch_row(VALUE self, ID timezone, int symbolize_keys, int as_array) { VALUE row; /* Storing Values */ unsigned int i; /* Wrapper And Local Vars */ GET_RESULT_WRAPPER(self); /* Create Empty Row */ row = as_array ? rb_ary_new2(rwrap->number_of_fields) : rb_hash_new(); for (i = 0; i < rwrap->number_of_fields; i++) { VALUE val = Qnil; int col = i+1; int coltype = dbcoltype(rwrap->client, col); BYTE *data = dbdata(rwrap->client, col); DBINT data_len = dbdatlen(rwrap->client, col); int null_val = ((data == NULL) && (data_len == 0)); if (!null_val) { switch(coltype) { case SYBINT1: val = INT2FIX(*(DBTINYINT *)data); break; case SYBINT2: val = INT2FIX(*(DBSMALLINT *)data); break; case SYBINT4: val = INT2NUM(*(DBINT *)data); break; case SYBINT8: val = LL2NUM(*(DBBIGINT *)data); break; case SYBBIT: val = *(int *)data ? Qtrue : Qfalse; break; case SYBNUMERIC: case SYBDECIMAL: { DBTYPEINFO *data_info = dbcoltypeinfo(rwrap->client, col); int data_slength = (int)data_info->precision + (int)data_info->scale + 1; char converted_decimal[data_slength]; dbconvert(rwrap->client, coltype, data, data_len, SYBVARCHAR, (BYTE *)converted_decimal, -1); val = rb_funcall(cBigDecimal, intern_new, 1, rb_str_new2((char *)converted_decimal)); break; } case SYBFLT8: { double col_to_double = *(double *)data; val = (col_to_double == 0.000000) ? opt_float_zero : rb_float_new(col_to_double); break; } case SYBREAL: { float col_to_float = *(float *)data; val = (col_to_float == 0.0) ? opt_float_zero : rb_float_new(col_to_float); break; } case SYBMONEY: { DBMONEY *money = (DBMONEY *)data; char converted_money[25]; long long money_value = ((long long)money->mnyhigh << 32) | money->mnylow; sprintf(converted_money, "%" LONG_LONG_FORMAT, money_value); val = rb_funcall(cBigDecimal, intern_new, 2, rb_str_new2(converted_money), opt_four); val = rb_funcall(val, intern_divide, 1, opt_tenk); break; } case SYBMONEY4: { DBMONEY4 *money = (DBMONEY4 *)data; char converted_money[20]; sprintf(converted_money, "%f", money->mny4 / 10000.0); val = rb_funcall(cBigDecimal, intern_new, 1, rb_str_new2(converted_money)); break; } case SYBBINARY: case SYBIMAGE: val = rb_str_new((char *)data, (long)data_len); #ifdef HAVE_RUBY_ENCODING_H rb_enc_associate(val, binaryEncoding); #endif break; case 36: { // SYBUNIQUE char converted_unique[37]; dbconvert(rwrap->client, coltype, data, 37, SYBVARCHAR, (BYTE *)converted_unique, -1); val = ENCODED_STR_NEW2(converted_unique); break; } case SYBDATETIME4: { DBDATETIME new_data; dbconvert(rwrap->client, coltype, data, data_len, SYBDATETIME, (BYTE *)&new_data, sizeof(new_data)); data = (BYTE *)&new_data; data_len = sizeof(new_data); } case SYBDATETIME: { DBDATEREC dr; dbdatecrack(rwrap->client, &dr, (DBDATETIME *)data); if (dr.year + dr.month + dr.day + dr.hour + dr.minute + dr.second + dr.millisecond != 0) { val = rb_funcall(rb_cTime, timezone, 7, INT2NUM(dr.year), INT2NUM(dr.month), INT2NUM(dr.day), INT2NUM(dr.hour), INT2NUM(dr.minute), INT2NUM(dr.second), INT2NUM(dr.millisecond*1000)); } break; } case 40: // SYBMSDATE case 41: // SYBMSTIME case 42: // SYBMSDATETIME2 case 43: { // SYBMSDATETIMEOFFSET #ifdef DBVERSION_73 if (dbtds(rwrap->client) >= DBTDS_7_3) { DBDATEREC2 dr2; dbanydatecrack(rwrap->client, &dr2, coltype, data); switch(coltype) { case 40: { // SYBMSDATE val = rb_funcall(cDate, intern_new, 3, INT2NUM(dr2.year), INT2NUM(dr2.month), INT2NUM(dr2.day)); break; } case 41: { // SYBMSTIME VALUE rational_nsec = rb_Rational(INT2NUM(dr2.nanosecond), opt_onek); val = rb_funcall(rb_cTime, timezone, 7, INT2NUM(1900), INT2NUM(1), INT2NUM(1), INT2NUM(dr2.hour), INT2NUM(dr2.minute), INT2NUM(dr2.second), rational_nsec); break; } case 42: { // SYBMSDATETIME2 VALUE rational_nsec = rb_Rational(INT2NUM(dr2.nanosecond), opt_onek); val = rb_funcall(rb_cTime, timezone, 7, INT2NUM(dr2.year), INT2NUM(dr2.month), INT2NUM(dr2.day), INT2NUM(dr2.hour), INT2NUM(dr2.minute), INT2NUM(dr2.second), rational_nsec); break; } case 43: { // SYBMSDATETIMEOFFSET long long numerator = ((long)dr2.second * (long long)1000000000) + (long long)dr2.nanosecond; VALUE rational_sec = rb_Rational(LL2NUM(numerator), opt_onebil); val = rb_funcall(rb_cTime, intern_new, 7, INT2NUM(dr2.year), INT2NUM(dr2.month), INT2NUM(dr2.day), INT2NUM(dr2.hour), INT2NUM(dr2.minute), rational_sec, INT2NUM(dr2.tzone*60)); break; } } } else { val = ENCODED_STR_NEW(data, data_len); } #else val = ENCODED_STR_NEW(data, data_len); #endif break; } case SYBCHAR: case SYBTEXT: val = ENCODED_STR_NEW(data, data_len); break; default: val = ENCODED_STR_NEW(data, data_len); break; } } if (as_array) { rb_ary_store(row, i, val); } else { VALUE key; if (rwrap->number_of_results == 0) { key = rb_ary_entry(rwrap->fields, i); } else { key = rb_ary_entry(rb_ary_entry(rwrap->fields, rwrap->number_of_results), i); } rb_hash_aset(row, key, val); } } return row; }
/* * Get the table information from sp_help, because it's easier to get the index information (eventually). * The column descriptions are in resultset #2, which is where we start. * As shown below, sp_help returns different columns for resultset #2, so we build a map. * Sybase Microsoft * ----------------- ---------------- * 1. Column_name Column_name * 2. Type Type * 3. Computed * 4. Length Length * 5. Prec Prec * 6. Scale Scale * 7. Nulls Nullable * 8. Default_name TrimTrail * 9. Rule_name FixedLenNullIn * 10. Access_Rule_name Collation * 11. Identity */ int print_ddl(DBPROCESS *dbproc, PROCEDURE *procedure) { struct DDL { char *name, *type, *length, *precision, *scale, *nullable; } *ddl = NULL; static int microsoft_colmap[6] = {1,2, 4,5,6,7}, sybase_colmap[6] = {1,2,3,4,5,6 }; int *colmap = NULL; FILE *create_index; RETCODE erc; int row_code, iresultset, i, ret; int maxnamelen = 0, nrows = 0; create_index = tmpfile(); assert(dbproc); assert(procedure); assert(create_index); /* sp_help returns several result sets. We want just the second one, for now */ for (iresultset=1; (erc = dbresults(dbproc)) != NO_MORE_RESULTS; iresultset++) { if (erc == FAIL) { fprintf(stderr, "%s:%d: dbresults(), result set %d failed\n", options.appname, __LINE__, iresultset); return 0; } /* Get the data */ while ((row_code = dbnextrow(dbproc)) != NO_MORE_ROWS) { struct DDL *p; char **coldesc[sizeof(struct DDL)/sizeof(char*)]; /* an array of pointers to the DDL elements */ assert(row_code == REG_ROW); /* Look for index data */ if (0 == strcmp("index_name", dbcolname(dbproc, 1))) { char *index_name, *index_description, *index_keys, *p, fprimary=0; DBINT datlen; assert(dbnumcols(dbproc) >=3 ); /* column had better be in range */ /* name */ datlen = dbdatlen(dbproc, 1); index_name = calloc(1, 1 + datlen); assert(index_name); memcpy(index_name, dbdata(dbproc, 1), datlen); /* kind */ datlen = dbdatlen(dbproc, 2); index_description = calloc(1, 1 + datlen); assert(index_description); memcpy(index_description, dbdata(dbproc, 2), datlen); /* columns */ datlen = dbdatlen(dbproc, 3); index_keys = calloc(1, 1 + datlen); assert(index_keys); memcpy(index_keys, dbdata(dbproc, 3), datlen); /* fix up the index attributes; we're going to use the string verbatim (almost). */ p = strstr(index_description, "located"); if (p) { *p = '\0'; /* we don't care where it's located */ } /* Microsoft version: clustered, unique, primary key located on PRIMARY */ p = strstr(index_description, "primary key"); if (p) { fprimary = 1; *p = '\0'; /* we don't care where it's located */ if ((p = strchr(index_description, ',')) != NULL) *p = '\0'; /* we use only the first term (clustered/nonclustered) */ } while ((p = strchr(index_description, ',')) != NULL) { *p = ' '; /* and we don't need the comma */ } /* Put it to a temporary file; we'll print it after the CREATE TABLE statement. */ if (fprimary) { fprintf(create_index, "ALTER TABLE %s.%s ADD CONSTRAINT %s PRIMARY KEY %s (%s)\nGO\n\n", procedure->owner, procedure->name, index_name, index_description, index_keys); } else { fprintf(create_index, "CREATE %s INDEX %s on %s.%s(%s)\nGO\n\n", index_description, index_name, procedure->owner, procedure->name, index_keys); } free(index_name); free(index_description); free(index_keys); continue; } /* skip other resultsets that don't describe the table's columns */ if (0 != strcmp("Column_name", dbcolname(dbproc, 1))) continue; /* Infer which columns we need from their names */ colmap = (0 == strcmp("Computed", dbcolname(dbproc, 3)))? microsoft_colmap : sybase_colmap; /* Make room for the next row */ p = realloc(ddl, ++nrows * sizeof(struct DDL)); if (p == NULL) { perror("error: insufficient memory for row DDL"); assert(p != NULL); exit(1); } ddl = p; /* take the address of each member, so we can loop through them */ coldesc[0] = &ddl[nrows-1].name; coldesc[1] = &ddl[nrows-1].type; coldesc[2] = &ddl[nrows-1].length; coldesc[3] = &ddl[nrows-1].precision; coldesc[4] = &ddl[nrows-1].scale; coldesc[5] = &ddl[nrows-1].nullable; for( i=0; i < sizeof(struct DDL)/sizeof(char*); i++) { DBINT datlen = dbdatlen(dbproc, colmap[i]); assert(datlen >= 0); /* column had better be in range */ if (datlen == 0) { *coldesc[i] = NULL; continue; } *coldesc[i] = calloc(1, 1 + datlen); /* calloc will null terminate */ if( *coldesc[i] == NULL ) { perror("error: insufficient memory for row detail"); assert(*coldesc[i] != NULL); exit(1); } memcpy(*coldesc[i], dbdata(dbproc, colmap[i]), datlen); /* * maxnamelen will determine how much room we allow for column names * in the CREATE TABLE statement */ if (i == 0) maxnamelen = (maxnamelen > datlen)? maxnamelen : datlen; } } /* wend */ } /* * We've collected the description for the columns in the 'ddl' array. * Now we'll print the CREATE TABLE statement in jkl's preferred format. */ printf("CREATE TABLE %s.%s\n", procedure->owner, procedure->name); for (i=0; i < nrows; i++) { static const char *varytypenames[] = { "char" , "nchar" , "varchar" , "nvarchar" , "text" , "ntext" , "unichar" , "univarchar" , "binary" , "varbinary" , "image" , NULL }; const char **t; char *type = NULL; int is_null; /* get size of decimal, numeric, char, and image types */ if (0 == strcasecmp("decimal", ddl[i].type) || 0 == strcasecmp("numeric", ddl[i].type)) { if (ddl[i].precision && 0 != strcasecmp("NULL", ddl[i].precision)) ret = asprintf(&type, "%s(%d,%d)", ddl[i].type, *(int*)ddl[i].precision, *(int*)ddl[i].scale); } else { for (t = varytypenames; *t; t++) { if (0 == strcasecmp(*t, ddl[i].type)) { ret = asprintf(&type, "%s(%d)", ddl[i].type, *(int*)ddl[i].length); break; } } } if (colmap == sybase_colmap) is_null = *(int*)ddl[i].nullable == 1; else is_null = (0 == strcasecmp("1", ddl[i].nullable) || 0 == strcasecmp("yes", ddl[i].nullable)); /* {(|,} name type [NOT] NULL */ printf("\t%c %-*s %-15s %3s NULL\n", (i==0? '(' : ','), maxnamelen, ddl[i].name, (type? type : ddl[i].type), (is_null? "" : "NOT")); free(type); } printf("\t)\nGO\n\n"); /* print the CREATE INDEX statements */ rewind(create_index); while ((i = fgetc(create_index)) != EOF) { fputc(i, stdout); } fclose(create_index); return nrows; }
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; }
// Aux. for CDBL_RowResult::GetItem() CDB_Object* CDBL_Result::GetItemInternal( I_Result::EGetItem policy, int item_no, SDBL_ColDescr* fmt, CDB_Object* item_buff ) { EDB_Type b_type = item_buff ? item_buff->GetType() : eDB_UnsupportedType; const BYTE* d_ptr = Check(dbdata (GetCmd(), item_no)); DBINT d_len = Check(dbdatlen(GetCmd(), item_no)); CDB_Object* val = s_GenericGetItem(fmt->data_type, item_buff, b_type, d_ptr, d_len); if (val) return val; switch (fmt->data_type) { case eDB_BigInt: { DBNUMERIC* v = (DBNUMERIC*) d_ptr; if (item_buff) { if (v) { if (b_type == eDB_Numeric) { ((CDB_Numeric*) item_buff)->Assign ((unsigned int) v->precision, (unsigned int) v->scale, (unsigned char*) DBNUMERIC_val(v)); } else if (b_type == eDB_BigInt) { *((CDB_BigInt*) item_buff) = numeric_to_longlong ((unsigned int) v->precision, DBNUMERIC_val(v)); } else { DATABASE_DRIVER_ERROR( "Wrong type of CDB_Object." + GetDbgInfo(), 230020 ); } } else item_buff->AssignNULL(); return item_buff; } return v ? new CDB_BigInt(numeric_to_longlong((unsigned int) v->precision, DBNUMERIC_val(v))) : new CDB_BigInt; } case eDB_Numeric: { DBNUMERIC* v = (DBNUMERIC*) d_ptr; if (item_buff) { if (v) { if (b_type == eDB_Numeric) { ((CDB_Numeric*) item_buff)->Assign ((unsigned int) v->precision, (unsigned int) v->scale, (unsigned char*) DBNUMERIC_val(v)); } else { DATABASE_DRIVER_ERROR( "Wrong type of CDB_Object." + GetDbgInfo(), 230020 ); } } else item_buff->AssignNULL(); return item_buff; } return v ? new CDB_Numeric((unsigned int) v->precision, (unsigned int) v->scale, (unsigned char*) DBNUMERIC_val(v)) : new CDB_Numeric; } case eDB_Text: { if (item_buff && b_type != eDB_Text && b_type != eDB_Image) { DATABASE_DRIVER_ERROR( "Wrong type of CDB_Object." + GetDbgInfo(), 130020 ); } CDB_Text* v = NULL; if (item_buff) { v = static_cast<CDB_Text*>(item_buff); if (policy == I_Result::eAssignLOB) { // Explicitly truncate previous value ... v->Truncate(); } } else { v = new CDB_Text; } _ASSERT(v); v->Append((char*) d_ptr, (int) d_len); return v; } case eDB_Image: { if (item_buff && b_type != eDB_Text && b_type != eDB_Image) { DATABASE_DRIVER_ERROR( "Wrong type of CDB_Object." + GetDbgInfo(), 130020 ); } CDB_Image* v = NULL; if (item_buff) { v = static_cast<CDB_Image*>(item_buff); if (policy == I_Result::eAssignLOB) { // Explicitly truncate previous value ... v->Truncate(); } } else { v = new CDB_Image; } _ASSERT(v); v->Append((void*) d_ptr, (int) d_len); return v; } default: DATABASE_DRIVER_ERROR( "Unexpected result type." + GetDbgInfo(), 130004 ); } }