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

📄 psql.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 5 页
字号:
		strcat(descbuf, " and pg_class.oid = pg_description.objoid ");		if (!(res = PSQLexec(pset, descbuf)))			return -1;		else if (PQntuples(res) <= 0)		{			PQclear(res);			descbuf[0] = '\0';			strcat(descbuf, "SELECT DISTINCT description ");			strcat(descbuf, "FROM pg_type, pg_description ");			strcat(descbuf, "WHERE pg_type.typname ~ '^");			strcat(descbuf, object);			strcat(descbuf, "' and ");			strcat(descbuf, " pg_type.oid = pg_description.objoid ");			if (!(res = PSQLexec(pset, descbuf)))				return -1;			else if (PQntuples(res) <= 0)			{				PQclear(res);				descbuf[0] = '\0';				strcat(descbuf, "SELECT DISTINCT description ");				strcat(descbuf, "FROM pg_proc, pg_description ");				strcat(descbuf, "WHERE pg_proc.proname ~ '^");				strcat(descbuf, object);				strcat(descbuf, "'");				strcat(descbuf, " and pg_proc.oid = pg_description.objoid ");				if (!(res = PSQLexec(pset, descbuf)))					return -1;				else if (PQntuples(res) <= 0)				{					PQclear(res);					descbuf[0] = '\0';					strcat(descbuf, "SELECT DISTINCT description ");					strcat(descbuf, "FROM pg_operator, pg_description ");					strcat(descbuf, "WHERE pg_operator.oprname ~ '^");					strcat(descbuf, object);					strcat(descbuf, "'");					/* operator descriptions are attached to the proc */					strcat(descbuf, " and RegprocToOid(pg_operator.oprcode) = pg_description.objoid ");					if (!(res = PSQLexec(pset, descbuf)))						return -1;					else if (PQntuples(res) <= 0)					{						PQclear(res);						descbuf[0] = '\0';						strcat(descbuf, "SELECT DISTINCT description ");						strcat(descbuf, "FROM pg_aggregate, pg_description ");						strcat(descbuf, "WHERE pg_aggregate.aggname ~ '^");						strcat(descbuf, object);						strcat(descbuf, "'");						strcat(descbuf, " and pg_aggregate.oid = pg_description.objoid ");						if (!(res = PSQLexec(pset, descbuf)))							return -1;						else if (PQntuples(res) <= 0)						{							PQclear(res);							descbuf[0] = '\0';							strcat(descbuf, "SELECT 'no description' as description ");							if (!(res = PSQLexec(pset, descbuf)))								return -1;						}					}				}			}		}	}	PQclear(res);	success = SendQuery(pset, descbuf, NULL, NULL);	return 0;}typedef char *(*READ_ROUTINE) (char *prompt, FILE *source);/* * gets_noreadline	prompt source gets a line of input without calling * readline, the source is ignored */static char *gets_noreadline(char *prompt, FILE *source){	fputs(prompt, stdout);	fflush(stdout);	return gets_fromFile(prompt, stdin);}/* * gets_readline  prompt source the routine to get input from GNU readline(), * the source is ignored the prompt argument is used as the prompting string */static char *gets_readline(char *prompt, FILE *source){	char	   *s;#ifdef USE_READLINE	s = readline(prompt);#else	char		buf[500];	printf("%s", prompt);	s = fgets(buf, 500, stdin);#endif	fputc('\r', stdout);	fflush(stdout);	return s;}/* * gets_fromFile  prompt source * * the routine to read from a file, the prompt argument is ignored the source * argument is a FILE * */static char *gets_fromFile(char *prompt, FILE *source){	char	   *line;	line = malloc(MAX_QUERY_BUFFER);	/* read up to MAX_QUERY_BUFFER characters */	if (fgets(line, MAX_QUERY_BUFFER, source) == NULL)	{		free(line);		return NULL;	}	line[MAX_QUERY_BUFFER - 1] = '\0';	/* this is unnecessary, I think */	if (strlen(line) == MAX_QUERY_BUFFER - 1)	{		fprintf(stderr, "line read exceeds maximum length.  Truncating at %d\n",				MAX_QUERY_BUFFER - 1);	}	return line;}/* * SendQuery: send the query string to the backend. * * Return true if the query executed successfully, false otherwise. * * If not NULL, copy_in_stream and copy_out_stream are files to redirect * copy in/out data to. */static boolSendQuery(PsqlSettings *pset, const char *query,		  FILE *copy_in_stream, FILE *copy_out_stream){	bool		success = false;	PGresult   *results;	PGnotify   *notify;	if (pset->singleStep)		fprintf(stdout, "\n**************************************"				"*****************************************\n");	if (pset->echoQuery || pset->singleStep)	{		fprintf(stderr, "QUERY: %s\n", query);		fflush(stderr);	}	if (pset->singleStep)	{		fprintf(stdout, "\n**************************************"				"*****************************************\n");		fflush(stdout);		printf("\npress return to continue ..\n");		gets_fromFile("", stdin);	}	results = PQexec(pset->db, query);	if (results == NULL)	{		fprintf(stderr, "%s", PQerrorMessage(pset->db));		success = false;	}	else	{		switch (PQresultStatus(results))		{			case PGRES_TUPLES_OK:				if (pset->gfname)				{					PsqlSettings settings_copy = *pset;					FILE	   *fp;					settings_copy.queryFout = stdout;					fp = setFout(&settings_copy, pset->gfname);					if (!fp || fp == stdout)					{						success = false;						break;					}					PQprint(fp,							results,							&pset->opt);					if (settings_copy.pipe)						pclose(fp);					else						fclose(fp);					free(pset->gfname);					pset->gfname = NULL;					success = true;					break;				}				else				{					success = true;					PQprint(pset->queryFout,							results,							&(pset->opt));					fflush(pset->queryFout);				}				break;			case PGRES_EMPTY_QUERY:				success = true;				break;			case PGRES_COMMAND_OK:				success = true;				if (!pset->quiet)					printf("%s\n", PQcmdStatus(results));				break;			case PGRES_COPY_OUT:				if (copy_out_stream)					success = handleCopyOut(pset->db, copy_out_stream);				else				{					if (pset->queryFout == stdout && !pset->quiet)						printf("Copy command returns...\n");					success = handleCopyOut(pset->db, pset->queryFout);				}				break;			case PGRES_COPY_IN:				if (copy_in_stream)					success = handleCopyIn(pset->db, false, copy_in_stream);				else					success = handleCopyIn(pset->db,									 cur_cmd_interactive && !pset->quiet,										   cur_cmd_source);				break;			case PGRES_NONFATAL_ERROR:			case PGRES_FATAL_ERROR:			case PGRES_BAD_RESPONSE:				success = false;				fprintf(stderr, "%s", PQerrorMessage(pset->db));				break;		}		if (PQstatus(pset->db) == CONNECTION_BAD)		{			fprintf(stderr,					"We have lost the connection to the backend, so "					"further processing is impossible.  "					"Terminating.\n");			exit(2);			/* we are out'ta here */		}		/* check for asynchronous returns */		while ((notify = PQnotifies(pset->db)) != NULL)		{			fprintf(stderr,				 "ASYNC NOTIFY of '%s' from backend pid '%d' received\n",					notify->relname, notify->be_pid);			free(notify);		}		if (results)			PQclear(results);	}	return success;}static voideditFile(char *fname){	char	   *editorName;	char	   *sys;	editorName = getenv("EDITOR");	if (!editorName)		editorName = DEFAULT_EDITOR;	sys = malloc(strlen(editorName) + strlen(fname) + 32 + 1);	if (!sys)	{		perror("malloc");		exit(1);	}	sprintf(sys, "exec '%s' '%s'", editorName, fname);	system(sys);	free(sys);}static booltoggle(PsqlSettings *pset, bool *sw, char *msg){	*sw = !*sw;	if (!pset->quiet)		printf("turned %s %s\n", on(*sw), msg);	return *sw;}static voidunescape(char *dest, const char *source){	/*-----------------------------------------------------------------------------	  Return as the string <dest> the value of string <source> with escape	  sequences turned into the bytes they represent.	-----------------------------------------------------------------------------*/	char	   *p;	bool		esc;			/* Last character we saw was the escape								 * character (/) */	esc = false;				/* Haven't seen escape character yet */	for (p = (char *) source; *p; p++)	{		char		c;			/* Our output character */		if (esc)		{			switch (*p)			{				case 'n':					c = '\n';					break;				case 'r':					c = '\r';					break;				case 't':					c = '\t';					break;				case 'f':					c = '\f';					break;				case '\\':					c = '\\';					break;				default:					c = *p;			}			esc = false;		}		else if (*p == '\\')		{			esc = true;			c = ' ';			/* meaningless, but compiler doesn't know								 * that */		}		else		{			c = *p;			esc = false;		}		if (!esc)			*dest++ = c;	}	*dest = '\0';				/* Terminating null character */}static voidparse_slash_copy(const char *args, char *table, const int table_len,				 char *file, const int file_len,				 bool *from_p, bool *error_p){	char		work_args[200];	/*	 * A copy of the \copy command arguments, except that we modify it as	 * we parse to suit our parsing needs.	 */	char	   *table_tok,			   *fromto_tok;	strncpy(work_args, args, sizeof(work_args));	work_args[sizeof(work_args) - 1] = '\0';	*error_p = false;			/* initial assumption */	table_tok = strtok(work_args, " ");	if (table_tok == NULL)	{		fprintf(stderr, "\\copy needs arguments.\n");		*error_p = true;	}	else	{		strncpy(table, table_tok, table_len);		file[table_len - 1] = '\0';		fromto_tok = strtok(NULL, "  ");		if (fromto_tok == NULL)		{			fprintf(stderr, "'FROM' or 'TO' must follow table name.\n");			*error_p = true;		}		else		{			if (strcasecmp(fromto_tok, "from") == 0)				*from_p = true;			else if (strcasecmp(fromto_tok, "to") == 0)				*from_p = false;			else			{				fprintf(stderr,						"Unrecognized token found where "						"'FROM' or 'TO' expected: '%s'.\n",						fromto_tok);				*error_p = true;			}			if (!*error_p)			{				char	   *file_tok;				file_tok = strtok(NULL, " ");				if (file_tok == NULL)				{					fprintf(stderr, "A file pathname must follow '%s'.\n",							fromto_tok);					*error_p = true;				}				else				{					strncpy(file, file_tok, file_len);					file[file_len - 1] = '\0';					if (strtok(NULL, " ") != NULL)					{						fprintf(stderr,						  "You have extra tokens after the filename.\n");						*error_p = true;					}				}			}		}	}}static voiddo_copy(const char *args, PsqlSettings *pset){	/*---------------------------------------------------------------------------	  Execute a \copy command (frontend copy).	We have to open a file, then	  submit a COPY query to the backend and either feed it data from the	  file or route its response into the file.	  We do a text copy with default (tab) column delimiters.  Some day, we	  should do all the things a backend copy can do.	----------------------------------------------------------------------------*/	char		query[200];	/* The COPY command we send to the back end */	bool		from;	/* The direction of the copy is from a file to a table. */	char		file[MAXPATHLEN + 1];	/* The pathname of the file from/to which we copy */	char		table[NAMEDATALEN];	/* The name of the table from/to which we copy */	bool		syntax_error;	/* The \c command has invalid syntax */	FILE	   *copystream;	parse_slash_copy(args, table, sizeof(table), file, sizeof(file),					 &from, &syntax_error);	if (!syntax_error)	{		strcpy(query, "COPY ");		strcat(query, table);		if (from)			strcat(query, " FROM stdin");		else			strcat(query, " TO stdout");		if (from)#ifndef __CYGWIN32__			copystream = fopen(file, "r");#else			copystream = fopen(file, "rb");#endif		else#ifndef __CYGWIN32__			copystream = fopen(file, "w");#else			copystream = fopen(file, "wb");#endif		if (copystream == NULL)			fprintf(stderr,				"Unable to open file %s which to copy, errno = %s (%d).",					from ? "from" : "to", strerror(errno), errno);		else		{			bool		success;/* The query succeeded at the backend */			success = SendQuery(pset, query,								from ? copystream : (FILE *) NULL,								!from ? copystream : (FILE *) NULL);			fclose(copystream);			if (!pset->quiet)			{				if (success)					printf("Successfully copied.\n");

⌨️ 快捷键说明

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