⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fe-print.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------- * * fe-print.c *	  functions for pretty-printing query results * * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * These functions were formerly part of fe-exec.c, but they * didn't really belong there. * * IDENTIFICATION *	  $PostgreSQL: pgsql/src/interfaces/libpq/fe-print.c,v 1.64.2.3 2006/04/19 16:15:34 tgl Exp $ * *------------------------------------------------------------------------- */#include "postgres_fe.h"#include <signal.h>#ifdef WIN32#include "win32.h"#else#include <unistd.h>#include <sys/ioctl.h>#endif#ifdef HAVE_TERMIOS_H#include <termios.h>#else#ifndef WIN32#include <sys/termios.h>#endif#endif#include "libpq-fe.h"#include "libpq-int.h"#include "pqsignal.h"static void do_field(const PQprintOpt *po, const PGresult *res,		 const int i, const int j, const int fs_len,		 char **fields,		 const int nFields, const char **fieldNames,		 unsigned char *fieldNotNum, int *fieldMax,		 const int fieldMaxLen, FILE *fout);static char *do_header(FILE *fout, const PQprintOpt *po, const int nFields,		  int *fieldMax, const char **fieldNames, unsigned char *fieldNotNum,		  const int fs_len, const PGresult *res);static void output_row(FILE *fout, const PQprintOpt *po, const int nFields, char **fields,		   unsigned char *fieldNotNum, int *fieldMax, char *border,		   const int row_index);static void fill(int length, int max, char filler, FILE *fp);/* * PQprint() * * Format results of a query for printing. * * PQprintOpt is a typedef (structure) that containes * various flags and options. consult libpq-fe.h for * details * * This function should probably be removed sometime since psql * doesn't use it anymore. It is unclear to what extent this is used * by external clients, however. */voidPQprint(FILE *fout, const PGresult *res, const PQprintOpt *po){	int			nFields;	nFields = PQnfields(res);	if (nFields > 0)	{							/* only print rows with at least 1 field.  */		int			i,					j;		int			nTups;		int		   *fieldMax = NULL;	/* in case we don't use them */		unsigned char *fieldNotNum = NULL;		char	   *border = NULL;		char	  **fields = NULL;		const char **fieldNames;		int			fieldMaxLen = 0;		int			numFieldName;		int			fs_len = strlen(po->fieldSep);		int			total_line_length = 0;		int			usePipe = 0;		char	   *pagerenv;#if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)		sigset_t	osigset;		bool		sigpipe_masked = false;		bool		sigpipe_pending;#endif#if !defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)		pqsigfunc	oldsigpipehandler = NULL;#endif#ifdef TIOCGWINSZ		struct winsize screen_size;#else		struct winsize		{			int			ws_row;			int			ws_col;		}			screen_size;#endif		nTups = PQntuples(res);		if (!(fieldNames = (const char **) calloc(nFields, sizeof(char *))))		{			fprintf(stderr, libpq_gettext("out of memory\n"));			exit(1);		}		if (!(fieldNotNum = (unsigned char *) calloc(nFields, 1)))		{			fprintf(stderr, libpq_gettext("out of memory\n"));			exit(1);		}		if (!(fieldMax = (int *) calloc(nFields, sizeof(int))))		{			fprintf(stderr, libpq_gettext("out of memory\n"));			exit(1);		}		for (numFieldName = 0;			 po->fieldName && po->fieldName[numFieldName];			 numFieldName++)			;		for (j = 0; j < nFields; j++)		{			int			len;			const char *s = (j < numFieldName && po->fieldName[j][0]) ?			po->fieldName[j] : PQfname(res, j);			fieldNames[j] = s;			len = s ? strlen(s) : 0;			fieldMax[j] = len;			len += fs_len;			if (len > fieldMaxLen)				fieldMaxLen = len;			total_line_length += len;		}		total_line_length += nFields * strlen(po->fieldSep) + 1;		if (fout == NULL)			fout = stdout;		if (po->pager && fout == stdout#ifndef WIN32			&&			isatty(fileno(stdin)) &&			isatty(fileno(stdout))#endif			)		{			/*			 * If we think there'll be more than one screen of output, try to			 * pipe to the pager program.			 */#ifdef TIOCGWINSZ			if (ioctl(fileno(stdout), TIOCGWINSZ, &screen_size) == -1 ||				screen_size.ws_col == 0 ||				screen_size.ws_row == 0)			{				screen_size.ws_row = 24;				screen_size.ws_col = 80;			}#else			screen_size.ws_row = 24;			screen_size.ws_col = 80;#endif			pagerenv = getenv("PAGER");			if (pagerenv != NULL &&				pagerenv[0] != '\0' &&				!po->html3 &&				((po->expanded &&				  nTups * (nFields + 1) >= screen_size.ws_row) ||				 (!po->expanded &&				  nTups * (total_line_length / screen_size.ws_col + 1) *				  (1 + (po->standard != 0)) >= screen_size.ws_row -				  (po->header != 0) *				  (total_line_length / screen_size.ws_col + 1) * 2				  - (po->header != 0) * 2		/* row count and newline */				  )))			{				fout = popen(pagerenv, "w");				if (fout)				{					usePipe = 1;#ifndef WIN32#ifdef ENABLE_THREAD_SAFETY					if (pq_block_sigpipe(&osigset, &sigpipe_pending) == 0)						sigpipe_masked = true;#else					oldsigpipehandler = pqsignal(SIGPIPE, SIG_IGN);#endif   /* ENABLE_THREAD_SAFETY */#endif   /* WIN32 */				}				else					fout = stdout;			}		}		if (!po->expanded && (po->align || po->html3))		{			if (!(fields = (char **) calloc(nFields * (nTups + 1), sizeof(char *))))			{				fprintf(stderr, libpq_gettext("out of memory\n"));				exit(1);			}		}		else if (po->header && !po->html3)		{			if (po->expanded)			{				if (po->align)					fprintf(fout, libpq_gettext("%-*s%s Value\n"),							fieldMaxLen - fs_len, libpq_gettext("Field"), po->fieldSep);				else					fprintf(fout, libpq_gettext("%s%sValue\n"), libpq_gettext("Field"), po->fieldSep);			}			else			{				int			len = 0;				for (j = 0; j < nFields; j++)				{					const char *s = fieldNames[j];					fputs(s, fout);					len += strlen(s) + fs_len;					if ((j + 1) < nFields)						fputs(po->fieldSep, fout);				}				fputc('\n', fout);				for (len -= fs_len; len--; fputc('-', fout));				fputc('\n', fout);			}		}		if (po->expanded && po->html3)		{			if (po->caption)				fprintf(fout, "<center><h2>%s</h2></center>\n", po->caption);			else				fprintf(fout,						"<center><h2>"						"Query retrieved %d rows * %d fields"						"</h2></center>\n",						nTups, nFields);		}		for (i = 0; i < nTups; i++)		{			if (po->expanded)			{				if (po->html3)					fprintf(fout,							"<table %s><caption align=\"top\">%d</caption>\n",							po->tableOpt ? po->tableOpt : "", i);				else					fprintf(fout, libpq_gettext("-- RECORD %d --\n"), i);			}			for (j = 0; j < nFields; j++)				do_field(po, res, i, j, fs_len, fields, nFields,						 fieldNames, fieldNotNum,						 fieldMax, fieldMaxLen, fout);			if (po->html3 && po->expanded)				fputs("</table>\n", fout);		}		if (!po->expanded && (po->align || po->html3))		{			if (po->html3)			{				if (po->header)				{					if (po->caption)						fprintf(fout,							  "<table %s><caption align=\"top\">%s</caption>\n",								po->tableOpt ? po->tableOpt : "",								po->caption);					else						fprintf(fout,								"<table %s><caption align=\"top\">"								"Retrieved %d rows * %d fields"								"</caption>\n",						   po->tableOpt ? po->tableOpt : "", nTups, nFields);				}				else					fprintf(fout, "<table %s>", po->tableOpt ? po->tableOpt : "");			}			if (po->header)				border = do_header(fout, po, nFields, fieldMax, fieldNames,								   fieldNotNum, fs_len, res);			for (i = 0; i < nTups; i++)				output_row(fout, po, nFields, fields,						   fieldNotNum, fieldMax, border, i);			free(fields);			if (border)				free(border);		}		if (po->header && !po->html3)			fprintf(fout, "(%d row%s)\n\n", PQntuples(res),					(PQntuples(res) == 1) ? "" : "s");		free(fieldMax);		free(fieldNotNum);		free((void *) fieldNames);		if (usePipe)		{#ifdef WIN32			_pclose(fout);#else			pclose(fout);#ifdef ENABLE_THREAD_SAFETY			/* we can't easily verify if EPIPE occurred, so say it did */			if (sigpipe_masked)				pq_reset_sigpipe(&osigset, sigpipe_pending, true);#else			pqsignal(SIGPIPE, oldsigpipehandler);#endif   /* ENABLE_THREAD_SAFETY */#endif   /* WIN32 */		}		if (po->html3 && !po->expanded)			fputs("</table>\n", fout);	}}static voiddo_field(const PQprintOpt *po, const PGresult *res,		 const int i, const int j, const int fs_len,		 char **fields,		 const int nFields, char const ** fieldNames,		 unsigned char *fieldNotNum, int *fieldMax,		 const int fieldMaxLen, FILE *fout){	const char *pval,			   *p;	int			plen;	bool		skipit;	plen = PQgetlength(res, i, j);	pval = PQgetvalue(res, i, j);	if (plen < 1 || !pval || !*pval)	{		if (po->align || po->expanded)			skipit = true;		else		{			skipit = false;			goto efield;		}	}	else		skipit = false;	if (!skipit)	{		if (po->align && !fieldNotNum[j])		{			/* Detect whether field contains non-numeric data */			char		ch = '0';			for (p = pval; *p; p += PQmblen(p, res->client_encoding))			{				ch = *p;				if (!((ch >= '0' && ch <= '9') ||					  ch == '.' ||					  ch == 'E' ||					  ch == 'e' ||					  ch == ' ' ||					  ch == '-'))				{					fieldNotNum[j] = 1;					break;				}			}			/*			 * Above loop will believe E in first column is numeric; also, we			 * insist on a digit in the last column for a numeric. This test			 * is still not bulletproof but it handles most cases.			 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -