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

📄 pg_backup_db.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 2 页
字号:
			appendBinaryPQExpBuffer(AH->pgCopyBuf, qry, (eos - qry));			return eos;		}		/*		 * fprintf(stderr, "Found cr at %d, prev char was %c, next was %c\n",		 * loc, qry[loc-1], qry[loc+1]);		 */		/* Count the number of preceding slashes */		sPos = loc;		while (sPos > 0 && qry[sPos - 1] == '\\')			sPos--;		sPos = loc - sPos;		/*		 * If an odd number of preceding slashes, then \n was escaped so set		 * the next search pos, and loop (if any left).		 */		if ((sPos & 1) == 1)		{			/* fprintf(stderr, "cr was escaped\n"); */			pos = loc + 1;			if (pos >= (eos - qry))			{				appendBinaryPQExpBuffer(AH->pgCopyBuf, qry, (eos - qry));				return eos;			}		}		else			break;	}	/* We found an unquoted newline */	qry[loc] = '\0';	appendPQExpBuffer(AH->pgCopyBuf, "%s\n", qry);	isEnd = (strcmp(AH->pgCopyBuf->data, "\\.\n") == 0);	/*	 * Note that we drop the data on the floor if libpq has failed to	 * enter COPY mode; this allows us to behave reasonably when trying	 * to continue after an error in a COPY command.	 */	if (AH->pgCopyIn && PQputline(AH->connection, AH->pgCopyBuf->data) != 0)		die_horribly(AH, modulename, "error returned by PQputline: %s",					 PQerrorMessage(AH->connection));	resetPQExpBuffer(AH->pgCopyBuf);	/*	 * fprintf(stderr, "Buffer is '%s'\n", AH->pgCopyBuf->data);	 */	if (isEnd)	{		if (AH->pgCopyIn && PQendcopy(AH->connection) != 0)			die_horribly(AH, modulename, "error returned by PQendcopy: %s",						 PQerrorMessage(AH->connection));		AH->pgCopyIn = false;	}	return qry + loc + 1;}/* * Used by ExecuteSqlCommandBuf to send one buffered line of SQL * (not data for the copy command). */static char *_sendSQLLine(ArchiveHandle *AH, char *qry, char *eos){	/*	 * The following is a mini state machine to assess the end of an SQL	 * statement. It really only needs to parse good SQL, or at least that's	 * the theory... End-of-statement is assumed to be an unquoted,	 * un-commented semi-colon that's not within any parentheses.	 *	 * Note: the input can be split into bufferloads at arbitrary boundaries.	 * Therefore all state must be kept in AH->sqlparse, not in local	 * variables of this routine.  We assume that AH->sqlparse was filled with	 * zeroes when created.	 */	for (; qry < eos; qry++)	{		switch (AH->sqlparse.state)		{			case SQL_SCAN:		/* Default state == 0, set in _allocAH */				if (*qry == ';' && AH->sqlparse.braceDepth == 0)				{					/*					 * We've found the end of a statement. Send it and reset					 * the buffer.					 */					appendPQExpBufferChar(AH->sqlBuf, ';');		/* inessential */					ExecuteSqlCommand(AH, AH->sqlBuf,									  "could not execute query");					resetPQExpBuffer(AH->sqlBuf);					AH->sqlparse.lastChar = '\0';					/*					 * Remove any following newlines - so that embedded COPY					 * commands don't get a starting newline.					 */					qry++;					while (qry < eos && *qry == '\n')						qry++;					/* We've finished one line, so exit */					return qry;				}				else if (*qry == '\'')				{					if (AH->sqlparse.lastChar == 'E')						AH->sqlparse.state = SQL_IN_E_QUOTE;					else						AH->sqlparse.state = SQL_IN_SINGLE_QUOTE;					AH->sqlparse.backSlash = false;				}				else if (*qry == '"')				{					AH->sqlparse.state = SQL_IN_DOUBLE_QUOTE;				}				/*				 * Look for dollar-quotes. We make the assumption that				 * $-quotes will not have an ident character just before them				 * in pg_dump output.  XXX is this good enough?				 */				else if (*qry == '$' && !_isIdentChar(AH->sqlparse.lastChar))				{					AH->sqlparse.state = SQL_IN_DOLLAR_TAG;					/* initialize separate buffer with possible tag */					if (AH->sqlparse.tagBuf == NULL)						AH->sqlparse.tagBuf = createPQExpBuffer();					else						resetPQExpBuffer(AH->sqlparse.tagBuf);					appendPQExpBufferChar(AH->sqlparse.tagBuf, *qry);				}				else if (*qry == '-' && AH->sqlparse.lastChar == '-')					AH->sqlparse.state = SQL_IN_SQL_COMMENT;				else if (*qry == '*' && AH->sqlparse.lastChar == '/')					AH->sqlparse.state = SQL_IN_EXT_COMMENT;				else if (*qry == '(')					AH->sqlparse.braceDepth++;				else if (*qry == ')')					AH->sqlparse.braceDepth--;				break;			case SQL_IN_SQL_COMMENT:				if (*qry == '\n')					AH->sqlparse.state = SQL_SCAN;				break;			case SQL_IN_EXT_COMMENT:				/*				 * This isn't fully correct, because we don't account for				 * nested slash-stars, but pg_dump never emits such.				 */				if (AH->sqlparse.lastChar == '*' && *qry == '/')					AH->sqlparse.state = SQL_SCAN;				break;			case SQL_IN_SINGLE_QUOTE:				/* We needn't handle '' specially */				if (*qry == '\'' && !AH->sqlparse.backSlash)					AH->sqlparse.state = SQL_SCAN;				else if (*qry == '\\')					AH->sqlparse.backSlash = !AH->sqlparse.backSlash;				else					AH->sqlparse.backSlash = false;				break;			case SQL_IN_E_QUOTE:				/*				 * Eventually we will need to handle '' specially, because				 * after E'...''... we should still be in E_QUOTE state.				 *				 * XXX problem: how do we tell whether the dump was made by a				 * version that thinks backslashes aren't special in non-E				 * literals??				 */				if (*qry == '\'' && !AH->sqlparse.backSlash)					AH->sqlparse.state = SQL_SCAN;				else if (*qry == '\\')					AH->sqlparse.backSlash = !AH->sqlparse.backSlash;				else					AH->sqlparse.backSlash = false;				break;			case SQL_IN_DOUBLE_QUOTE:				/* We needn't handle "" specially */				if (*qry == '"')					AH->sqlparse.state = SQL_SCAN;				break;			case SQL_IN_DOLLAR_TAG:				if (*qry == '$')				{					/* Do not add the closing $ to tagBuf */					AH->sqlparse.state = SQL_IN_DOLLAR_QUOTE;					AH->sqlparse.minTagEndPos = AH->sqlBuf->len + AH->sqlparse.tagBuf->len + 1;				}				else if (_isDQChar(*qry, (AH->sqlparse.tagBuf->len == 1)))				{					/* Valid, so add to tag */					appendPQExpBufferChar(AH->sqlparse.tagBuf, *qry);				}				else				{					/*					 * Ooops, we're not really in a dollar-tag.  Valid tag					 * chars do not include the various chars we look for in					 * this state machine, so it's safe to just jump from this					 * state back to SCAN.	We have to back up the qry pointer					 * so that the current character gets rescanned in SCAN					 * state; and then "continue" so that the bottom-of-loop					 * actions aren't done yet.					 */					AH->sqlparse.state = SQL_SCAN;					qry--;					continue;				}				break;			case SQL_IN_DOLLAR_QUOTE:				/*				 * If we are at a $, see whether what precedes it matches				 * tagBuf.	(Remember that the trailing $ of the tag was not				 * added to tagBuf.)  However, don't compare until we have				 * enough data to be a possible match --- this is needed to				 * avoid false match on '$a$a$...'				 */				if (*qry == '$' &&					AH->sqlBuf->len >= AH->sqlparse.minTagEndPos &&					strcmp(AH->sqlparse.tagBuf->data,						   AH->sqlBuf->data + AH->sqlBuf->len - AH->sqlparse.tagBuf->len) == 0)					AH->sqlparse.state = SQL_SCAN;				break;		}		appendPQExpBufferChar(AH->sqlBuf, *qry);		AH->sqlparse.lastChar = *qry;	}	/*	 * If we get here, we've processed entire bufferload with no complete SQL	 * stmt	 */	return eos;}/* Convenience function to send one or more queries. Monitors result to handle COPY statements */intExecuteSqlCommandBuf(ArchiveHandle *AH, void *qryv, size_t bufLen){	char	   *qry = (char *) qryv;	char	   *eos = qry + bufLen;	/*	 * fprintf(stderr, "\n\n*****\n Buffer:\n\n%s\n*******************\n\n",	 * qry);	 */	/* Could switch between command and COPY IN mode at each line */	while (qry < eos)	{		/*		 * If libpq is in CopyIn mode *or* if the archive structure shows we		 * are sending COPY data, treat the data as COPY data.  The pgCopyIn		 * check is only needed for backwards compatibility with ancient		 * archive files that might just issue a COPY command without marking		 * it properly.  Note that in an archive entry that has a copyStmt,		 * all data up to the end of the entry will go to _sendCopyLine, and		 * therefore will be dropped if libpq has failed to enter COPY mode.		 * Also, if a "\." data terminator is found, anything remaining in the		 * archive entry will be dropped.		 */		if (AH->pgCopyIn || AH->writingCopyData)			qry = _sendCopyLine(AH, qry, eos);		else			qry = _sendSQLLine(AH, qry, eos);	}	return 1;}voidStartTransaction(ArchiveHandle *AH){	PQExpBuffer qry = createPQExpBuffer();	appendPQExpBuffer(qry, "BEGIN");	ExecuteSqlCommand(AH, qry, "could not start database transaction");	destroyPQExpBuffer(qry);}voidCommitTransaction(ArchiveHandle *AH){	PQExpBuffer qry = createPQExpBuffer();	appendPQExpBuffer(qry, "COMMIT");	ExecuteSqlCommand(AH, qry, "could not commit database transaction");	destroyPQExpBuffer(qry);}static bool_isIdentChar(unsigned char c){	if ((c >= 'a' && c <= 'z')		|| (c >= 'A' && c <= 'Z')		|| (c >= '0' && c <= '9')		|| (c == '_')		|| (c == '$')		|| (c >= (unsigned char) '\200')		/* no need to check <= \377 */		)		return true;	else		return false;}static bool_isDQChar(unsigned char c, bool atStart){	if ((c >= 'a' && c <= 'z')		|| (c >= 'A' && c <= 'Z')		|| (c == '_')		|| (!atStart && c >= '0' && c <= '9')		|| (c >= (unsigned char) '\200')		/* no need to check <= \377 */		)		return true;	else		return false;}

⌨️ 快捷键说明

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