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

📄 pqprint.c

📁 适合于Unix/Linux下的一个持久数据库连接池
💻 C
📖 第 1 页 / 共 2 页
字号:
/*Portions Copyright (c) 1996-2002, The PostgreSQL Global Development Group Portions Copyright (c) 1994, The Regents of the University of CaliforniaPortions Copyright (c) 2003-2004, David MusePermission to use, copy, modify, and distribute this software and its documentation for any purpose, without fee, and without a written agreement is hereby granted, provided that the above copyright notice and this paragraph and the following two paragraphs appear in all copies. IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.*/#include <pqdefinitions.h>#include <rudiments/charstring.h>#ifdef WIN32#include "win32.h"#else// for isatty()#include <unistd.h>#endifextern "C" {typedef struct _PQprintOpt {	char	header;		char	align;	char	standard;	char	html3;	char	expanded;	char	pager;	char	*fieldSep;	char	*tableOpt;	char	*caption;	char	**fieldName;} PQprintOpt;// Haha!  I stole these straight out of the postgresql source/*PostgreSQL is Copyright © 1996-2002 by the PostgreSQL Global Development Groupand is distributed under the terms of the license of the University ofCalifornia below.Postgres95 is Copyright © 1994-5 by the Regents of the University of California.Permission to use, copy, modify, and distribute this software and itsdocumentation for any purpose, without fee, and without a written agreement ishereby granted, provided that the above copyright notice and this paragraph andthe following two paragraphs appear in all copies.IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FORDIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOSTPROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IFTHE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR APARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS-IS" BASIS, ANDTHE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE,SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */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 extend 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 = charstring::length(po->fieldSep);		int			total_line_length = 0;		int			usePipe = 0;		//pqsigfunc	oldsigpipehandler = NULL;		char	   *pagerenv;#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 *))))		{			perror("calloc");			exit(1);		}		if (!(fieldNotNum = (unsigned char *) calloc(nFields, 1)))		{			perror("calloc");			exit(1);		}		if (!(fieldMax = (int *) calloc(nFields, sizeof(int))))		{			perror("calloc");			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 ? charstring::length(s) : 0;			fieldMax[j] = len;			len += fs_len;			if (len > fieldMaxLen)				fieldMaxLen = len;			total_line_length += len;		}		total_line_length += nFields * charstring::length(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 */				  )))			{#ifdef WIN32				fout = _popen(pagerenv, "w");#else				fout = popen(pagerenv, "w");#endif				if (fout)				{					usePipe = 1;#ifndef WIN32					//oldsigpipehandler = pqsignal(SIGPIPE, SIG_IGN);#endif				}				else					fout = stdout;			}		}		if (!po->expanded && (po->align || po->html3))		{			if (!(fields = (char **) calloc(nFields * (nTups + 1), sizeof(char *))))			{				perror("calloc");				exit(1);			}		}		else if (po->header && !po->html3)		{			if (po->expanded)			{				if (po->align)					fprintf(fout, "%-*s%s Value\n",							fieldMaxLen - fs_len, "Field", po->fieldSep);				else					fprintf(fout, "%s%sValue\n", "Field", po->fieldSep);			}			else			{				int			len = 0;				for (j = 0; j < nFields; j++)				{					const char *s = fieldNames[j];					fputs(s, fout);					len += charstring::length(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, "<centre><h2>%s</h2></centre>\n", po->caption);			else				fprintf(fout,						"<centre><h2>"						"Query retrieved %d rows * %d fields"						"</h2></centre>\n",						nTups, nFields);		}		for (i = 0; i < nTups; i++)		{			if (po->expanded)			{				if (po->html3)					fprintf(fout,						  "<table %s><caption align=high>%d</caption>\n",							po->tableOpt ? po->tableOpt : "", i);				else					fprintf(fout, "-- 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=high>%s</caption>\n",								po->tableOpt ? po->tableOpt : "",								po->caption);					else						fprintf(fout,								"<table %s><caption align=high>"								"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);			//pqsignal(SIGPIPE, oldsigpipehandler);#endif		}		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((unsigned char *)p, PQclientEncoding(res->parent)))			{				ch = *p;				if (!((ch >= '0' && ch <= '9') ||					  ch == '.' ||					  ch == 'E' ||					  ch == 'e' ||					  ch == ' ' ||

⌨️ 快捷键说明

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