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

📄 pg_backup_archiver.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (AH->currUser)		free(AH->currUser);	AH->currUser = strdup(user);}/* * Become the owner of the the given TOC entry object.	If * changes in ownership are not allowed, this doesn't do anything. */static void_becomeOwner(ArchiveHandle *AH, TocEntry *te){	if (AH->ropt && (AH->ropt->noOwner || !AH->ropt->use_setsessauth))		return;	_becomeUser(AH, te->owner);}/* * Set the proper default_with_oids value for the table. */static void_setWithOids(ArchiveHandle *AH, TocEntry *te){	if (AH->currWithOids != te->withOids)	{		_doSetWithOids(AH, te->withOids);		AH->currWithOids = te->withOids;	}}/* * Issue the commands to select the specified schema as the current schema * in the target database. */static void_selectOutputSchema(ArchiveHandle *AH, const char *schemaName){	PQExpBuffer qry;	if (!schemaName || *schemaName == '\0' ||		strcmp(AH->currSchema, schemaName) == 0)		return;					/* no need to do anything */	qry = createPQExpBuffer();	appendPQExpBuffer(qry, "SET search_path = %s",					  fmtId(schemaName));	if (strcmp(schemaName, "pg_catalog") != 0)		appendPQExpBuffer(qry, ", pg_catalog");	if (RestoringToDB(AH))	{		PGresult   *res;		res = PQexec(AH->connection, qry->data);		if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)			warn_or_die_horribly(AH, modulename,								 "could not set search_path to \"%s\": %s",								 schemaName, PQerrorMessage(AH->connection));		PQclear(res);	}	else		ahprintf(AH, "%s;\n\n", qry->data);	if (AH->currSchema)		free(AH->currSchema);	AH->currSchema = strdup(schemaName);	destroyPQExpBuffer(qry);}/* * Issue the commands to select the specified tablespace as the current one * in the target database. */static void_selectTablespace(ArchiveHandle *AH, const char *tablespace){	PQExpBuffer qry;	const char *want,			   *have;	have = AH->currTablespace;	want = tablespace;	/* no need to do anything for non-tablespace object */	if (!want)		return;	if (have && strcmp(want, have) == 0)		return;					/* no need to do anything */	qry = createPQExpBuffer();	if (strcmp(want, "") == 0)	{		/* We want the tablespace to be the database's default */		appendPQExpBuffer(qry, "SET default_tablespace = ''");	}	else	{		/* We want an explicit tablespace */		appendPQExpBuffer(qry, "SET default_tablespace = %s", fmtId(want));	}	if (RestoringToDB(AH))	{		PGresult   *res;		res = PQexec(AH->connection, qry->data);		if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)			warn_or_die_horribly(AH, modulename,								 "could not set default_tablespace to %s: %s",								 fmtId(want), PQerrorMessage(AH->connection));		PQclear(res);	}	else		ahprintf(AH, "%s;\n\n", qry->data);	if (AH->currTablespace)		free(AH->currTablespace);	AH->currTablespace = strdup(want);	destroyPQExpBuffer(qry);}/* * Extract an object description for a TOC entry, and append it to buf. * * This is not quite as general as it may seem, since it really only * handles constructing the right thing to put into ALTER ... OWNER TO. * * The whole thing is pretty grotty, but we are kind of stuck since the * information used is all that's available in older dump files. */static void_getObjectDescription(PQExpBuffer buf, TocEntry *te, ArchiveHandle *AH){	const char *type = te->desc;	/* Use ALTER TABLE for views and sequences */	if (strcmp(type, "VIEW") == 0 ||		strcmp(type, "SEQUENCE") == 0)		type = "TABLE";	/* objects named by a schema and name */	if (strcmp(type, "CONVERSION") == 0 ||		strcmp(type, "DOMAIN") == 0 ||		strcmp(type, "TABLE") == 0 ||		strcmp(type, "TYPE") == 0)	{		appendPQExpBuffer(buf, "%s ", type);		if (te->namespace && te->namespace[0])	/* is null pre-7.3 */			appendPQExpBuffer(buf, "%s.", fmtId(te->namespace));		/*		 * Pre-7.3 pg_dump would sometimes (not always) put a fmtId'd name		 * into te->tag for an index. This check is heuristic, so make its		 * scope as narrow as possible.		 */		if (AH->version < K_VERS_1_7 &&			te->tag[0] == '"' &&			te->tag[strlen(te->tag) - 1] == '"' &&			strcmp(type, "INDEX") == 0)			appendPQExpBuffer(buf, "%s", te->tag);		else			appendPQExpBuffer(buf, "%s", fmtId(te->tag));		return;	}	/* objects named by just a name */	if (strcmp(type, "DATABASE") == 0 ||		strcmp(type, "SCHEMA") == 0)	{		appendPQExpBuffer(buf, "%s %s", type, fmtId(te->tag));		return;	}	/*	 * These object types require additional decoration.  Fortunately, the	 * information needed is exactly what's in the DROP command.	 */	if (strcmp(type, "AGGREGATE") == 0 ||		strcmp(type, "FUNCTION") == 0 ||		strcmp(type, "OPERATOR") == 0 ||		strcmp(type, "OPERATOR CLASS") == 0)	{		/* Chop "DROP " off the front and make a modifiable copy */		char	   *first = strdup(te->dropStmt + 5);		char	   *last;		/* point to last character in string */		last = first + strlen(first) - 1;		/* Strip off any ';' or '\n' at the end */		while (last >= first && (*last == '\n' || *last == ';'))			last--;		*(last + 1) = '\0';		appendPQExpBufferStr(buf, first);		free(first);		return;	}	write_msg(modulename, "WARNING: don't know how to set owner for object type %s\n",			  type);}static void_printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isData, bool acl_pass){	/* ACLs are dumped only during acl pass */	if (acl_pass)	{		if (strcmp(te->desc, "ACL") != 0)			return;	}	else	{		if (strcmp(te->desc, "ACL") == 0)			return;	}	/*	 * Avoid dumping the public schema, as it will already be created ...	 * unless we are using --clean mode, in which case it's been deleted and	 * we'd better recreate it.	 */	if (!ropt->dropSchema &&		strcmp(te->desc, "SCHEMA") == 0 && strcmp(te->tag, "public") == 0)		return;	/* Select owner, schema, and tablespace as necessary */	_becomeOwner(AH, te);	_selectOutputSchema(AH, te->namespace);	_selectTablespace(AH, te->tablespace);	/* Set up OID mode too */	if (strcmp(te->desc, "TABLE") == 0)		_setWithOids(AH, te);	/* Emit header comment for item */	if (!AH->noTocComments)	{		const char *pfx;		if (isData)			pfx = "Data for ";		else			pfx = "";		ahprintf(AH, "--\n");		if (AH->public.verbose)		{			ahprintf(AH, "-- TOC entry %d (class %u OID %u)\n",					 te->dumpId, te->catalogId.tableoid, te->catalogId.oid);			if (te->nDeps > 0)			{				int			i;				ahprintf(AH, "-- Dependencies:");				for (i = 0; i < te->nDeps; i++)					ahprintf(AH, " %d", te->dependencies[i]);				ahprintf(AH, "\n");			}		}		ahprintf(AH, "-- %sName: %s; Type: %s; Schema: %s; Owner: %s",				 pfx, te->tag, te->desc,				 te->namespace ? te->namespace : "-",				 te->owner);		if (te->tablespace)			ahprintf(AH, "; Tablespace: %s", te->tablespace);		ahprintf(AH, "\n");		if (AH->PrintExtraTocPtr !=NULL)			(*AH->PrintExtraTocPtr) (AH, te);		ahprintf(AH, "--\n\n");	}	/*	 * Actually print the definition.	 *	 * Really crude hack for suppressing AUTHORIZATION clause that old pg_dump	 * versions put into CREATE SCHEMA.  We have to do this when --no-owner	 * mode is selected.  This is ugly, but I see no other good way ...	 */	if (ropt->noOwner && strcmp(te->desc, "SCHEMA") == 0)	{		ahprintf(AH, "CREATE SCHEMA %s;\n\n\n", fmtId(te->tag));	}	else	{		if (strlen(te->defn) > 0)			ahprintf(AH, "%s\n\n", te->defn);	}	/*	 * If we aren't using SET SESSION AUTH to determine ownership, we must	 * instead issue an ALTER OWNER command.  We assume that anything without	 * a DROP command is not a separately ownable object.  All the categories	 * with DROP commands must appear in one list or the other.	 */	if (!ropt->noOwner && !ropt->use_setsessauth &&		strlen(te->owner) > 0 && strlen(te->dropStmt) > 0)	{		if (strcmp(te->desc, "AGGREGATE") == 0 ||			strcmp(te->desc, "CONVERSION") == 0 ||			strcmp(te->desc, "DATABASE") == 0 ||			strcmp(te->desc, "DOMAIN") == 0 ||			strcmp(te->desc, "FUNCTION") == 0 ||			strcmp(te->desc, "OPERATOR") == 0 ||			strcmp(te->desc, "OPERATOR CLASS") == 0 ||			strcmp(te->desc, "SCHEMA") == 0 ||			strcmp(te->desc, "TABLE") == 0 ||			strcmp(te->desc, "TYPE") == 0 ||			strcmp(te->desc, "VIEW") == 0 ||			strcmp(te->desc, "SEQUENCE") == 0)		{			PQExpBuffer temp = createPQExpBuffer();			appendPQExpBuffer(temp, "ALTER ");			_getObjectDescription(temp, te, AH);			appendPQExpBuffer(temp, " OWNER TO %s;", fmtId(te->owner));			ahprintf(AH, "%s\n\n", temp->data);			destroyPQExpBuffer(temp);		}		else if (strcmp(te->desc, "CAST") == 0 ||				 strcmp(te->desc, "CHECK CONSTRAINT") == 0 ||				 strcmp(te->desc, "CONSTRAINT") == 0 ||				 strcmp(te->desc, "DEFAULT") == 0 ||				 strcmp(te->desc, "FK CONSTRAINT") == 0 ||				 strcmp(te->desc, "INDEX") == 0 ||				 strcmp(te->desc, "PROCEDURAL LANGUAGE") == 0 ||				 strcmp(te->desc, "RULE") == 0 ||				 strcmp(te->desc, "TRIGGER") == 0)		{			/* these object types don't have separate owners */		}		else		{			write_msg(modulename, "WARNING: don't know how to set owner for object type %s\n",					  te->desc);		}	}	/*	 * If it's an ACL entry, it might contain SET SESSION AUTHORIZATION	 * commands, so we can no longer assume we know the current auth setting.	 */	if (strncmp(te->desc, "ACL", 3) == 0)	{		if (AH->currUser)			free(AH->currUser);		AH->currUser = NULL;	}}voidWriteHead(ArchiveHandle *AH){	struct tm	crtm;	(*AH->WriteBufPtr) (AH, "PGDMP", 5);		/* Magic code */	(*AH->WriteBytePtr) (AH, AH->vmaj);	(*AH->WriteBytePtr) (AH, AH->vmin);	(*AH->WriteBytePtr) (AH, AH->vrev);	(*AH->WriteBytePtr) (AH, AH->intSize);	(*AH->WriteBytePtr) (AH, AH->offSize);	(*AH->WriteBytePtr) (AH, AH->format);#ifndef HAVE_LIBZ	if (AH->compression != 0)		write_msg(modulename, "WARNING: requested compression not available in this "				  "installation -- archive will be uncompressed\n");	AH->compression = 0;#endif	WriteInt(AH, AH->compression);	crtm = *localtime(&AH->createDate);	WriteInt(AH, crtm.tm_sec);	WriteInt(AH, crtm.tm_min);	WriteInt(AH, crtm.tm_hour);	WriteInt(AH, crtm.tm_mday);	WriteInt(AH, crtm.tm_mon);	WriteInt(AH, crtm.tm_year);	WriteInt(AH, crtm.tm_isdst);	WriteStr(AH, PQdb(AH->connection));	WriteStr(AH, AH->public.remoteVersionStr);	WriteStr(AH, PG_VERSION);}voidReadHead(ArchiveHandle *AH){	char		tmpMag[7];	int			fmt;	struct tm	crtm;	/* If we haven't already read the header... */	if (!AH->readHeader)	{		(*AH->ReadBufPtr) (AH, tmpMag, 5);		if (strncmp(tmpMag, "PGDMP", 5) != 0)			die_horribly(AH, modulename, "did not find magic string in file header\n");		AH->vmaj = (*AH->ReadBytePtr) (AH);		AH->vmin = (*AH->ReadBytePtr) (AH);		if (AH->vmaj > 1 || ((AH->vmaj == 1) && (AH->vmin > 0)))		/* Version > 1.0 */			AH->vrev = (*AH->ReadBytePtr) (AH);		else			AH->vrev = 0;		AH->version = ((AH->vmaj * 256 + AH->vmin) * 256 + AH->vrev) * 256 + 0;		if (AH->version < K_VERS_1_0 || AH->version > K_VERS_MAX)			die_horribly(AH, modulename, "unsupported version (%d.%d) in file header\n",						 AH->vmaj, AH->vmin);		AH->intSize = (*AH->ReadBytePtr) (AH);		if (AH->intSize > 32)			die_horribly(AH, modulename, "sanity check on integer size (%lu) failed\n",						 (unsigned long) AH->intSize);		if (AH->intSize > sizeof(int))			write_msg(modulename, "WARNING: archive was made on a machine with larger integers, some operations may fail\n");		if (AH->version >= K_VERS_1_7)			AH->offSize = (*AH->ReadBytePtr) (AH);		else			AH->offSize = AH->intSize;		fmt = (*AH->ReadBytePtr) (AH);		if (AH->format != fmt)			die_horribly(AH, modulename, "expected format (%d) differs from format found in file (%d)\n",						 AH->format, fmt);	}	if (AH->version >= K_VERS_1_2)	{		if (AH->version < K_VERS_1_4)			AH->compression = (*AH->ReadBytePtr) (AH);		else			AH->compression = ReadInt(AH);	}	else		AH->compression = Z_DEFAULT_COMPRESSION;#ifndef HAVE_LIBZ	if (AH->compression != 0)		write_msg(modulename, "WARNING: archive is compressed, but this installation does not support compression -- no data will be available\n");#endif	if (AH->version >= K_VERS_1_4)	{		crtm.tm_sec = ReadInt(AH);		crtm.tm_min = ReadInt(AH);		crtm.tm_hour = ReadInt(AH);		crtm.tm_mday = ReadInt(AH);		crtm.tm_mon = ReadInt(AH);		crtm.tm_year = ReadInt(AH);		crtm.tm_isdst = ReadInt(AH);		AH->archdbname = ReadStr(AH);		AH->createDate = mktime(&crtm);		if (AH->createDate == (time_t) -1)			write_msg(modulename, "WARNING: invalid creation date in header\n");	}	if (AH->version >= K_VERS_1_10)	{		AH->archiveRemoteVersion = ReadStr(AH);		AH->archiveDumpVersion = ReadStr(AH);	}}/* * checkSeek *	  check to see if fseek can be performed. */boolcheckSeek(FILE *fp){	if (fseeko(fp, 0, SEEK_CUR) != 0)		return false;	else if (sizeof(off_t) > sizeof(long))		/*		 * At this point, off_t is too large for long, so we return based on		 * whether an off_t version of fseek is available.		 */#ifdef HAVE_FSEEKO		return true;#else		return false;#endif	else		return true;}/* * dumpTimestamp */static voiddumpTimestamp(ArchiveHandle *AH, const char *msg, time_t tim){	char		buf[256];	if (strftime(buf, 256, "%Y-%m-%d %H:%M:%S %Z", localtime(&tim)) != 0)		ahprintf(AH, "-- %s %s\n\n", msg, buf);}

⌨️ 快捷键说明

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