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

📄 command.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 3 页
字号:
		opt1 = psql_scan_slash_option(scan_state,									  OT_NORMAL, NULL, true);		opt2 = psql_scan_slash_option(scan_state,									  OT_NORMAL, NULL, true);		if (strcmp(cmd + 3, "export") == 0)		{			if (!opt2)			{				psql_error("\\%s: missing required argument\n", cmd);				success = false;			}			else			{				expand_tilde(&opt2);				success = do_lo_export(opt1, opt2);			}		}		else if (strcmp(cmd + 3, "import") == 0)		{			if (!opt1)			{				psql_error("\\%s: missing required argument\n", cmd);				success = false;			}			else			{				expand_tilde(&opt1);				success = do_lo_import(opt1, opt2);			}		}		else if (strcmp(cmd + 3, "list") == 0)			success = do_lo_list();		else if (strcmp(cmd + 3, "unlink") == 0)		{			if (!opt1)			{				psql_error("\\%s: missing required argument\n", cmd);				success = false;			}			else				success = do_lo_unlink(opt1);		}		else			status = CMD_UNKNOWN;		free(opt1);		free(opt2);	}	/* \o -- set query output */	else if (strcmp(cmd, "o") == 0 || strcmp(cmd, "out") == 0)	{		char	   *fname = psql_scan_slash_option(scan_state,												   OT_FILEPIPE, NULL, true);		expand_tilde(&fname);		success = setQFout(fname);		free(fname);	}	/* \p prints the current query buffer */	else if (strcmp(cmd, "p") == 0 || strcmp(cmd, "print") == 0)	{		if (query_buf && query_buf->len > 0)			puts(query_buf->data);		else if (!quiet)			puts(_("Query buffer is empty."));		fflush(stdout);	}	/* \pset -- set printing parameters */	else if (strcmp(cmd, "pset") == 0)	{		char	   *opt0 = psql_scan_slash_option(scan_state,												  OT_NORMAL, NULL, false);		char	   *opt1 = psql_scan_slash_option(scan_state,												  OT_NORMAL, NULL, false);		if (!opt0)		{			psql_error("\\%s: missing required argument\n", cmd);			success = false;		}		else			success = do_pset(opt0, opt1, &pset.popt, quiet);		free(opt0);		free(opt1);	}	/* \q or \quit */	else if (strcmp(cmd, "q") == 0 || strcmp(cmd, "quit") == 0)		status = CMD_TERMINATE;	/* reset(clear) the buffer */	else if (strcmp(cmd, "r") == 0 || strcmp(cmd, "reset") == 0)	{		resetPQExpBuffer(query_buf);		psql_scan_reset(scan_state);		if (!quiet)			puts(_("Query buffer reset (cleared)."));	}	/* \s save history in a file or show it on the screen */	else if (strcmp(cmd, "s") == 0)	{		char	   *fname = psql_scan_slash_option(scan_state,												   OT_NORMAL, NULL, true);		expand_tilde(&fname);		/* This scrolls off the screen when using /dev/tty */		success = saveHistory(fname ? fname : DEVTTY);		if (success && !quiet && fname)			printf(gettext("Wrote history to file \"%s/%s\".\n"),				   pset.dirname ? pset.dirname : ".", fname);		if (!fname)			putchar('\n');		free(fname);	}	/* \set -- generalized set variable/option command */	else if (strcmp(cmd, "set") == 0)	{		char	   *opt0 = psql_scan_slash_option(scan_state,												  OT_NORMAL, NULL, false);		if (!opt0)		{			/* list all variables */			PrintVariables(pset.vars);			success = true;		}		else		{			/*			 * Set variable to the concatenation of the arguments.			 */			char	   *newval;			char	   *opt;			opt = psql_scan_slash_option(scan_state,										 OT_NORMAL, NULL, false);			newval = pg_strdup(opt ? opt : "");			free(opt);			while ((opt = psql_scan_slash_option(scan_state,												 OT_NORMAL, NULL, false)))			{				newval = realloc(newval, strlen(newval) + strlen(opt) + 1);				if (!newval)				{					psql_error("out of memory\n");					exit(EXIT_FAILURE);				}				strcat(newval, opt);				free(opt);			}			if (SetVariable(pset.vars, opt0, newval))			{				/* Check for special variables */				if (strcmp(opt0, "VERBOSITY") == 0)					SyncVerbosityVariable();			}			else			{				psql_error("\\%s: error\n", cmd);				success = false;			}			free(newval);		}		free(opt0);	}	/* \t -- turn off headers and row count */	else if (strcmp(cmd, "t") == 0)		success = do_pset("tuples_only", NULL, &pset.popt, quiet);	/* \T -- define html <table ...> attributes */	else if (strcmp(cmd, "T") == 0)	{		char	   *value = psql_scan_slash_option(scan_state,												   OT_NORMAL, NULL, false);		success = do_pset("tableattr", value, &pset.popt, quiet);		free(value);	}	/* \timing -- toggle timing of queries */	else if (strcmp(cmd, "timing") == 0)	{		pset.timing = !pset.timing;		if (!quiet)		{			if (pset.timing)				puts(_("Timing is on."));			else				puts(_("Timing is off."));		}	}	/* \unset */	else if (strcmp(cmd, "unset") == 0)	{		char	   *opt = psql_scan_slash_option(scan_state,												 OT_NORMAL, NULL, false);		if (!opt)		{			psql_error("\\%s: missing required argument\n", cmd);			success = false;		}		else if (!SetVariable(pset.vars, opt, NULL))		{			psql_error("\\%s: error\n", cmd);			success = false;		}		free(opt);	}	/* \w -- write query buffer to file */	else if (strcmp(cmd, "w") == 0 || strcmp(cmd, "write") == 0)	{		FILE	   *fd = NULL;		bool		is_pipe = false;		char	   *fname = NULL;		if (!query_buf)		{			psql_error("no query buffer\n");			status = CMD_ERROR;		}		else		{			fname = psql_scan_slash_option(scan_state,										   OT_FILEPIPE, NULL, true);			expand_tilde(&fname);			if (!fname)			{				psql_error("\\%s: missing required argument\n", cmd);				success = false;			}			else			{				if (fname[0] == '|')				{					is_pipe = true;					fd = popen(&fname[1], "w");				}				else				{					canonicalize_path(fname);					fd = fopen(fname, "w");				}				if (!fd)				{					psql_error("%s: %s\n", fname, strerror(errno));					success = false;				}			}		}		if (fd)		{			int			result;			if (query_buf && query_buf->len > 0)				fprintf(fd, "%s\n", query_buf->data);			if (is_pipe)				result = pclose(fd);			else				result = fclose(fd);			if (result == EOF)			{				psql_error("%s: %s\n", fname, strerror(errno));				success = false;			}		}		free(fname);	}	/* \x -- toggle expanded table representation */	else if (strcmp(cmd, "x") == 0)		success = do_pset("expanded", NULL, &pset.popt, quiet);	/* \z -- list table rights (equivalent to \dp) */	else if (strcmp(cmd, "z") == 0)	{		char	   *pattern = psql_scan_slash_option(scan_state,													 OT_NORMAL, NULL, true);		success = permissionsList(pattern);		if (pattern)			free(pattern);	}	/* \! -- shell escape */	else if (strcmp(cmd, "!") == 0)	{		char	   *opt = psql_scan_slash_option(scan_state,												 OT_WHOLE_LINE, NULL, false);		success = do_shell(opt);		free(opt);	}	/* \? -- slash command help */	else if (strcmp(cmd, "?") == 0)		slashUsage(pset.popt.topt.pager);#if 0	/*	 * These commands don't do anything. I just use them to test the parser.	 */	else if (strcmp(cmd, "void") == 0 || strcmp(cmd, "#") == 0)	{		int			i = 0;		char	   *value;		while ((value = psql_scan_slash_option(scan_state,											   OT_NORMAL, NULL, true)))		{			fprintf(stderr, "+ opt(%d) = |%s|\n", i++, value);			free(value);		}	}#endif	else		status = CMD_UNKNOWN;	if (!success)		status = CMD_ERROR;	return status;}/* do_connect * -- handler for \connect * * Connects to a database (new_dbname) as a certain user (new_user). * The new user can be NULL. A db name of "-" is the same as the old one. * (That is, the one currently in pset. But pset.db can also be NULL. A NULL * dbname is handled by libpq.) * Returns true if all ok, false if the new connection couldn't be established. * The old connection will be kept if the session is interactive. */static booldo_connect(const char *new_dbname, const char *new_user){	PGconn	   *oldconn = pset.db;	const char *dbparam = NULL;	const char *userparam = NULL;	const char *pwparam = NULL;	char	   *password_prompt = NULL;	char	   *prompted_password = NULL;	bool		need_pass;	bool		success = false;	/* Delete variables (in case we fail before setting them anew) */	UnsyncVariables();	/* If dbname is "" then use old name, else new one (even if NULL) */	if (oldconn && new_dbname && PQdb(oldconn) && strcmp(new_dbname, "") == 0)		dbparam = PQdb(oldconn);	else		dbparam = new_dbname;	/* If user is "" then use the old one */	if (new_user && PQuser(oldconn) && strcmp(new_user, "") == 0)		userparam = PQuser(oldconn);	else		userparam = new_user;	if (userparam == NULL)		password_prompt = strdup("Password: ");	else	{		password_prompt = malloc(strlen(_("Password for user %s: ")) - 2 +								 strlen(userparam) + 1);		sprintf(password_prompt, _("Password for user %s: "), userparam);	}	/* need to prompt for password? */	if (pset.getPassword)		pwparam = prompted_password = simple_prompt(password_prompt, 100, false);	/*	 * Use old password (if any) if no new one given and we are reconnecting	 * as same user	 */	if (!pwparam && oldconn && PQuser(oldconn) && userparam &&		strcmp(PQuser(oldconn), userparam) == 0)		pwparam = PQpass(oldconn);	do	{		need_pass = false;		pset.db = PQsetdbLogin(PQhost(oldconn), PQport(oldconn),							   NULL, NULL, dbparam, userparam, pwparam);		if (PQstatus(pset.db) == CONNECTION_BAD &&			strcmp(PQerrorMessage(pset.db), PQnoPasswordSupplied) == 0 &&			!feof(stdin))		{			PQfinish(pset.db);			need_pass = true;			free(prompted_password);			prompted_password = NULL;			pwparam = prompted_password = simple_prompt(password_prompt, 100, false);		}	} while (need_pass);	free(prompted_password);	free(password_prompt);	/*	 * If connection failed, try at least keep the old one. That's probably	 * more convenient than just kicking you out of the program.	 */	if (!pset.db || PQstatus(pset.db) == CONNECTION_BAD)	{		if (pset.cur_cmd_interactive)		{			psql_error("%s", PQerrorMessage(pset.db));			PQfinish(pset.db);			if (oldconn)			{				fputs(_("Previous connection kept\n"), stderr);				pset.db = oldconn;			}			else				pset.db = NULL;		}		else		{			/*			 * we don't want unpredictable things to happen in scripting mode			 */			psql_error("\\connect: %s", PQerrorMessage(pset.db));			PQfinish(pset.db);			if (oldconn)				PQfinish(oldconn);			pset.db = NULL;		}	}	else	{		if (!QUIET())		{			if (userparam != new_user)	/* no new user */				printf(_("You are now connected to database \"%s\".\n"), dbparam);			else if (dbparam != new_dbname)		/* no new db */				printf(_("You are now connected as new user \"%s\".\n"), new_user);			else				/* both new */				printf(_("You are now connected to database \"%s\" as user \"%s\".\n"),					   PQdb(pset.db), PQuser(pset.db));		}		if (oldconn)			PQfinish(oldconn);		success = true;	}	PQsetNoticeProcessor(pset.db, NoticeProcessor, NULL);	/* Update variables */	SyncVariables();	return success;}/* * SyncVariables * * Make psql's internal variables agree with connection state upon * establishing a new connection. */voidSyncVariables(void){	/* get stuff from connection */	pset.encoding = PQclientEncoding(pset.db);	pset.popt.topt.encoding = pset.encoding;	SetVariable(pset.vars, "DBNAME", PQdb(pset.db));	SetVariable(pset.vars, "USER", PQuser(pset.db));	SetVariable(pset.vars, "HOST", PQhost(pset.db));	SetVariable(pset.vars, "PORT", PQport(pset.db));	SetVariable(pset.vars, "ENCODING", pg_encoding_to_char(pset.encoding));	/* send stuff to it, too */	SyncVerbosityVariable();}/* * UnsyncVariables * * Clear variables that should be not be set when there is no connection. */voidUnsyncVariables(void){	SetVariable(pset.vars, "DBNAME", NULL);	SetVariable(pset.vars, "USER", NULL);	SetVariable(pset.vars, "HOST", NULL);	SetVariable(pset.vars, "PORT", NULL);	SetVariable(pset.vars, "ENCODING", NULL);}/* * Update connection state from VERBOSITY variable */voidSyncVerbosityVariable(void){	switch (SwitchVariable(pset.vars, "VERBOSITY",						   "default", "terse", "verbose", NULL))	{		case 1:			/* default */			pset.verbosity = PQERRORS_DEFAULT;			break;		case 2:			/* terse */			pset.verbosity = PQERRORS_TERSE;			break;		case 3:			/* verbose */			pset.verbosity = PQERRORS_VERBOSE;

⌨️ 快捷键说明

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