Пример #1
0
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;
}
Пример #2
0
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;
	}
}
Пример #3
0
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;
}
Пример #4
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;
}
Пример #5
0
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;
}
Пример #6
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;
}
Пример #7
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;
}
Пример #8
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;
}
Пример #9
0
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;
}
Пример #10
0
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);		
}
Пример #11
0
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;
}
Пример #12
0
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;
  }
}
Пример #13
0
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);
}
Пример #14
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;
	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;
}
Пример #15
0
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;
}
Пример #16
0
/*
 * 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;
}
Пример #17
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;
}
Пример #18
0
// 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 );
    }
}