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

📄 psql.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 5 页
字号:
				else					printf("Copy failed.\n");			}		}	}}static voiddo_connect(const char *new_dbname,		   const char *new_user,		   PsqlSettings *pset){	if (!new_dbname)		fprintf(stderr, "\\connect must be followed by a database name\n");	else if (new_user != NULL && pset->getPassword)		fprintf(stderr, "You can't specify a username when using passwords.\n");	else	{		PGconn	   *olddb = pset->db;		const char *dbparam;		const char *userparam;		const char *pwparam;		if (strcmp(new_dbname, "-") != 0)			dbparam = new_dbname;		else			dbparam = PQdb(olddb);		if (new_user != NULL && strcmp(new_user, "-") != 0)			userparam = new_user;		else			userparam = PQuser(olddb);		/* FIXME: if changing user, ought to prompt for a new password? */		pwparam = PQpass(olddb);#ifdef MULTIBYTE		/*		 * PGCLIENTENCODING may be set by the previous connection. if a		 * user does not explicitly set PGCLIENTENCODING, we should		 * discard PGCLIENTENCODING so that libpq could get the backend		 * encoding as the default PGCLIENTENCODING value. -- 1998/12/12		 * Tatsuo Ishii		 */		if (!has_client_encoding)		{			static const char ev[] = "PGCLIENTENCODING=";			putenv(ev);		}#endif		pset->db = PQsetdbLogin(PQhost(olddb), PQport(olddb),								NULL, NULL, dbparam, userparam, pwparam);		if (!pset->quiet)		{			if (!new_user)				printf("connecting to new database: %s\n", dbparam);			else if (dbparam != new_dbname)				printf("connecting as new user: %s\n", new_user);			else				printf("connecting to new database: %s as user: %s\n",					   dbparam, new_user);		}		if (PQstatus(pset->db) == CONNECTION_BAD)		{			fprintf(stderr, "%s\n", PQerrorMessage(pset->db));			fprintf(stderr, "Could not connect to new database. exiting\n");			exit(2);		}		else		{			cancelConn = pset->db;		/* redirect sigint's loving										 * attentions */			PQfinish(olddb);			free(pset->prompt);			pset->prompt = malloc(strlen(PQdb(pset->db)) + 10);			sprintf(pset->prompt, "%s%s", PQdb(pset->db), PROMPT);		}	}}static voiddo_edit(const char *filename_arg, char *query, int *status_p){	int			fd;	char		tmp[64];	char	   *fname;	int			cc;	const int	ql = strlen(query);	bool		error;	if (filename_arg)	{		fname = (char *) filename_arg;		error = false;	}	else	{#ifndef WIN32		sprintf(tmp, "/tmp/psql.%ld.%ld", (long) geteuid(), (long) getpid());#else		GetTempFileName(".", "psql", 0, tmp);#endif		fname = tmp;		unlink(tmp);		if (ql > 0)		{			if ((fd = open(tmp, O_EXCL | O_CREAT | O_WRONLY, 0600)) == -1)			{				perror(tmp);				error = true;			}			else			{				if (query[ql - 1] != '\n')					strcat(query, "\n");				if (write(fd, query, ql) != ql)				{					perror(tmp);					close(fd);					unlink(tmp);					error = true;				}				else					error = false;				close(fd);			}		}		else			error = false;	}	if (error)		*status_p = CMD_SKIP_LINE;	else	{		editFile(fname);		if ((fd = open(fname, O_RDONLY, 0)) == -1)		{			perror(fname);			if (!filename_arg)				unlink(fname);			*status_p = CMD_SKIP_LINE;		}		else		{			if ((cc = read(fd, query, MAX_QUERY_BUFFER)) == -1)			{				perror(fname);				close(fd);				if (!filename_arg)					unlink(fname);				*status_p = CMD_SKIP_LINE;			}			else			{				query[cc] = '\0';				close(fd);				if (!filename_arg)					unlink(fname);				rightTrim(query);				*status_p = CMD_NEWEDIT;			}		}	}}static voiddo_help(PsqlSettings *pset, const char *topic){	if (!topic)	{		char		left_center_right;	/* Which column we're displaying */		int			i;			/* Index into QL_HELP[] */		printf("type \\h <cmd> where <cmd> is one of the following:\n");		left_center_right = 'L';/* Start with left column */		i = 0;		while (QL_HELP[i].cmd != NULL)		{			switch (left_center_right)			{				case 'L':					printf("    %-25s", QL_HELP[i].cmd);					left_center_right = 'C';					break;				case 'C':					printf("%-25s", QL_HELP[i].cmd);					left_center_right = 'R';					break;				case 'R':					printf("%-25s\n", QL_HELP[i].cmd);					left_center_right = 'L';					break;			}			i++;		}		if (left_center_right != 'L')			puts("\n");		printf("type \\h * for a complete description of all commands\n");	}	else	{		int			i;			/* Index into QL_HELP[] */		bool		help_found; /* We found the help he asked for */		int			usePipe = 0;		char	   *pagerenv;		FILE	   *fout;		if (strcmp(topic, "*") == 0 &&			(pset->notty == 0) &&			(pagerenv = getenv("PAGER")) &&			(pagerenv[0] != '\0') &&			(fout = popen(pagerenv, "w")))		{			usePipe = 1;			pqsignal(SIGPIPE, SIG_IGN);		}		else			fout = stdout;		help_found = false;		/* Haven't found it yet */		for (i = 0; QL_HELP[i].cmd; i++)		{			if (strcasecmp(QL_HELP[i].cmd, topic) == 0 ||				strcmp(topic, "*") == 0)			{				help_found = true;				fprintf(fout, "Command: %s\n", QL_HELP[i].cmd);				fprintf(fout, "Description: %s\n", QL_HELP[i].help);				fprintf(fout, "Syntax:\n");				fprintf(fout, "%s\n", QL_HELP[i].syntax);				fprintf(fout, "\n");			}		}		if (usePipe)		{			pclose(fout);			pqsignal(SIGPIPE, SIG_DFL);		}		if (!help_found)			fprintf(stderr, "command not found, "					"try \\h with no arguments to see available help\n");	}}static voiddo_shell(const char *command){	if (!command)	{		char	   *sys;		char	   *shellName;		shellName = getenv("SHELL");		if (shellName == NULL)			shellName = DEFAULT_SHELL;		sys = malloc(strlen(shellName) + 16);		if (!sys)		{			perror("malloc");			exit(1);		}		sprintf(sys, "exec %s", shellName);		system(sys);		free(sys);	}	else		system(command);}/* * HandleSlashCmds: * * Handles all the different commands that start with \ * db_ptr is a pointer to the TgDb* structure line is the current input * line prompt_ptr is a pointer to the prompt string, a pointer is used * because the prompt can be used with a connection to a new database. * Returns a status: *	0 - send currently constructed query to backend (i.e. we got a \g) *	1 - skip processing of this line, continue building up query *	2 - terminate processing of this query entirely *	3 - new query supplied by edit */static intHandleSlashCmds(PsqlSettings *pset,				char *line,				char *query){	int			status = CMD_SKIP_LINE;	char	   *optarg;	bool		success;	/*	 * Pointer inside the <cmd> string to the argument of the slash	 * command, assuming it is a one-character slash command.  If it's not	 * a one-character command, this is meaningless.	 */	char	   *optarg2;	/*	 * Pointer inside the <cmd> string to the argument of the slash	 * command assuming it's not a one-character command.  If it's a	 * one-character command, this is meaningless.	 */	char	   *cmd;	/*	 * String: value of the slash command, less the slash and with escape	 * sequences decoded.	 */	int			blank_loc;	/* Offset within <cmd> of first blank */	cmd = malloc(strlen(line)); /* unescaping better not make string grow. */	unescape(cmd, line + 1);	/* sets cmd string */	if (strlen(cmd) >= 1 && cmd[strlen(cmd) - 1] == ';')		/* strip trailing ; */		cmd[strlen(cmd) - 1] = '\0';	/*	 * Originally, there were just single character commands.  Now, we	 * define some longer, friendly commands, but we have to keep the old	 * single character commands too.  \c used to be what \connect is now.	 * Complicating matters is the fact that with the single-character	 * commands, you can start the argument right after the single	 * character, so "\copy" would mean "connect to database named 'opy'".	 */	if (strlen(cmd) > 1)		optarg = cmd + 1 + strspn(cmd + 1, " \t");	else		optarg = NULL;	blank_loc = strcspn(cmd, " \t");	if (blank_loc == 0 || !cmd[blank_loc])		optarg2 = NULL;	else		optarg2 = cmd + blank_loc + strspn(cmd + blank_loc, " \t");	switch (cmd[0])	{		case 'a':				/* toggles to align fields on output */			toggle(pset, &pset->opt.align, "field alignment");			break;		case 'C':				/* define new caption */			if (pset->opt.caption)			{				free(pset->opt.caption);				pset->opt.caption = NULL;			}			if (optarg && !(pset->opt.caption = strdup(optarg)))			{				perror("malloc");				exit(CMD_TERMINATE);			}			break;		case 'c':			{				if (strncmp(cmd, "copy ", strlen("copy ")) == 0 ||					strncmp(cmd, "copy	", strlen("copy	")) == 0)					do_copy(optarg2, pset);				else if (strcmp(cmd, "copy") == 0)				{					fprintf(stderr, "See \\? for help\n");					break;				}				else if (strncmp(cmd, "connect ", strlen("connect ")) == 0 ||				  strcmp(cmd, "connect") == 0 /* issue error message */ )				{					char	   *optarg3 = NULL;					int			blank_loc2;					if (optarg2)					{						blank_loc2 = strcspn(optarg2, " \t");						if (blank_loc2 == 0 || *(optarg2 + blank_loc2) == '\0')							optarg3 = NULL;						else						{							optarg3 = optarg2 + blank_loc2 +								strspn(optarg2 + blank_loc2, " \t");							*(optarg2 + blank_loc2) = '\0';						}					}					do_connect(optarg2, optarg3, pset);				}				else				{					char	   *optarg3 = NULL;					int			blank_loc2;					if (optarg)					{						blank_loc2 = strcspn(optarg, " \t");						if (blank_loc2 == 0 || *(optarg + blank_loc2) == '\0')							optarg3 = NULL;						else						{							optarg3 = optarg + blank_loc2 +								strspn(optarg + blank_loc2, " \t");							*(optarg + blank_loc2) = '\0';						}					}					do_connect(optarg, optarg3, pset);				}			}			break;		case 'd':				/* \d describe database information */			/*			 * if the optarg2 name is surrounded by double-quotes, then			 * don't convert case			 */			if (optarg2)			{				if (*optarg2 == '"')				{					optarg2++;					if (*(optarg2 + strlen(optarg2) - 1) == '"')						*(optarg2 + strlen(optarg2) - 1) = '\0';				}				else				{					int			i;#ifdef MULTIBYTE					for (i = 0; optarg2[i]; i += PQmblen(optarg2 + i))#else					for (i = 0; optarg2[i]; i++)#endif						if (isupper(optarg2[i]))							optarg2[i] = tolower(optarg2[i]);				}			}#ifdef TIOCGWINSZ			if (pset->notty == 0 &&				(ioctl(fileno(stdout), TIOCGWINSZ, &screen_size) == -1 ||				 screen_size.ws_col == 0 ||				 screen_size.ws_row == 0))			{#endif				screen_size.ws_row = 24;				screen_size.ws_col = 80;#ifdef TIOCGWINSZ			}#endif			if (strncmp(cmd, "da", 2) == 0)			{				char		descbuf[4096];				/* aggregates */				descbuf[0] = '\0';				strcat(descbuf, "SELECT	a.aggname AS aggname, ");				strcat(descbuf, "		t.typname AS type, ");				strcat(descbuf, "		obj_description(a.oid) as description ");				strcat(descbuf, "FROM	pg_aggregate a, pg_type t ");				strcat(descbuf, "WHERE	a.aggbasetype = t.oid ");				if (optarg2)				{					strcat(descbuf, "AND a.aggname ~ '^");					strcat(descbuf, optarg2);					strcat(descbuf, "' ");				}				strcat(descbuf, "UNION ");				strcat(descbuf, "SELECT	a.aggname AS aggname, ");				strcat(descbuf, "		'all types' as type, ");				strcat(descbuf, "		obj_description(a.oid) as description ");				strcat(descbuf, "FROM	pg_aggregate a ");				strcat(descbuf, "WHERE	a.aggbasetype = 0 ");				if (optarg2)				{					strcat(descbuf, "AND a.aggname ~ '^");					strcat(descbuf, optarg2);					strcat(descbuf, "' ");				}				strcat(descbuf, "ORDER BY aggname, type;");				success = SendQuery(pset, descbuf, NULL, NULL);			}			else if (strncmp(cmd, "dd", 2) == 0)				/* descriptions */				objectDescription(pset, optarg + 1);			else if (strncmp(cmd, "df", 2) == 0)			{				char		descbuf[4096];				/* functions/procedures */

⌨️ 快捷键说明

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