Exemplo n.º 1
0
static void
print_results(SQLHSTMT hStmt) 
{
	static const char dashes[] = "----------------------------------------------------------------" /* each line is 64 */
				     "----------------------------------------------------------------"
				     "----------------------------------------------------------------"
				     "----------------------------------------------------------------";
	
	struct METADATA *metadata = NULL;
	
	struct DATA *data = NULL;
	
	SQLSMALLINT ncols = 0;
	RETCODE erc;
	int c, ret;

	/* 
	 * Process each resultset
	 */
	do {
		/* free metadata, in case it was previously allocated */
		free_metadata(metadata, data, ncols);
		metadata = NULL;
		data = NULL;
		ncols = 0;
		
		/* 
		 * Allocate memory for metadata and bound columns 
		 */
		if ((erc = SQLNumResultCols(hStmt, &ncols)) != SQL_SUCCESS){
			odbc_perror(hStmt, erc, "SQLNumResultCols", "failed");
			exit(EXIT_FAILURE);
		} 
		
		metadata = (struct METADATA*) calloc(ncols, sizeof(struct METADATA));
		assert(metadata);

		data = (struct DATA*) calloc(ncols, sizeof(struct DATA));
		assert(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 the address of the buffer we want filled as each row is fetched.
		 */

		fprintf(options.verbose, "Metadata\n");
		fprintf(options.verbose, "%-6s  %-30s  %-10s  %-18s  %-6s  %-6s  \n", 
					 "col", "name", "type value", "type name", "size", "varies");
		fprintf(options.verbose, "%.6s  %.30s  %.10s  %.18s  %.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. */
			SQLCHAR name[512];
			SQLSMALLINT namelen, ndigits, fnullable;

			if ((erc = SQLDescribeCol(hStmt, c+1, name, sizeof(name), &namelen, 
							&metadata[c].type, &metadata[c].size,
							&ndigits, &fnullable)) != SQL_SUCCESS) {
				odbc_perror(hStmt, erc, "SQLDescribeCol", "failed");
				exit(EXIT_FAILURE);
			} 
			assert(namelen < sizeof(name));
			name[namelen] = '\0';
			metadata[c].name = strdup((char *) name);
			metadata[c].width = (ndigits > metadata[c].size)? ndigits : metadata[c].size;
			
			if (is_character_data(metadata[c].type)) {
				SQLHDESC hDesc;
				SQLINTEGER buflen;
				
				metadata[c].nchars = metadata[c].size;
				
				if ((erc = SQLAllocHandle(SQL_HANDLE_DESC, hStmt, &hDesc)) != SQL_SUCCESS) {
					odbc_perror(hStmt, erc, "SQLAllocHandle", "failed");
					exit(EXIT_FAILURE);
				} 
				if ((erc = SQLGetDescField(hDesc, c+1, SQL_DESC_OCTET_LENGTH, 
								&metadata[c].size, sizeof(metadata[c].size), 
								&buflen)) != SQL_SUCCESS) {
					odbc_perror(hStmt, erc, "SQLGetDescField", "failed");
					exit(EXIT_FAILURE);
				} 
				
				if ((erc = SQLFreeHandle(SQL_HANDLE_DESC, hStmt)) != SQL_SUCCESS) {
					odbc_perror(hStmt, erc, "SQLFreeHandle", "failed");
					exit(EXIT_FAILURE);
				} 
			}

			fprintf(options.verbose, "%6d  %30s  %10d  %18s  %6lu  %6d  \n", 
				c+1, metadata[c].name, (int)metadata[c].type, prtype(metadata[c].type), 
				(long unsigned int) metadata[c].size,  -1);

#if 0
			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));

			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);
#endif				
			/* 
			 * 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?"
			 */
			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 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.  
			 */

			data[c].buffer = calloc(1, bufsize(&metadata[c]));
			assert(data[c].buffer);

			if ((erc = SQLBindCol(hStmt, c+1, SQL_C_CHAR, (SQLPOINTER)data[c].buffer, 
						bufsize(&metadata[c]), &data[c].len)) != SQL_SUCCESS){
				odbc_perror(hStmt, erc, "SQLBindCol", "failed");
				exit(EXIT_FAILURE);
			} 

		}
		
		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 (ncols > 0 && (erc = SQLFetch(hStmt)) != SQL_NO_DATA) {
			switch(erc) {
			case SQL_SUCCESS_WITH_INFO:
				print_error_message(SQL_HANDLE_STMT, hStmt);
			case SQL_SUCCESS:
				break;
			default:
				odbc_perror(hStmt, erc, "SQLFetch", "failed");
				exit(EXIT_FAILURE);
			}
			for (c=0; c < ncols; c++) {
				char *s;
				switch (data[c].len) { /* handle nulls */
				case SQL_NULL_DATA: /* is null */
					fprintf(stdout, metadata[c].format_string, "NULL");
					break;
				default:
					assert(data[c].len > 0);
					s = calloc(1, 1 + data[c].len);
					assert(s);
					memcpy(s, data[c].buffer, data[c].len);
					fprintf(stdout, metadata[c].format_string, s);
					free(s);
					break;
				}
			}
		}
		if (ncols > 0 && erc == SQL_NO_DATA)
			print_error_message(SQL_HANDLE_STMT, hStmt);

		erc = SQLMoreResults(hStmt);
		fprintf(options.verbose, "SQLMoreResults returned %s\n", prret(erc));
		switch (erc) {
		case SQL_NO_DATA:
			print_error_message(SQL_HANDLE_STMT, hStmt);
			break;
		case SQL_SUCCESS_WITH_INFO:
			print_error_message(SQL_HANDLE_STMT, hStmt);
		case SQL_SUCCESS:
			continue;
		default:
			odbc_perror(hStmt, erc, "SQLMoreResults", "failed");
			exit(EXIT_FAILURE);
		}
	} while (erc != SQL_NO_DATA);
	
	if (erc != SQL_NO_DATA) {
		assert(erc != SQL_STILL_EXECUTING);
		odbc_perror(hStmt, erc, "SQLMoreResults", "failed");
		exit(EXIT_FAILURE);
	} 
}
Exemplo n.º 2
0
void
zzzcode(NODE *p, int c)
{
	NODE *l, *r;
	TWORD t;
	int m;
	char *ch;

	switch (c) {
	case 'N':  /* logical ops, turned into 0-1 */
		/* use register given by register 1 */
		cbgen( 0, m=getlab2());
		deflab( p->n_label );
		printf( "	clrl	%s\n", rnames[getlr( p, '1' )->n_rval] );
		deflab( m );
		return;

	case 'A': /* Assign a constant directly to a memory position */
		printf("\t");
		if (p->n_type < LONG || ISPTR(p->n_type))
			casg(p);
		else
			casg64(p);
		printf("\n");
		break;

	case 'B': /* long long compare */
		twollcomp(p);
		break;

	case 'C':	/* num words pushed on arg stack */
		printf("$%d", p->n_qual);
		break;

	case 'D':	/* INCR and DECR */
		zzzcode(p->n_left, 'A');
		printf("\n	");

#if 0
	case 'E':	/* INCR and DECR, FOREFF */
		if (p->n_right->n_lval == 1)
			{
			printf("%s", (p->n_op == INCR ? "inc" : "dec") );
			prtype(p->n_left);
			printf("	");
			adrput(stdout, p->n_left);
			return;
			}
		printf("%s", (p->n_op == INCR ? "add" : "sub") );
		prtype(p->n_left);
		printf("2	");
		adrput(stdout, p->n_right);
		printf(",");
		adrput(p->n_left);
		return;
#endif

	case 'F':	/* register type of right operand */
		{
		register NODE *n;
		register int ty;

		n = getlr( p, 'R' );
		ty = n->n_type;

		if (x2debug) printf("->%d<-", ty);

		if ( ty==DOUBLE) printf("d");
		else if ( ty==FLOAT ) printf("f");
		else printf("l");
		return;
		}

	case 'G': /* emit conversion instructions */
		sconv(p);
		break;

	case 'J': /* jump or ret? */
		{
			struct interpass *ip =
			    DLIST_PREV((struct interpass *)p2env.epp, qelem);
			if (ip->type != IP_DEFLAB ||
			    ip->ip_lbl != getlr(p, 'L')->n_lval)
				expand(p, FOREFF, "jbr	LL");
			else
				printf("ret");
		}
		break;

	case 'L':	/* type of left operand */
	case 'R':	/* type of right operand */
		{
		register NODE *n;

		n = getlr ( p, c);
		if (x2debug) printf("->%d<-", n->n_type);

		prtype(n);
		return;
		}

	case 'O': /* print out emulated ops */
		expand(p, FOREFF, "\tmovq	AR,-(%sp)\n");
		expand(p, FOREFF, "\tmovq	AL,-(%sp)\n");
		if (p->n_op == DIV && p->n_type == ULONGLONG) ch = "udiv";
		else if (p->n_op == DIV) ch = "div";
		else if (p->n_op == MOD && p->n_type == ULONGLONG) ch = "umod";
		else if (p->n_op == MOD) ch = "mod";
		else if (p->n_op == MUL) ch = "mul";
		else ch = 0, comperr("ZO %d", p->n_op);
		printf("\tcalls	$4,__%sdi3\n", ch);
		break;


	case 'Z':	/* complement mask for bit instr */
		printf("$%Ld", ~p->n_right->n_lval);
		return;

	case 'U':	/* 32 - n, for unsigned right shifts */
		t = DEUNSIGN(p->n_left->n_type);
		m = t == CHAR ? 8 : t == SHORT ? 16 : 32;
		printf("$" CONFMT, m - p->n_right->n_lval);
		return;

	case 'T':	/* rounded structure length for arguments */
		{
		int size;

		size = p->n_stsize;
		SETOFF( size, 4);
		printf("$%d", size);
		return;
		}

	case 'S':  /* structure assignment */
		{
			register int size;

			size = p->n_stsize;
			l = r = NULL; /* XXX gcc */
			if( p->n_op == STASG ){
				l = p->n_left;
				r = p->n_right;

				}
			else if( p->n_op == STARG ){
				/* store an arg into a temporary */
				printf("\tsubl2 $%d,%%sp\n",
				    size < 4 ? 4 : size);
				l = mklnode(OREG, 0, SP, INT);
				r = p->n_left;
				}
			else cerror( "STASG bad" );

			if( r->n_op == ICON ) r->n_op = NAME;
			else if( r->n_op == REG ) r->n_op = OREG;
			else if( r->n_op != OREG ) cerror( "STASG-r" );

		if (size != 0) {
			if( size <= 0 || size > 65535 )
				cerror("structure size <0=0 or >65535");

			switch(size) {
				case 1:
					printf("	movb	");
					break;
				case 2:
					printf("	movw	");
					break;
				case 4:
					printf("	movl	");
					break;
				case 8:
					printf("	movq	");
					break;
				default:
					printf("	movc3	$%d,", size);
					break;
			}
			adrput(stdout, r);
			printf(",");
			adrput(stdout, l);
			printf("\n");
		}

			if( r->n_op == NAME ) r->n_op = ICON;
			else if( r->n_op == OREG ) r->n_op = REG;
			if (p->n_op == STARG)
				tfree(l);

			}
		break;

	default:
		comperr("illegal zzzcode '%c'", c);
	}
}