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

📄 copy.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 2 页
字号:
					for (;;)					{						token = strtokx(NULL, whitespace, ",", "\"",										0, false, pset.encoding);						if (!token || strchr(",", token[0]))							goto error;						if (!result->force_notnull_list)							result->force_notnull_list = pg_strdup(token);						else							xstrcat(&result->force_notnull_list, token);						token = strtokx(NULL, whitespace, ",", "\"",										0, false, pset.encoding);						if (!token || token[0] != ',')							break;						xstrcat(&result->force_notnull_list, token);					}				}				else					goto error;			}			else				goto error;			if (fetch_next)				token = strtokx(NULL, whitespace, NULL, NULL,								0, false, pset.encoding);		}	}	free(line);	return result;error:	if (token)		psql_error("\\copy: parse error at \"%s\"\n", token);	else		psql_error("\\copy: parse error at end of line\n");	free_copy_options(result);	free(line);	return NULL;}/* * 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. */booldo_copy(const char *args){	PQExpBufferData query;	FILE	   *copystream;	struct copy_options *options;	PGresult   *result;	bool		success;	struct stat st;	/* parse options */	options = parse_slash_copy(args);	if (!options)		return false;	initPQExpBuffer(&query);	printfPQExpBuffer(&query, "COPY ");	if (options->binary)		appendPQExpBuffer(&query, "BINARY ");	appendPQExpBuffer(&query, "%s ", options->table);	if (options->column_list)		appendPQExpBuffer(&query, "%s ", options->column_list);	/* Uses old COPY syntax for backward compatibility 2002-06-19 */	if (options->oids)		appendPQExpBuffer(&query, "WITH OIDS ");	if (options->from)		appendPQExpBuffer(&query, "FROM STDIN");	else		appendPQExpBuffer(&query, "TO STDOUT");	/* Uses old COPY syntax for backward compatibility 2002-06-19 */	if (options->delim)	{		if (options->delim[0] == '\'')			appendPQExpBuffer(&query, " USING DELIMITERS %s",							  options->delim);		else			appendPQExpBuffer(&query, " USING DELIMITERS '%s'",							  options->delim);	}	/* There is no backward-compatible CSV syntax */	if (options->null)	{		if (options->null[0] == '\'')			appendPQExpBuffer(&query, " WITH NULL AS %s", options->null);		else			appendPQExpBuffer(&query, " WITH NULL AS '%s'", options->null);	}	if (options->csv_mode)		appendPQExpBuffer(&query, " CSV");	if (options->header)		appendPQExpBuffer(&query, " HEADER");	if (options->quote)	{		if (options->quote[0] == '\'')			appendPQExpBuffer(&query, " QUOTE AS %s", options->quote);		else			appendPQExpBuffer(&query, " QUOTE AS '%s'", options->quote);	}	if (options->escape)	{		if (options->escape[0] == '\'')			appendPQExpBuffer(&query, " ESCAPE AS %s", options->escape);		else			appendPQExpBuffer(&query, " ESCAPE AS '%s'", options->escape);	}	if (options->force_quote_list)		appendPQExpBuffer(&query, " FORCE QUOTE %s", options->force_quote_list);	if (options->force_notnull_list)		appendPQExpBuffer(&query, " FORCE NOT NULL %s", options->force_notnull_list);	if (options->file)		canonicalize_path(options->file);	if (options->from)	{		if (options->file)			copystream = fopen(options->file, PG_BINARY_R);		else if (!options->psql_inout)			copystream = pset.cur_cmd_source;		else			copystream = stdin;	}	else	{		if (options->file)			copystream = fopen(options->file, "w");		else if (!options->psql_inout)			copystream = pset.queryFout;		else			copystream = stdout;	}	if (!copystream)	{		psql_error("%s: %s\n",				   options->file, strerror(errno));		free_copy_options(options);		return false;	}	/* make sure the specified file is not a directory */	fstat(fileno(copystream), &st);	if (S_ISDIR(st.st_mode))	{		fclose(copystream);		psql_error("%s: cannot copy from/to a directory\n",				   options->file);		free_copy_options(options);		return false;	}	result = PSQLexec(query.data, true);	termPQExpBuffer(&query);	switch (PQresultStatus(result))	{		case PGRES_COPY_OUT:			success = handleCopyOut(pset.db, copystream);			break;		case PGRES_COPY_IN:			success = handleCopyIn(pset.db, copystream);			break;		case PGRES_NONFATAL_ERROR:		case PGRES_FATAL_ERROR:		case PGRES_BAD_RESPONSE:			success = false;			psql_error("\\copy: %s", PQerrorMessage(pset.db));			break;		default:			success = false;			psql_error("\\copy: unexpected response (%d)\n", PQresultStatus(result));	}	PQclear(result);	if (options->file != NULL)	{		if (fclose(copystream) != 0)		{			psql_error("%s: %s\n", options->file, strerror(errno));			success = false;		}	}	free_copy_options(options);	return success;}#define COPYBUFSIZ 8192			/* size doesn't matter *//* * handleCopyOut * receives data as a result of a COPY ... TO stdout command * * If you want to use COPY TO in your application, this is the code to steal :) * * conn should be a database connection that you just called COPY TO on * (and which gave you PGRES_COPY_OUT back); * copystream is the file stream you want the output to go to */boolhandleCopyOut(PGconn *conn, FILE *copystream){	bool		copydone = false;		/* haven't started yet */	char		copybuf[COPYBUFSIZ];	int			ret;	while (!copydone)	{		ret = PQgetline(conn, copybuf, COPYBUFSIZ);		if (copybuf[0] == '\\' &&			copybuf[1] == '.' &&			copybuf[2] == '\0')		{			copydone = true;	/* we're at the end */		}		else		{			fputs(copybuf, copystream);			switch (ret)			{				case EOF:					copydone = true;					/* FALLTHROUGH */				case 0:					fputc('\n', copystream);					break;				case 1:					break;			}		}	}	fflush(copystream);	ret = !PQendcopy(conn);	ResetCancelConn();	return ret;}/* * handleCopyIn * receives data as a result of a COPY ... FROM stdin command * * Again, if you want to use COPY FROM in your application, copy this. * * conn should be a database connection that you just called COPY FROM on * (and which gave you PGRES_COPY_IN back); * copystream is the file stream you want the input to come from */boolhandleCopyIn(PGconn *conn, FILE *copystream){	const char *prompt;	bool		copydone = false;	bool		firstload;	bool		linedone;	bool		saw_cr = false;	char		copybuf[COPYBUFSIZ];	char	   *s;	int			bufleft;	int			c = 0;	int			ret;	unsigned int linecount = 0;	/* Prompt if interactive input */	if (isatty(fileno(copystream)))	{		if (!QUIET())			puts(_("Enter data to be copied followed by a newline.\n"				   "End with a backslash and a period on a line by itself."));		prompt = get_prompt(PROMPT_COPY);	}	else		prompt = NULL;	while (!copydone)	{							/* for each input line ... */		if (prompt)		{			fputs(prompt, stdout);			fflush(stdout);		}		firstload = true;		linedone = false;		while (!linedone)		{						/* for each bufferload in line ... */			/* Fetch string until \n, EOF, or buffer full */			s = copybuf;			for (bufleft = COPYBUFSIZ - 1; bufleft > 0; bufleft--)			{				c = getc(copystream);				if (c == EOF)				{					linedone = true;					break;				}				*s++ = c;				if (c == '\n')				{					linedone = true;					break;				}				if (c == '\r')					saw_cr = true;			}			*s = '\0';			/* EOF with empty line-so-far? */			if (c == EOF && s == copybuf && firstload)			{				/*				 * We are guessing a little bit as to the right line-ending				 * here...				 */				if (saw_cr)					PQputline(conn, "\\.\r\n");				else					PQputline(conn, "\\.\n");				copydone = true;				if (pset.cur_cmd_interactive)					puts("\\.");				break;			}			/* No, so pass the data to the backend */			PQputline(conn, copybuf);			/* Check for line consisting only of \. */			if (firstload)			{				if (strcmp(copybuf, "\\.\n") == 0 ||					strcmp(copybuf, "\\.\r\n") == 0)				{					copydone = true;					break;				}				firstload = false;			}		}		linecount++;	}	ret = !PQendcopy(conn);	pset.lineno += linecount;	return ret;}

⌨️ 快捷键说明

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